【问题标题】:How to create a time spiral graph with an origin farther from the center and with a radius greater than 0 using matplotlib?如何使用matplotlib创建一个原点远离中心且半径大于0的时间螺旋图?
【发布时间】:2020-10-04 08:35:36
【问题描述】:

我对使用 matplotlib 绘图比较陌生,目前我正在尝试绘制一个我已经工作了好几天的时间范围螺旋图,但我遇到了一个我无法解决的问题。

我正在以 1 分钟的间隔从具有以下格式的 excel 文件中绘制图形,我有长达 30 天的数据。

 
Timestamp       alarms summatory
01/12/2018 00:00        3
01/12/2018 00:01        1
01/12/2018 00:02        2
01/12/2018 00:03        1
01/12/2018 00:04        1
01/12/2018 00:05        3
01/12/2018 00:06        1
01/12/2018 00:07        3
01/12/2018 00:08        1
01/12/2018 00:09        4
01/12/2018 00:10        3

从这个社区提出的其他问题和一些文档中支持自己,我得到了下图,其中 2 pi 是一天,每种颜色代表一分钟内已激活的警报数量:

Mygraph

我想展示这些 1 分钟的事件,但从第一天开始,它们的可视化就更容易了,如下图所示,中心为空,线条开始远离中心:

Graph Expected

我一直在尝试修改 linespace 函数的参数以尝试获取最后一张图像的图形,但没有任何效果,我不知道还能做什么,希望有人能帮助我。

这是我一直在使用的代码和excel文件。

Data

代码

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.patheffects as mpe
import matplotlib.colors as colors
import pandas as pd
from datetime import datetime, timedelta
# styling 
LINEWIDTH=5
EDGEWIDTH=0
CAPSTYLE="projecting"
ALPHA=1
FIRSTHOUR=0 # 0= 24 hrs, 23= 23 hrs

cdict = {'red':  ((0.0, 0.0, 0.0),
(1/6., 0.0, 0.0),
(1/2., 0.8, 1.0),
(5/6., 1.0, 1.0),
(1.0, 0.4, 1.0)),
'green':  ((0.0, 0.0, 0.4),
(1/6., 1.0, 1.0),
(1/2., 1.0, 0.8),
(5/6., 0.0, 0.0),
(1.0, 0.0, 0.0)),
'blue': ((0.0, 0.0, 0.0),
(1/6., 0.0, 0.0),
(1/2., 0.9, 0.9),
(5/6., 0.0, 0.0),
(1.0, 0.0, 0.0))
}

COLORMAP=colors.LinearSegmentedColormap.from_list("", ["green","yellow","red"])
#Read excel
df = pd.read_excel('alarms_boiler_1min_v2.xlsx')
df['Timestamp'] = df['Timestamp'].replace('/','-').apply(pd.to_datetime)

#set origin  
firts_timestamp =df['Timestamp'].min()
origin = (firts_timestamp + pd.to_timedelta(firts_timestamp.hour - FIRSTHOUR, unit='hours'))
day = pd.date_range("00:00", "23:00", freq="60min").strftime('%H:%M').tolist()
# convert alarms sumatory timestamps to day fractions
df['start'] = (df['Timestamp'] - origin) / np.timedelta64(1, 'D')
df['stop'] = (pd.DatetimeIndex(df['Timestamp']) + timedelta(minutes=1)- origin)/np.timedelta64(1, 
'D')

fig = plt.figure(figsize=(8, 6))
ax = fig.gca(projection="polar")

for idx, event in df.iterrows():
    # sample normalized alarms summatory colormap
    alarms_sum = event['alarms summatory']/4        
    color = plt.cm.get_cmap(COLORMAP)(alarms_sum)
    tstart, tstop = event.loc[['start', 'stop']]
    # timestamps are in day fractions, 2pi is one day
    nsamples = int(10000. * (tstop - tstart))
    t = np.linspace(tstart, (tstop),nsamples)
    theta = 2 * np.pi * (t) 
    arc, = ax.plot(theta, t, lw=LINEWIDTH, color=color, solid_capstyle=CAPSTYLE, alpha=ALPHA)
    arc.set_path_effects([mpe.Stroke(linewidth=LINEWIDTH+EDGEWIDTH, foreground='black'),mpe.Normal()])

#set grid, labels
ax.set_rticks([])
ax.set_theta_zero_location("N")
ax.set_theta_direction(-1)
ax.set_xticks(np.linspace(0, 2*np.pi, 24, endpoint=False))
ax.set_xticklabels(day)
ax.tick_params('x', pad=2)
ax.grid(True)
#show graph
norm = mpl.colors.Normalize(vmin=0, vmax=4)
sm = plt.cm.ScalarMappable(cmap=COLORMAP, norm=norm)
sm.set_array([])
plt.colorbar(sm, ticks=np.linspace(0, 4, 10), fraction=0.04, aspect=60, pad=0.1, label="alarms summatory", ax=ax)
plt.show()

非常感谢您,祝您有美好的一天。

【问题讨论】:

    标签: python numpy matplotlib plot graph


    【解决方案1】:

    欢迎来到 SO!一个非常好的第一个问题。

    您可以通过设置负 y/r-limits 很容易地将极坐标图转换为“甜甜圈”图:

    ax.set_rlim(bottom=-10) # or ax.set_ylim(bottom=-10)
    

    【讨论】:

      猜你喜欢
      • 2017-01-21
      • 1970-01-01
      • 1970-01-01
      • 2016-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-12
      相关资源
      最近更新 更多