Pythonとmatplotlibを使用したタイムライン棒グラフ 質問する

Pythonとmatplotlibを使用したタイムライン棒グラフ 質問する

私はタイムラインの棒グラフを描きたいと思っていますマットプロットこれは、人が1日に何をしたかを表示します。以下のコードの出力と、私が探している期待される出力を追加します。任意のライブラリを使用できますが、私の場合は、最も近いものを使用しました。マットプロットご協力いただければ幸いです。

import datetime as dt
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

data = [    (dt.datetime(2018, 7, 17, 0, 15), dt.datetime(2018, 7, 17, 0, 30), 'sleep'),
            (dt.datetime(2018, 7, 17, 0, 30), dt.datetime(2018, 7, 17, 0, 45), 'eat'),
            (dt.datetime(2018, 7, 17, 0, 45), dt.datetime(2018, 7, 17, 1, 0), 'work'),
            (dt.datetime(2018, 7, 17, 1, 0), dt.datetime(2018, 7, 17, 1, 30), 'sleep'),
            (dt.datetime(2018, 7, 17, 1, 15), dt.datetime(2018, 7, 17, 1, 30), 'eat'), 
            (dt.datetime(2018, 7, 17, 1, 30), dt.datetime(2018, 7, 17, 1, 45), 'work')
        ]

rng=[]
for i in range(len(data)):
    rng.append((data[i][0]).strftime('%H:%M'))

index={}
activity = []
for i in range(len(data)):
    index[(data[i][2])]=[]
    activity.append(data[i][2])

for i in range(len(index)):
    for j in range(len(activity)):
        if activity[j]==index.keys()[i]:
            index[index.keys()[i]].append(15)
        else:
            index[index.keys()[i]].append(0)            

data = list(index.values())
df = pd.DataFrame(data,index=list(index.keys()))
df.plot.barh(stacked=True, sharex=False)
plt.show()

私のアウトプット:

matplotlibを使用すると、これが得られたものです

matplotlibを使用すると、これが得られたものです

期待される出力:

私はこれをGoogle Chartsのタイムライングラフを使って取得しましたが、Pythonを使ってこれを取得する必要があり、両方のグラフを生成するために使用されるデータはまったく同じではありません。ポイントを理解していただければ幸いです。私はこれをGoogle Charts Timelineグラフを使用して取得しましたが、Pythonを使用してこれを取得する必要があり、両方のグラフを生成するために使用されるデータはまったく同じではありません。ポイントを理解していただければ幸いです。

ベストアンサー1

あなたはPolyCollection「バー」の。このためには、日付を数値に変換する必要があります(matplotlib.dates.date2num)。

import datetime as dt
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from matplotlib.collections import PolyCollection

data = [    (dt.datetime(2018, 7, 17, 0, 15), dt.datetime(2018, 7, 17, 0, 30), 'sleep'),
            (dt.datetime(2018, 7, 17, 0, 30), dt.datetime(2018, 7, 17, 0, 45), 'eat'),
            (dt.datetime(2018, 7, 17, 0, 45), dt.datetime(2018, 7, 17, 1, 0), 'work'),
            (dt.datetime(2018, 7, 17, 1, 0), dt.datetime(2018, 7, 17, 1, 30), 'sleep'),
            (dt.datetime(2018, 7, 17, 1, 15), dt.datetime(2018, 7, 17, 1, 30), 'eat'), 
            (dt.datetime(2018, 7, 17, 1, 30), dt.datetime(2018, 7, 17, 1, 45), 'work')
        ]

cats = {"sleep" : 1, "eat" : 2, "work" : 3}
colormapping = {"sleep" : "C0", "eat" : "C1", "work" : "C2"}

verts = []
colors = []
for d in data:
    v =  [(mdates.date2num(d[0]), cats[d[2]]-.4),
          (mdates.date2num(d[0]), cats[d[2]]+.4),
          (mdates.date2num(d[1]), cats[d[2]]+.4),
          (mdates.date2num(d[1]), cats[d[2]]-.4),
          (mdates.date2num(d[0]), cats[d[2]]-.4)]
    verts.append(v)
    colors.append(colormapping[d[2]])

bars = PolyCollection(verts, facecolors=colors)

fig, ax = plt.subplots()
ax.add_collection(bars)
ax.autoscale()
loc = mdates.MinuteLocator(byminute=[0,15,30,45])
ax.xaxis.set_major_locator(loc)
ax.xaxis.set_major_formatter(mdates.AutoDateFormatter(loc))

ax.set_yticks([1,2,3])
ax.set_yticklabels(["sleep", "eat", "work"])
plt.show()

ここに画像の説明を入力してください

このようなプロットは、折れ線グラフ ( broken_barh)ただし、ここで使用されている (ソートされていない) データでは、PolyCollection を使用すると少し簡単になります。

そして今度は、どうすれば同時に寝て食べることができるのかを私に説明しなければなりません。それは、私がどんなに頑張っても決してできないことです。

おすすめ記事