在线图上绘制事件

发布于 2025-01-20 11:14:10 字数 5164 浏览 0 评论 0原文

我正在尝试使用数据框中包含的数据来可视化降雨事件。 想法看似很简单,但执行起来却似乎不可能! 这是数据框的一部分:

         start_time             end_time      duration      br_open_total
0   2022-01-01 10:00:00 2022-01-01 19:00:00     9.0       0.2540000563879943
1   2022-01-02 00:00:00 2022-01-02 10:00:00    10.0       1.0160002255520624
2   2022-01-02 17:00:00 2022-01-03 02:00:00     9.0       0.7620001691640113
3   2022-01-03 02:00:00 2022-01-04 12:00:00    34.0      10.668002368296513
4   2022-01-07 21:00:00 2022-01-08 06:00:00     9.0       0.2540000563879943
5   2022-01-16 05:00:00 2022-01-16 20:00:00    15.0       0.5080001127760454
6   2022-01-19 04:00:00 2022-01-19 17:00:00    13.0       0.7620001691640255
7   2022-01-21 14:00:00 2022-01-22 00:00:00    10.0       1.5240003383280751
8   2022-01-27 02:00:00 2022-01-27 16:00:00    14.0       3.0480006766561503
9   2022-02-01 12:00:00 2022-02-01 21:00:00     9.0       0.2540000563880126
10  2022-02-03 05:00:00 2022-02-03 15:00:00    10.0       0.5080001127760251

我想要做的是在 x 轴上绘制时间图,在 y 轴上绘制“br_open_total”的值。

我可以画出我想要的样子,如下所示:

graph example

对于绘图的简单性,我深表歉意,但是我认为它解释了我想做的事情。 我该如何执行此操作,然后对同一绘图上的其他数据帧重复此操作。 我尝试过楼梯、matplotlib.pyplot.stair 和其他但没有成功。

这似乎是一个简单的概念!

编辑1:

用实际数据尝试了 Joswin K J 的答案,得到了这个: 尝试 1

02-12 11:00 的事件持续时间应为 112 小时,但条形图与所有其他条形图的宽度相同。

编辑2: 尝试了 Mozway 的答案并得到了这个: 输入图片这里的描述

仍然不显示每个事件的宽度,并且也不离散事件

编辑3: 使用 Mozway 的修正答案,我得到了实际数据的图: pic3我使用paint添加了光标位置,在绘图的右上角,您可以看到光标位于2022-02-09和20.34,这实际上是2022-02-01的值,所以看起来绘图向左移动了一个数据点?而且2022-3-01和2022-04-03之间的大块似乎不在数据

编辑 中4:按照 Mozway

Reshape Data

    duration    br_open_total       variable          date
0   10.0      1.0160002255520624     start_time     2022-01-02 00:00:00
19  10.0            0.0              end_time       2022-01-02 10:00:00
1   9.0       0.7620001691640113     start_time     2022-01-02 17:00:00
2   34.0     10.668002368296513      start_time     2022-01-03 02:00:00
21  34.0          0.0                end_time       2022-01-04 12:00:00
3   15.0      0.5080001127760454     start_time     2022-01-16 05:00:00
22  15.0           0.0               end_time       2022-01-16 20:00:00
4   13.0      0.7620001691640255     start_time     2022-01-19 04:00:00
23  13.0           0.0               end_time       2022-01-19 17:00:00
5   10.0      1.5240003383280751     start_time     2022-01-21 14:00:00
24  10.0           0.0               end_time       2022-01-22 00:00:00
6   14.0      3.0480006766561503     start_time     2022-01-27 02:00:00
25  14.0           0.0               end_time       2022-01-27 16:00:00
7   10.0      0.5080001127760251     start_time     2022-02-03 05:00:00
26  10.0           0.0               end_time       2022-02-03 15:00:00
8   18.0      7.366001635252363      start_time     2022-02-03 23:00:00
27  18.0           0.0               end_time       2022-02-04 17:00:00
9   13.0      2.28600050749211       start_time     2022-02-05 11:00:00
28  13.0           0.0               end_time       2022-02-06 00:00:00
10  19.0      2.2860005074921173     start_time     2022-02-06 04:00:00
29  19.0           0.0               end_time       2022-02-06 23:00:00
11  13.0      1.2700002819400584     start_time     2022-02-07 11:00:00
30  13.0           0.0               end_time       2022-02-08 00:00:00
12  12.0      2.79400062026814       start_time     2022-02-09 01:00:00
31  12.0           0.0               end_time       2022-02-09 13:00:00
13  112.0    20.320004511041         start_time     2022-02-12 11:00:00
32  112.0          0.0               end_time       2022-02-17 03:00:00
14  28.0      2.0320004511041034     start_time     2022-02-18 14:00:00
33  28.0           0.0               end_time       2022-02-19 18:00:00
15  17.0     17.272003834384847      start_time     2022-02-23 17:00:00
34  17.0           0.0               end_time       2022-02-24 10:00:00
16  9.0       0.7620001691640397     start_time     2022-02-27 13:00:00
35  9.0            0.0               end_time       2022-02-27 22:00:00
17  18.0      4.0640009022082        start_time     2022-04-04 00:00:00
36  18.0           0.0               end_time       2022-04-04 18:00:00
18  15.0      1.0160002255520482     start_time     2022-04-06 05:00:00
37  15.0           0.0               end_time       2022-04-06 20:00:00

的要求,使用绘制时

plt.step(bdf2['date'], bdf2['br_open_total'])
plt.gcf().set_size_inches(10, 4)
plt.xticks(rotation=90)

会生成如上所示的图,其中块的左上角对应于前一个数据点。

编辑5:更多信息 当我绘制所有数据帧(不同的传感器)时,我在事件开始和结束时间上得到相同的差异? 输入图片此处描述

I am trying to visualise rain events using a data contained in a dataframe.
the idea seems very simple, but the execution seems to be impossible!
here is a part of the dataframe:

         start_time             end_time      duration      br_open_total
0   2022-01-01 10:00:00 2022-01-01 19:00:00     9.0       0.2540000563879943
1   2022-01-02 00:00:00 2022-01-02 10:00:00    10.0       1.0160002255520624
2   2022-01-02 17:00:00 2022-01-03 02:00:00     9.0       0.7620001691640113
3   2022-01-03 02:00:00 2022-01-04 12:00:00    34.0      10.668002368296513
4   2022-01-07 21:00:00 2022-01-08 06:00:00     9.0       0.2540000563879943
5   2022-01-16 05:00:00 2022-01-16 20:00:00    15.0       0.5080001127760454
6   2022-01-19 04:00:00 2022-01-19 17:00:00    13.0       0.7620001691640255
7   2022-01-21 14:00:00 2022-01-22 00:00:00    10.0       1.5240003383280751
8   2022-01-27 02:00:00 2022-01-27 16:00:00    14.0       3.0480006766561503
9   2022-02-01 12:00:00 2022-02-01 21:00:00     9.0       0.2540000563880126
10  2022-02-03 05:00:00 2022-02-03 15:00:00    10.0       0.5080001127760251

What I want to do is have a plot with time on the x axis, and the value of the 'br_open_total' on the y axis.

I can draw what I want it to look like, see below:

graph example

I apologise for the simplicity of the drawing, but I think it explains what I want to do.
How do I do this, and then repeat for other dataframes on the same plot.
I have tried staircase, matplotlib.pyplot.stair and others with no success.

It seems such a simple concept!

Edit 1:

Tried Joswin K J's answer with the actual data, and got this:
attempt 1

The event at 02-12 11:00 should be 112 hours duration, but the bar is the same width as all the others.

Edit2:
Tried Mozway's answer and got this:
enter image description here

Still doesn't show width of each event, and doesn't discretise the events either

Edit 3:
Using Mozway's amended answer I get this plot for the actual data:
pic3
I have added the cursor position using paint, at the top right of the plot you can see that the cursor is at 2022-02-09 and 20.34, which is actually the value for 2022-02-01, so it seems that the plot is shifted to the left by one data point?, also the large block between 2022-3-01 and 2022-04-03 doesn't seem to be in the data

edit 4: as requested by Mozway

Reshaped Data

    duration    br_open_total       variable          date
0   10.0      1.0160002255520624     start_time     2022-01-02 00:00:00
19  10.0            0.0              end_time       2022-01-02 10:00:00
1   9.0       0.7620001691640113     start_time     2022-01-02 17:00:00
2   34.0     10.668002368296513      start_time     2022-01-03 02:00:00
21  34.0          0.0                end_time       2022-01-04 12:00:00
3   15.0      0.5080001127760454     start_time     2022-01-16 05:00:00
22  15.0           0.0               end_time       2022-01-16 20:00:00
4   13.0      0.7620001691640255     start_time     2022-01-19 04:00:00
23  13.0           0.0               end_time       2022-01-19 17:00:00
5   10.0      1.5240003383280751     start_time     2022-01-21 14:00:00
24  10.0           0.0               end_time       2022-01-22 00:00:00
6   14.0      3.0480006766561503     start_time     2022-01-27 02:00:00
25  14.0           0.0               end_time       2022-01-27 16:00:00
7   10.0      0.5080001127760251     start_time     2022-02-03 05:00:00
26  10.0           0.0               end_time       2022-02-03 15:00:00
8   18.0      7.366001635252363      start_time     2022-02-03 23:00:00
27  18.0           0.0               end_time       2022-02-04 17:00:00
9   13.0      2.28600050749211       start_time     2022-02-05 11:00:00
28  13.0           0.0               end_time       2022-02-06 00:00:00
10  19.0      2.2860005074921173     start_time     2022-02-06 04:00:00
29  19.0           0.0               end_time       2022-02-06 23:00:00
11  13.0      1.2700002819400584     start_time     2022-02-07 11:00:00
30  13.0           0.0               end_time       2022-02-08 00:00:00
12  12.0      2.79400062026814       start_time     2022-02-09 01:00:00
31  12.0           0.0               end_time       2022-02-09 13:00:00
13  112.0    20.320004511041         start_time     2022-02-12 11:00:00
32  112.0          0.0               end_time       2022-02-17 03:00:00
14  28.0      2.0320004511041034     start_time     2022-02-18 14:00:00
33  28.0           0.0               end_time       2022-02-19 18:00:00
15  17.0     17.272003834384847      start_time     2022-02-23 17:00:00
34  17.0           0.0               end_time       2022-02-24 10:00:00
16  9.0       0.7620001691640397     start_time     2022-02-27 13:00:00
35  9.0            0.0               end_time       2022-02-27 22:00:00
17  18.0      4.0640009022082        start_time     2022-04-04 00:00:00
36  18.0           0.0               end_time       2022-04-04 18:00:00
18  15.0      1.0160002255520482     start_time     2022-04-06 05:00:00
37  15.0           0.0               end_time       2022-04-06 20:00:00

when plotted using

plt.step(bdf2['date'], bdf2['br_open_total'])
plt.gcf().set_size_inches(10, 4)
plt.xticks(rotation=90)

produces the plot shown above, in which the top left corner of a block corresponds to the previous data point.

edit 5: further info
When I plot all my dataframes (different sensors) I get the same differential on the event start and end times?
enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

红衣飘飘貌似仙 2025-01-27 11:14:10

您可以使用 step step

# ensure datetime
df['start_time'] = pd.to_datetime(df['start_time'])
df['end_time'] = pd.to_datetime(df['end_time'])

# reshape the data
df2 = (df
 .melt(id_vars=['duration', 'br_open_total'], value_name='date')
 .sort_values(by='date')
 .drop_duplicates(subset='date')
 .assign(br_open_total=lambda d: d['br_open_total'].mask(d['variable'].eq('end_time'), 0))
)

# plot
import matplotlib.pyplot as plt
plt.step(df2['date'], df2['br_open_total'])
plt.gcf().set_size_inches(10, 4)

重塑数据:

    duration  br_open_total    variable                date
0        9.0       0.254000  start_time 2022-01-01 10:00:00
11       9.0       0.000000    end_time 2022-01-01 19:00:00
1       10.0       1.016000  start_time 2022-01-02 00:00:00
12      10.0       0.000000    end_time 2022-01-02 10:00:00
2        9.0       0.762000  start_time 2022-01-02 17:00:00
3       34.0      10.668002  start_time 2022-01-03 02:00:00
14      34.0       0.000000    end_time 2022-01-04 12:00:00
4        9.0       0.254000  start_time 2022-01-07 21:00:00
15       9.0       0.000000    end_time 2022-01-08 06:00:00
5       15.0       0.508000  start_time 2022-01-16 05:00:00
16      15.0       0.000000    end_time 2022-01-16 20:00:00
6       13.0       0.762000  start_time 2022-01-19 04:00:00
17      13.0       0.000000    end_time 2022-01-19 17:00:00
7       10.0       1.524000  start_time 2022-01-21 14:00:00
18      10.0       0.000000    end_time 2022-01-22 00:00:00
8       14.0       3.048001  start_time 2022-01-27 02:00:00
19      14.0       0.000000    end_time 2022-01-27 16:00:00
9        9.0       0.254000  start_time 2022-02-01 12:00:00
20       9.0       0.000000    end_time 2022-02-01 21:00:00
10      10.0       0.508000  start_time 2022-02-03 05:00:00
21      10.0       0.000000    end_time 2022-02-03 15:00:00

You can use a step plot:

# ensure datetime
df['start_time'] = pd.to_datetime(df['start_time'])
df['end_time'] = pd.to_datetime(df['end_time'])

# reshape the data
df2 = (df
 .melt(id_vars=['duration', 'br_open_total'], value_name='date')
 .sort_values(by='date')
 .drop_duplicates(subset='date')
 .assign(br_open_total=lambda d: d['br_open_total'].mask(d['variable'].eq('end_time'), 0))
)

# plot
import matplotlib.pyplot as plt
plt.step(df2['date'], df2['br_open_total'])
plt.gcf().set_size_inches(10, 4)

output:

step plot

reshaped data:

    duration  br_open_total    variable                date
0        9.0       0.254000  start_time 2022-01-01 10:00:00
11       9.0       0.000000    end_time 2022-01-01 19:00:00
1       10.0       1.016000  start_time 2022-01-02 00:00:00
12      10.0       0.000000    end_time 2022-01-02 10:00:00
2        9.0       0.762000  start_time 2022-01-02 17:00:00
3       34.0      10.668002  start_time 2022-01-03 02:00:00
14      34.0       0.000000    end_time 2022-01-04 12:00:00
4        9.0       0.254000  start_time 2022-01-07 21:00:00
15       9.0       0.000000    end_time 2022-01-08 06:00:00
5       15.0       0.508000  start_time 2022-01-16 05:00:00
16      15.0       0.000000    end_time 2022-01-16 20:00:00
6       13.0       0.762000  start_time 2022-01-19 04:00:00
17      13.0       0.000000    end_time 2022-01-19 17:00:00
7       10.0       1.524000  start_time 2022-01-21 14:00:00
18      10.0       0.000000    end_time 2022-01-22 00:00:00
8       14.0       3.048001  start_time 2022-01-27 02:00:00
19      14.0       0.000000    end_time 2022-01-27 16:00:00
9        9.0       0.254000  start_time 2022-02-01 12:00:00
20       9.0       0.000000    end_time 2022-02-01 21:00:00
10      10.0       0.508000  start_time 2022-02-03 05:00:00
21      10.0       0.000000    end_time 2022-02-03 15:00:00
奢欲 2025-01-27 11:14:10

试试这个:

import matplotlib.pyplot as plt

for ind,row in df.iterrows():
    plt.plot(pd.Series([row['start_time'],row['end_time']]),pd.Series([row['br_open_total'],row['br_open_total']]),color='b')
    plt.plot(pd.Series([row['start_time'],row['start_time']]),pd.Series([0,row['br_open_total']]),color='b')
    plt.plot(pd.Series([row['end_time'],row['end_time']]),pd.Series([0,row['br_open_total']]),color='b')
plt.xticks(rotation=90)

结果:

在此处输入图像描述

Try this:

import matplotlib.pyplot as plt

for ind,row in df.iterrows():
    plt.plot(pd.Series([row['start_time'],row['end_time']]),pd.Series([row['br_open_total'],row['br_open_total']]),color='b')
    plt.plot(pd.Series([row['start_time'],row['start_time']]),pd.Series([0,row['br_open_total']]),color='b')
    plt.plot(pd.Series([row['end_time'],row['end_time']]),pd.Series([0,row['br_open_total']]),color='b')
plt.xticks(rotation=90)

Result:

enter image description here

葬花如无物 2025-01-27 11:14:10

我相信我现在已经破解了它,非常感谢@Mozway。
重构数据框以进行绘图的代码:

#create dataframes of each open gauge events removing any event with an open total of less than 0.254mm
#bresser/open
bdftdf=bdf.loc[bdf['br_open_total'] > 0.255]
bdftdf=bdftdf.copy()
bdftdf['start_time'] = pd.to_datetime(bdftdf['start_time'])
bdftdf['end_time'] = pd.to_datetime(bdftdf['end_time'])
bdf2 = (bdftdf
  .melt(id_vars=['duration', 'ic_total','mc_total','md_total','imd_total','oak_total','highpoint_total','school_total','br_open_total',
                'fr_gauge_total','open_mean_total','br_open_ic_%_int','br_open_mc_%_int','br_open_md_%_int','br_open_imd_%_int',
                'br_open_oak_%_int'], value_name='date')
  .sort_values(by='date')
  #.drop_duplicates(subset='date')
  .assign(br_open_total=lambda d: d['br_open_total'].mask(d['variable'].eq('end_time'), 0))
)
#create array for stairs plot
bdfarr=np.array(bdf2['date'])
bl=len(bdf2)
bdfarr=np.append(bdfarr,[bdfarr[bl-1]+np.timedelta64(1,'h')])

在数据框中创建“日期”列的数组并向该数组附加额外元素之后,我使用了 plt.stairs,而不是按照 Mozway 建议使用 plt.step 图等于最后一个元素=1小时。
这意味着数据现在按照我的预期绘制:
输入图片此处描述

绘图代码:

fig1=plt.figure()
plt.stairs(bdf2['br_open_total'], bdfarr, label='Bresser\Open')
plt.stairs(frdf2['fr_gauge_total'], frdfarr, label='FR Gauge')
plt.stairs(hpdf2['highpoint_total'], hpdfarr, label='Highpoint')
plt.stairs(schdf2['school_total'], schdfarr, label='School')
plt.stairs(opmedf2['open_mean_total'], opmedfarr, label='Open mean')
plt.xticks(rotation=90)
plt.legend(title='Rain events', loc='best')
plt.show()

I believe I have now cracked it, with a great debt of thanks to @Mozway.
The code to restructure the dataframe for plotting:

#create dataframes of each open gauge events removing any event with an open total of less than 0.254mm
#bresser/open
bdftdf=bdf.loc[bdf['br_open_total'] > 0.255]
bdftdf=bdftdf.copy()
bdftdf['start_time'] = pd.to_datetime(bdftdf['start_time'])
bdftdf['end_time'] = pd.to_datetime(bdftdf['end_time'])
bdf2 = (bdftdf
  .melt(id_vars=['duration', 'ic_total','mc_total','md_total','imd_total','oak_total','highpoint_total','school_total','br_open_total',
                'fr_gauge_total','open_mean_total','br_open_ic_%_int','br_open_mc_%_int','br_open_md_%_int','br_open_imd_%_int',
                'br_open_oak_%_int'], value_name='date')
  .sort_values(by='date')
  #.drop_duplicates(subset='date')
  .assign(br_open_total=lambda d: d['br_open_total'].mask(d['variable'].eq('end_time'), 0))
)
#create array for stairs plot
bdfarr=np.array(bdf2['date'])
bl=len(bdf2)
bdfarr=np.append(bdfarr,[bdfarr[bl-1]+np.timedelta64(1,'h')])

Rather than use the plt.step plot as suggested by Mozway, I have used plt.stairs, after creating an array of the 'date' column in the dataframe and appending an extra element to that array equal to the last element =1hour.
This means that the data now plots as I had intended it to.:
enter image description here

code for plot:

fig1=plt.figure()
plt.stairs(bdf2['br_open_total'], bdfarr, label='Bresser\Open')
plt.stairs(frdf2['fr_gauge_total'], frdfarr, label='FR Gauge')
plt.stairs(hpdf2['highpoint_total'], hpdfarr, label='Highpoint')
plt.stairs(schdf2['school_total'], schdfarr, label='School')
plt.stairs(opmedf2['open_mean_total'], opmedfarr, label='Open mean')
plt.xticks(rotation=90)
plt.legend(title='Rain events', loc='best')
plt.show()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文