Как построить стек длительность события (диаграммы Ганта) с помощью Python Pandas?
У меня есть фрейм данных Pandas, содержащий дату, когда датчик потока начал измерять поток, и дату вывода станции из эксплуатации. Я хочу создать график, показывающий эти даты графически. Вот пример моего фрейма данных:
index StationId amin amax
40623 UTAHDWQ-5932100 1994-07-19 13:15:00 1998-06-30 14:51:00
40637 UTAHDWQ-5932230 2006-03-16 13:55:00 2007-01-24 12:55:00
40666 UTAHDWQ-5932240 1980-10-31 16:00:00 2007-07-31 11:35:00
40697 UTAHDWQ-5932250 1981-06-11 17:45:00 1990-08-01 08:30:00
40728 UTAHDWQ-5932253 2006-06-28 13:15:00 2007-01-24 13:35:00
40735 UTAHDWQ-5932254 2006-06-28 13:55:00 2007-01-24 14:05:00
40742 UTAHDWQ-5932280 1981-06-11 15:30:00 2006-08-22 16:00:00
40773 UTAHDWQ-5932290 1992-06-10 15:45:00 1998-06-30 11:33:00
40796 UTAHDWQ-5932750 2005-10-03 16:30:00 2005-10-22 15:00:00
40819 UTAHDWQ-5983753 2006-04-25 09:56:00 2006-04-25 10:00:00
40823 UTAHDWQ-5983754 2006-04-25 11:05:00 2008-04-08 12:16:00
40845 UTAHDWQ-5983755 2006-04-25 13:50:00 2008-04-08 09:10:00
40867 UTAHDWQ-5983756 2006-04-25 14:20:00 2008-04-08 09:30:00
40887 UTAHDWQ-5983757 2006-04-25 12:45:00 2008-04-08 11:27:00
40945 UTAHDWQ-5983759 2008-04-08 13:03:00 2008-04-08 13:05:00
40964 UTAHDWQ-5983760 2008-04-08 13:15:00 2008-04-08 13:23:00
40990 UTAHDWQ-5983775 2008-04-15 12:47:00 2009-04-07 13:15:00
41040 UTAHDWQ-5989066 2005-10-04 10:15:00 2005-10-05 11:40:00
41091 UTAHDWQ-5996780 1995-03-09 13:59:00 1996-03-14 10:40:00
41100 UTAHDWQ-5996800 1995-03-09 15:13:00 1996-03-14 11:05:00
Я хочу создать сюжет, подобный этому (обратите внимание, что я не делал этот сюжет, используя вышеуказанные данные):
на графике не обязательно должен отображаться текст вдоль каждой строки, только ось y с названиями станций.
хотя это может показаться нишевым применением панд, я знаю нескольких ученых, которые выиграют от этой способности построения графиков.
ближайший ответ, который я мог найти здесь:
- как построить сложенный пропорциональный график?
- как построить два столбца фрейма данных pandas с использованием точек?
- библиотек matplotlib сроки
- создать сюжет Ганта с python matplotlib
последний ответ ближе всего к удовлетворению моих потребностей.
хотя я бы предпочел способ сделать это через оболочку Pandas, я был бы открыт и благодарен прямому решению matplotlib.
4 ответов
Я думаю, вы пытаетесь создать сюжет Ганта. этой предлагает использовать hlines
:
from datetime import datetime
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as dt
df = pd.read_csv('data.csv')
df.amin = pd.to_datetime(df.amin).astype(datetime)
df.amax = pd.to_datetime(df.amax).astype(datetime)
fig = plt.figure()
ax = fig.add_subplot(111)
ax = ax.xaxis_date()
ax = plt.hlines(df.index, dt.date2num(df.amin), dt.date2num(df.amax))
вы можете использовать Боке (библиотека python), чтобы сделать диаграмму Ганта и ее действительно красивой. Вот код, который я скопировал с twiiter. http://nbviewer.jupyter.org/gist/quebbs/10416d9fb954020688f2
from bokeh.plotting import figure, show, output_notebook, output_file
from bokeh.models import ColumnDataSource, Range1d
from bokeh.models.tools import HoverTool
from datetime import datetime
from bokeh.charts import Bar
output_notebook()
#output_file('GanntChart.html') #use this to create a standalone html file to send to others
import pandas as ps
DF=ps.DataFrame(columns=['Item','Start','End','Color'])
Items=[
['Contract Review & Award','2015-7-22','2015-8-7','red'],
['Submit SOW','2015-8-10','2015-8-14','gray'],
['Initial Field Study','2015-8-17','2015-8-21','gray'],
['Topographic Procesing','2015-9-1','2016-6-1','gray'],
['Init. Hydrodynamic Modeling','2016-1-2','2016-3-15','gray'],
['Prepare Suitability Curves','2016-2-1','2016-3-1','gray'],
['Improvement Conceptual Designs','2016-5-1','2016-6-1','gray'],
['Retrieve Water Level Data','2016-8-15','2016-9-15','gray'],
['Finalize Hydrodynamic Models','2016-9-15','2016-10-15','gray'],
['Determine Passability','2016-9-15','2016-10-1','gray'],
['Finalize Improvement Concepts','2016-10-1','2016-10-31','gray'],
['Stakeholder Meeting','2016-10-20','2016-10-21','blue'],
['Completion of Project','2016-11-1','2016-11-30','red']
] #first items on bottom
for i,Dat in enumerate(Items[::-1]):
DF.loc[i]=Dat
#convert strings to datetime fields:
DF['Start_dt']=ps.to_datetime(DF.Start)
DF['End_dt']=ps.to_datetime(DF.End)
G=figure(title='Project Schedule',x_axis_type='datetime',width=800,height=400,y_range=DF.Item.tolist(),
x_range=Range1d(DF.Start_dt.min(),DF.End_dt.max()), tools='save')
hover=HoverTool(tooltips="Task: @Item<br>\
Start: @Start<br>\
End: @End")
G.add_tools(hover)
DF['ID']=DF.index+0.8
DF['ID1']=DF.index+1.2
CDS=ColumnDataSource(DF)
G.quad(left='Start_dt', right='End_dt', bottom='ID', top='ID1',source=CDS,color="Color")
#G.rect(,"Item",source=CDS)
show(G)
Это можно сделать и с горизонтальными полосами:broken_barh(xranges, yrange, **kwargs)
хотя я не знаю, как это сделать в MatplotLib, вы можете взглянуть на опции с визуализацией данных так, как вы хотите, используя D3, например, с этой библиотекой:
https://github.com/jiahuang/d3-timeline
Если вы должны сделать это с Matplotlib, вот один из способов, которым это было сделано: