【问题标题】:How can I annotate a Grouped Broken Barh Chart Python Matplotlib我如何注释分组的断条形图 Python Matplotlib
【发布时间】:2020-04-22 13:01:24
【问题描述】:

我已经搜索到筋疲力尽,试图注释我的分组损坏条形图。我想在每个断条部分中注释我的数据框中的“事件”。我在网上找到的手动输入事件x,y位置,AND的例子,不是分组的破条例子。

最终目标是让这些事件在悬停时显示,但我相信如果我可以让这些事件显示,我不会有问题。

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import datetime
import matplotlib.ticker as ticker
import io
pd.plotting.register_matplotlib_converters()

inp = u""" T29,11/4/2019 0:00,11/4/2019 0:00,off,none
T29,11/4/2019 0:00,11/5/2019 0:00,off,eventa
T29,11/5/2019 0:00,11/6/2019 0:00,on,none
T35,11/4/2019 0:00,11/5/2019 0:00,off,eventb
T35,11/5/2019 0:00,11/6/2019 0:00,paused,eventa
T43,11/4/2019 0:00,11/4/2019 4:01,on,none
T43,11/4/2019 4:01,11/4/2019 12:06,off,none
T43,11/4/2019 12:06,11/5/2019 8:07,on,eventc
T43,11/5/2019 8:07,11/5/2019 10:12,paused,eventd
T43,11/5/2019 10:12,11/5/2019 16:15,on,none
T43,11/5/2019 18:12,11/5/2019 20:15,off,none
"""

mydateparser = lambda x: pd.datetime.strptime(x, "%m/%d/%Y %H:%M")
df = pd.read_csv(io.StringIO(inp), header=0, encoding = "ISO-8859-1", parse_dates=['StartTime', 'FinishTime'], date_parser=mydateparser, names=["Name", "StartTime", "FinishTime", "Status", "Event"])
color = {"on": "g", "paused": "yellow", "off": "black"}

df["Diff"] = df.FinishTime - df.StartTime
minDate = (datetime.datetime.toordinal(min(df.StartTime)))
maxDate = (datetime.datetime.toordinal(max(df.FinishTime)))
days = mdates.DayLocator()
Mcount = 0

fig, ax = plt.subplots(figsize=(6, 3), edgecolor="black", linewidth=1)
labels = []
for i, task in enumerate(df.groupby("Name")):
    Mcount += 1
    labels.append(task[0])
    for r in task[1].groupby("Status"):
        data = r[1][["StartTime", "Diff"]]
        ax.broken_barh(data.values, (i - 0.4, 0.8), edgecolor="black", alpha=1, linewidth=1, 
                        color=color[r[0]])

ax.set_ylim(bottom=-0.8, top=Mcount)
ax.set_yticks(range(len(labels)))
ax.set_yticklabels(labels)
ax.set_ylabel("Names", rotation=90, fontdict={'family': 'DejaVu Sans', 'color': 'black', 'weight': 'bold', 'size': 14})

ax.set_xlim(left=minDate, right=maxDate)
ax.set_xlabel("Date", fontdict={'family': 'DejaVu Sans', 'color':  'black', 'weight': 'bold', 'size': 14})

ax.xaxis.set_major_formatter(mdates.DateFormatter('%m-%d-%Y'))
ax.tick_params(which='major', axis='x', rotation=0, length=11, color='black')
ax.xaxis.set_major_locator(days)

ax.xaxis.set_minor_formatter(mdates.DateFormatter('%H:%M'))
ax.tick_params(which='minor', rotation=0, labelsize=8, length=4, color='red', size=2)
ax.xaxis.set_minor_locator(ticker.MultipleLocator(.50))
plt.show()

【问题讨论】:

标签: python-3.x pandas datetime matplotlib


【解决方案1】:

您好,欢迎来到 StackOverflow。 IIUC,您可以在枚举语句中附加一个 for 循环以将文本添加到轴。

for i, task in enumerate(df.groupby("Name")):
    Mcount += 1
    labels.append(task[0])
    for r in task[1].groupby("Status"):
        data = r[1][["StartTime", "Diff"]]
        ax.broken_barh(data.values, 
                       (i - 0.4, 0.8), 
                       edgecolor="black", 
                       alpha=1, 
                       linewidth=1, 
                       color=color[r[0]]
                      )

        for x1, x2 in data.values:
            ax.text(x=x1 + x2/2, 
                    y=i,
                    s=r[1]["Event"].values[0], 
                    ha='center', 
                    va='center',
                    color='white',
                   )

修改自docs。

输出:

当然,您可以修改文本格式。

text 需要一个 x 位置、一个 y 位置和一个字符串。 hacky 索引是我从数据框中提取事件信息的最快方法。

【讨论】:

  • 完美的胜利给你我的朋友。在我之前的尝试中,我的逻辑是好的,我的语法不是。这教会了我哪里出错了。谢谢。
猜你喜欢
  • 1970-01-01
  • 2020-11-23
  • 2020-12-09
  • 1970-01-01
  • 1970-01-01
  • 2017-10-18
  • 2016-03-21
  • 2018-11-29
  • 2018-08-02
相关资源
最近更新 更多