在 Pandas/Matplotlib 上输入图例后命名堆积条
Posted
技术标签:
【中文标题】在 Pandas/Matplotlib 上输入图例后命名堆积条【英文标题】:Name stacked bars after legend entry on Pandas/Matplotlib 【发布时间】:2021-07-21 05:17:12 【问题描述】:我有一个堆积条形图,非常适合我要查找的内容。我的问题是处理标签。
我可以在其值(数字)之后标记每个堆叠条,但我希望在其名称(在图例上)之后标记它。
有人知道如何解决这个问题吗?
ps.:很遗憾我还不能发布图片。
I have something like this:
####
#15#
####
oooo ####
oooo #35#
o55o ####
oooo ####
oooo o12o
And need like this:
####
#### A
####
oooo ####
oooo B #### A
oooo ####
oooo oooo B
【问题讨论】:
【参考方案1】:我写了一个简短的例子,请看下面的代码:
import numpy as np
import matplotlib.pyplot as plt
# Some data
x = np.array([0, 1, 2])
y1 = np.array([3, 4, 1])
y2 = np.array([2, 2, 4])
# label text
label_y1 = 'y1'
label_y2 = 'y2'
# Create the base plot
fig, ax = plt.subplots()
bars_y1 = ax.bar(x, y1, width=0.5, label=label_y1)
bars_y2 = ax.bar(x, y2, width=0.5, label=label_y2, bottom=y1)
# Function to add labels to the plot
def add_labels(ax, bars, label):
for bar in bars:
# Get the desired x and y locations
xloc = bar.get_x() + 1.05 * bar.get_width()
yloc = bar.get_y() + bar.get_height() / 2
ax.annotate(label, xy=(xloc, yloc), va='center', ha='left', color=bar.get_facecolor())
# Add the labels in the plot
add_labels(ax, bars_y1, label_y1)
add_labels(ax, bars_y2, label_y2)
plt.show()
首先,我生成一些虚拟数据(x
、y1
和 y2
)。然后,我定义所需的标签文本(label_y1
和label_y2
),最后我使用Axes.bar
制作基本条形图。请注意,我存储了来自 Axes.bar
调用的返回值,这是一个包含所有条形的容器!
现在,我们进入有趣的部分。我定义了一个名为add_labels
的函数。作为输入,它需要感兴趣的轴、一个包含所有条形的容器和所需的标签文本。在函数体中,我遍历所有条形并确定标签文本所需的 x 和 y 位置。使用这些值,我使用Axes.annotate
方法将标签文本放置在这些坐标处。在脚本结束时,我只需使用所需的参数调用 add_labels
函数即可获得以下输出:
这是你要找的吗?
【讨论】:
嗨,德克斯!非常感谢您的回答!我以不同的方式解决了它,但你的回答帮助我意识到我错过了什么!谢谢!!!我的问题有一些额外的要求,例如: - 数据框上的可变列数 - 行数 - 可用大小所以我使用图中的补丁来处理图例,如下所示【参考方案2】:根据 Dex 的回答,我想出了一个解决方案。 使用补丁,它将从图表中获取每个条形图。条形按行排列。所以如果你有一个 4x3 的数据框:
zero um dois
0 a b c
1 d e f
2 g h i
3 j k l
bars.patches 的每一列将依次排列:[a,d,g,j,b,e,h,k,c,f,i,l]
因此,每 4 个项目(行),它就会重新启动。为此,我们可以根据 df 上的行数使用 mod 函数 (%):
i % len(df.index) == 0 #moves position counter to the next column name
代码最终是这样的:
import pandas as pd
import numpy as np
# Some data
x = np.array(['zero', 'um', 'dois'])
y = np.array([[3, 4, 8],[2, 2, 4],[6, 7, 8]])
df = pd.DataFrame(y, columns = x)
print(df)
zero um dois
0 3 4 8
1 2 2 4
2 6 7 8
title = 'Chart Title'
bars = df.plot.bar(ax = ax, stacked = True, title = title, legend = False)
plt.xlabel('x axis label')
pos = -1
for i, bar in enumerate(bars.patches): #runs through every single bar on the chart
if i % len(df.index) == 0: #based on lenght of the index, gets which label
pos += 1 #to use from the columns. Returning to the
#first after completing a row
xloc = bar.get_x()
yloc = bar.get_y() + bar.get_height() / 2
if bar.get_height() > 30:
ax.annotate(str(df.columns[pos]), xy = (xloc, yloc), va='center', ha='left')
#df.columns[pos] will get the correct column name
因此,无论数据框的大小如何,它都会在条形旁边绘制列名
图表示例: https://i.stack.imgur.com/2iHau.png
【讨论】:
以上是关于在 Pandas/Matplotlib 上输入图例后命名堆积条的主要内容,如果未能解决你的问题,请参考以下文章
Pandas Matplotlib:如何更改散点图中图例的形状和大小?
如何在 pandas / matplotlib 中绘制多条线
解决Pandas/Matplotlib保存图形时坐标轴标签太长导致显示不全的问题