matplotlib:带有日期时间x轴的条形图导致条形宽度无法控制

J S*_*att 7 matplotlib pandas

一段时间以来我一直在努力寻找解决方案。我正在使用 pandas 和 matplotlib 编写绘图库。我目前正在纠正使用字符串而不是时间戳的设计错误。这是一个错误的原因之一是它阻止了任何简单的方法来填充丢失的时间戳。

目标是创建一个类似于下图的堆叠条形图,但仅包含时间戳的一部分。(HH:MM、YYYY-MM-DD、YYYY-MM 等)此条形图是使用常规 pandas 索引生成的。

df = pd.read_csv('/path/to/file.csv', index_col='ts')
Run Code Online (Sandbox Code Playgroud)

体面的图表- 还没有足够的代表来嵌入图像

将我的索引转换为 pandas DateTimeIndex 后,使用相同的数据生成以下图表。

df = pd.read_csv('/path/to/file.csv', index_col='ts', parse_dates=True, infer_datetime_format=True)
Run Code Online (Sandbox Code Playgroud)

图表难以辨认

经过一些操作后,这里是用于绘图的数据框的结构:

work_type            CYCLECOUNT  PICK  REPLENISHMENT
ts                                                  
2018-10-25 05:00:00          35     0              5
2018-10-25 06:00:00          95     0              1
2018-10-25 07:00:00         125     0              1
2018-10-25 08:00:00           8     0              0
2018-10-25 09:00:00          19     0              3
2018-10-25 11:00:00           0     0             89
2018-10-25 12:00:00           1     0             59
2018-10-25 13:00:00           1   541            208
2018-10-25 14:00:00           0   516            123
2018-10-25 15:00:00           0   390             95
2018-10-25 16:00:00           2   315            167
2018-10-25 17:00:00           0   784             87
2018-10-25 18:00:00           1   521            145
2018-10-25 19:00:00           1   768            196
2018-10-25 20:00:00           0   769            113
2018-10-25 21:00:00           4   785            139
2018-10-25 22:00:00           0   858             81
2018-10-25 23:00:00           2   568             33
2018-10-26 00:00:00           6   530             60
2018-10-26 01:00:00          13   163             50
2018-10-26 02:00:00          12     4            158
2018-10-26 03:00:00           6     5             92
Run Code Online (Sandbox Code Playgroud)

这是用于生成图表的代码:

def create_stacked_bar_chart(
    self, dataframe, focus_total, ax: matplotlib.axes.Axes=None,
    top_bar_lbls=False, mid_bar_lbls=False, mid_bar_as_percent=False
):
        i = 0  # part_map keys
        k = 0  # pivot_df row index
        barwidth = 0.5
        part_map = dict()

        column_names = dataframe.columns.values

        if ax is None:
            fig, ax = self.create_figure()

        for col in column_names:
            if i == 0:
                part_map[i] = ax.bar(
                    dataframe.index,
                    dataframe[col].values,
                    barwidth, zorder=3
                )
            else:
                barstart = 0
                for j in range(i):
                    barstart += dataframe[column_names[j]]
                part_map[i] = ax.bar(
                     dataframe.index, dataframe[col].values,
                     barwidth, bottom=barstart, zorder=3
                )
Run Code Online (Sandbox Code Playgroud)

我还在 ax.bar() 函数中尝试了 dataframe.index.to_pydatetime() ,但似乎没有效果。我已经尝试了很多东西,但 to_pydatetime() 似乎在很多地方都被推荐。

J S*_*att 8

更新:此解决方案适用于本文中涉及的图表,但适用于可能遇到此问题的任何人......

===>日期 x 轴上的条形宽度单位是 <===

通过更改以下行解决了这个问题:

barwidth = 0.5
Run Code Online (Sandbox Code Playgroud)

barwidth = 0.5 * (1 / dataframe.shape[0])
Run Code Online (Sandbox Code Playgroud)

其中dataframe.shape[0]等于数据框中允许动态调整大小的行数。

  • 你的最后一句话很金!我需要以分钟为间隔绘制数据并使用“width = 0.5 * 1/ (24 * 60)”。 (2认同)