【问题标题】:Plot histogram / curve on time axis在时间轴上绘制直方图/曲线
【发布时间】:2018-08-17 15:12:56
【问题描述】:

我觉得有一种非常简单的方法可以做到这一点。我正在尝试绘制在环境中运行的任务的时间表,包括。同一张图上的两个图:

  1. 任务运行时间为broken_barh
  2. 基于每个时间点上的任务聚合的总体负载曲线(或直方图),比方说具有较低的不透明度或一条线。

在示例中,有 6 个任务正在运行 (A-F),长度不同,开始时间也不同。它们完全按照我的需要 (1/) 绘制,在一个类似甘特的图表中,时间在 X 轴上。

import numpy as np
import pandas as pd
%matplotlib inline
import matplotlib as mpl
from matplotlib import pyplot as plt

cols=['ID','From','To']

df = pd.DataFrame([['A', 736758.993, 736758.995], ['B', 736758.995, 736758.998],
                   ['C', 736758.994, 736758.996], ['D', 736758.996, 736758.997],
                   ['E', 736758.996, 736758.997], ['F', 736758.995, 736758.996]],
                   columns=cols)

df['Diff'] = df['To']-df['From']

fig,ax=plt.subplots()
for i, slice in df.iterrows():
    values = [[slice['From'], slice['Diff']]]
    ax.broken_barh((values), (i-0.4,0.8), color=np.random.rand(3))

ax.xaxis_date()

为此,我想添加 2 条曲线,显示每次的活动任务数(23:51-23:52 之间为 1 个,23:52-53 为 2 个等,在 23:54 左右达到峰值)

问题在于我不能只绘制开始时间的直方图,因为不同的任务在时间上重叠。你知道创建这种直方图的好方法吗?

【问题讨论】:

  • 您不想先按 ID 对数据进行分组,还是希望使用 Gantt chart
  • 我觉得这个问题可以改进很多。目前,代码显示的是甘特图类型的绘图,而这根本不是您在此处询问的内容。我会删除所有关于断条的东西,因为那是你已经知道该怎么做的,而且对设想的任务毫无帮助。
  • 对不起,有一个错字,ID 是唯一的。我做了一些编辑。我试图澄清。我需要在同一张图上绘制两个图,一个甘特图 + 一条显示负载的曲线。我希望这可以澄清。

标签: python pandas matplotlib histogram


【解决方案1】:

我很确定有更简洁的方法来解决这个问题。尤其是在尝试创建直方图时,浮动数学问题非常烦人。不过,第一部分是一个简单的单衬里。只需按照建议使用hlines 并增加linewidth 即可创建您的条形图。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.cm as cm

df = pd.DataFrame([['A', 736758.993, 736758.995], ['B', 736758.995, 736758.998],
                   ['C', 736758.994, 736758.996], ['D', 736758.994, 736758.997],
                   ['E', 736758.997, 736758.998], ['F', 736758.995, 736758.999]],
                   columns = ['ID','From','To'])

#create two subplots with shared x axis
fig, (ax1, ax2) = plt.subplots(2, 1, sharex = True)
#plot1 - Gantt chart for individual IDs
ax1.hlines(df.ID, df.From, df.To, colors = cm.inferno(df.index/len(df)), linewidth = 20)

#plot 2 - make table of time series for each ID - multiply by 1000 to avoid float problems
hist_count = df.apply(lambda row: pd.Series(np.arange(1000 * row["From"], 1000 * row["To"])), axis = 1)
hist_count = pd.melt(hist_count)["value"].dropna().astype(int)
#find borders for bins 
min_time = hist_count.min(axis = 0)
max_time = hist_count.max(axis = 0)
#plot 2 histogram - add 0.0001 to prevent arbitrary binning due to float problems
ax2.hist(hist_count / 1000 + 0.0001, range = (min_time / 1000, (max_time + 1) / 1000), bins = max_time - min_time + 1)
ax2.xaxis_date()

plt.show()

样本数据集的输出:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-07
    • 1970-01-01
    • 1970-01-01
    • 2021-01-13
    • 2013-12-22
    • 1970-01-01
    相关资源
    最近更新 更多