pandas 数据框中每个索引箱的带有水平条形子图的图表

bfhwhh0e  于 2023-08-01  发布在  其他
关注(0)|答案(1)|浏览(83)

我有多索引的数据框架(按“5min_interval”和“price”索引排序)。

quantity
5min_intervals       price 
2023-07-27 17:40:00  172.20     330
                     172.19       1
2023-07-27 17:45:00  172.25       4
                     172.24      59
                     172.23     101
                     172.22     224
                     172.21      64
                     172.20     303
                     172.19     740
                     172.18      26
2023-07-27 17:50:00  172.17      30
                     172.16       2
                     172.15    1014
                     172.14     781
                     172.13    1285

字符串
我知道用df.plot.barh()简单的水平条形图。我也可以通过'5min_intervals'索引迭代dataframe

for date in df.index.levels[0]:
    print(df.loc[date])


并获取每个'5min_intervals'索引的 Dataframe ,如下所示

quantity
price           
172.20       330
172.19         1


有没有任何方法可以创建一个图表与matplotlib,其中每个'5min_intervals'索引将是水平条形图。示意图如下所示

ruarlubt

ruarlubt1#

让我们准备一些虚拟数据来处理:

from pandas import DataFrame, Timestamp

data = {
    'quantity': {
        (Timestamp('2023-07-27 17:40:00'), 172.2): 330,
        (Timestamp('2023-07-27 17:40:00'), 172.19): 1,
        (Timestamp('2023-07-27 17:45:00'), 172.25): 4,
        (Timestamp('2023-07-27 17:45:00'), 172.24): 59,
        (Timestamp('2023-07-27 17:45:00'), 172.23): 101,
        (Timestamp('2023-07-27 17:45:00'), 172.22): 224,
        (Timestamp('2023-07-27 17:45:00'), 172.21): 64,
        (Timestamp('2023-07-27 17:45:00'), 172.2): 303,
        (Timestamp('2023-07-27 17:45:00'), 172.19): 740,
        (Timestamp('2023-07-27 17:45:00'), 172.18): 26,
        (Timestamp('2023-07-27 17:50:00'), 172.17): 30,
        (Timestamp('2023-07-27 17:50:00'), 172.16): 2,
        (Timestamp('2023-07-27 17:50:00'), 172.15): 1014,
        (Timestamp('2023-07-27 17:50:00'), 172.14): 781,
        (Timestamp('2023-07-27 17:50:00'), 172.13): 1285
    }
}

df = DataFrame(data)

字符串
至于图形,几乎没有像你要求的东西准备从盒子。所以我们需要手动构建它。首先,让我们做一些基本的准备:

unique_time = df.index.get_level_values(0).unique().sort_values()
unique_price = df.index.get_level_values(1).unique().sort_values()

spacing = 0.2   # a minimum distance between two consecutive horizontal lines
values = (1-spacing) * df/df.max()   # relative lengths of horizontal lines
base = DataFrame(index=unique_price)   # the widest blank frame with prices


为了构建图形,我们可以使用barh(y, width, height, left)-水平条-价格作为第一个参数,时间作为左移,值代替宽度,以及一些固定的小高度。为了使非常小的值可见,我们可以再次使用barh用一个小刻度标记一行的开始(左端)。

import matplotlib.pyplot as plt
from matplotlib.colors import TABLEAU_COLORS
from itertools import cycle

fig, ax = plt.subplots(figsize=(7,7))

xlabels = unique_time.astype(str)
ylabels = unique_price.astype(str)

ax.set_xticks(range(len(xlabels)), xlabels, rotation=45)
ax.set_yticks(range(len(ylabels)), ylabels)
ax.set_xlim([-0.5,len(xlabels)])
ax.set_ylim([-1, len(ylabels)])

for i, (t, c) in enumerate(zip(unique_time, cycle(TABLEAU_COLORS))):
    pr = base.join(values.loc[t]).squeeze()
    # draw horizontal lines, shifted left by i-th timepoint
    ax.barh(ylabels, pr, 0.1, i, color=c)
    # put tics at the left end of lines, i.e. their beginning
    ax.barh(ylabels, 0.01*pr.notna(), 0.3, i, color=c)

ax.grid(axis='y', linestyle='--', linewidth=0.5)
fig.tight_layout()
plt.show()


下面是输出:x1c 0d1x的数据

python           : 3.11
pandas           : 1.5.1
matplotlib       : 3.6.1

相关问题