numpy 按最大值到最小值排序的堆叠条形图

iswrvxsc  于 2023-08-05  发布在  其他
关注(0)|答案(2)|浏览(99)

**问题:**我想制作一个堆叠条形图,其中堆叠的每个值按最大值(底部)到最小值排序。

我有一个DataFrame,其中一个方向包含一个时间序列,另一个方向包含12个不同的类别,如下所示:

bz =  ['NO1','NO2','NO3','NO4','NO5','DK1','DK2','FI','SE1','SE2','SE3','SE4']
df = pd.DataFrame(columns = bz, index = range(0,24,1), data=np.random.randint(0,100,size=(24, 12)))

字符串
我无法在同一行代码中排序和绘制值,所以我重新排序为每小时硬编码,并按最高值到最低值排序,如下所示:

hour1 = df.loc[:,0].sort_values(ascending = True)
hour2 = df.loc[:,1].sort_values(ascending = True)
hour3 = df.loc[:,2].sort_values(ascending = True)
...


但是我不知道如何正确地把它们放在一个堆栈中。

预期结果:

bz中的每个类别都按每个连续小时的值(最大值在底部,最小值在顶部)进行堆叠和排序。其中每个x值是变量hour1,hour2等之一。

d8tt03nd

d8tt03nd1#

我不知道有什么简单的方法可以做到这一点。也就是说,我能够得到期望的结果(至少我认为你期望的结果是这样的)。
首先,我为每一行创建了一个numpy数组的排序索引。然后,我循环遍历数据框(通常是不好的做法),并创建了堆叠条形图。堆叠是通过首先根据排序对行进行排序并计算累积和来完成的,确保从0开始并忽略最后一个值以设置每个条形的底部。然后通过排序设置颜色,以确保每个循环中每列的颜色都相同。
由于这种“黑客”方法,您还需要创建一个自定义图例,我按照matplotlib tutorial的方法完成了这一操作。我还必须将图例移到外面,这样它就不会阻塞数据,我在this answer之后这样做了。对于刻度线,我将其设置为以"hourXX"表示相应的小时,其中"XX"是从01开始的0填充数字。

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.patches import Patch
import numpy as np

rng = np.random.default_rng(10)

bz = ["NO1", "NO2", "NO3", "NO4", "NO5", "DK1",
      "DK2", "FI", "SE1", "SE2", "SE3", "SE4"]
df = pd.DataFrame(columns=bz,
                  index=range(0, 24, 1),
                  data=rng.integers(0, 100, size=(24, 12)))
sorted_indices = np.argsort(-df).to_numpy()

cmap = plt.get_cmap("tab20")
fig, ax = plt.subplots()
for index, row in df.iterrows():
    row = row.iloc[sorted_indices[index]]
    bottoms = np.hstack(([0], np.cumsum(row)[:-1]))
    ax.bar(index, row, bottom=bottoms, color=cmap(sorted_indices[index]))

ticks = [f"hour{n:02}" for n in range(1, len(df)+1)]
ax.set_xticks(np.arange(len(df)), ticks, rotation=90)

legend_elements = []
for index, name in enumerate(bz):
    legend_elements.append(Patch(facecolor=cmap(index), label=name))

ax.legend(handles=legend_elements, bbox_to_anchor=(1.04, 1), loc="upper left")
fig.tight_layout()
fig.show()

字符串


的数据

jv4diomz

jv4diomz2#

IIUC,您需要创建一个包含排序列的新DataFrame,然后绘制:

>>> pd.concat([df[col].sort_values(ignore_index=True) for col in df.columns],axis=1).plot.bar(stacked=True)

字符串


的数据

相关问题