0

如何获取熊猫条形图中元素的颜色?

示例:我有一个条形图,其中包含几列的历史数据。现在我想绘制一条水平线,每列的平均值与条形颜色相同。

这个问题讨论了对 matplotlib 线图颜色的访问:How to get color of most recent plotted line in Python's plt

它允许我获得线图的颜色,但不能获得条形图的颜色。我想可能有一个等价于get_lines(),但我找不到它。

"""Access bar plot colors."""

import pandas as pd
df = pd.DataFrame(data={'col1': [1, 2], 'col2': [3, 4]})
ax = df.plot()

# This works fine for line plots
for i, col in enumerate(df):
    color = ax.get_lines()[i].get_color()
    print(color)


ax = df.plot(kind='bar')

# This does not work: "IndexError: list index out of range"
for i, col in enumerate(df):
    color = ax.get_lines()[i].get_color()
    print(color)
4

3 回答 3

2

你可以使用.patches

>>> ax = df.plot(kind='bar')
>>> print(ax.patches)
[<matplotlib.patches.Rectangle object at 0x7f02e2ba3760>, <matplotlib.patches.Rectangle object at 0x7f02e2ba35e0>, <matplotlib.patches.Rectangle object at 0x7f02e2ba3dc0>, <matplotlib.patches.Rectangle object at 0x7f02e2ba35b0>]
>>> for i, col in enumerate(df):
...     color = ax.patches[i].get_facecolor()
...     print(color)
...
(0.12156862745098039, 0.4666666666666667, 0.7058823529411765, 1.0)
(0.12156862745098039, 0.4666666666666667, 0.7058823529411765, 1.0)

但是,正如您所见,枚举它们并不能告诉您哪个补丁对应于哪个数据。在这里,我们抓取了 2 个相同颜色的矩形。因此,我会推荐.get_legend_handles_labels()用于构建图例的函数:

>>> print(ax.get_legend_handles_labels())
([<BarContainer object of 2 artists>, <BarContainer object of 2 artists>], ['col1', 'col2'])
>>> for bars, column in zip(*ax.get_legend_handles_labels()):
...     color = bars[0].get_facecolor()
...     print(column, color)
...
col1 (0.12156862745098039, 0.4666666666666667, 0.7058823529411765, 1.0)
col2 (1.0, 0.4980392156862745, 0.054901960784313725, 1.0)
于 2021-09-15T09:51:26.900 回答
2

我会改变它并自己明确地绘制数据,而不是试图从返回的轴中拼出你需要的东西。但如果需要,Cimbali 已经展示了如何做到这一点。

这是更多的代码,但调用ax.bar自己可以让您捕获返回值。

例如情节:

fig, ax = plt.subplots()

idx = df.index.values

width = 0.25
col1_bars = ax.bar(idx - width/2, 'col1', width, label='Col1', data=df)
col2_bars = ax.bar(idx + width/2, 'col2', width, label='Col2', data=df)

ax.set_xticks(idx)
ax.legend(loc=2)

然后,您可以通过检查返回的BarContainer对象来提取颜色或条形的任何其他属性:

col1_colors = list(map(lambda x: x.get_facecolor(), col1_bars))
col2_colors = list(map(lambda x: x.get_facecolor(), col2_bars))
于 2021-09-15T10:08:06.827 回答
0

结合 Rutger 和 Cimbali 的答案,我想出了自己的解决方案,我将其留在这里以供参考:可以找到正确的 BarContainer 并以这种方式获得颜色。但是 Cimbali 对 get_legend_handles_labels() 的使用可能更优雅。:-)

"""Access bar plot colors."""

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame(data={'col1': [1, 2], 'col2': [3, 4]})

# This works fine for line plots
ax = df.plot()
for i, col in enumerate(df):
    color = ax.get_lines()[i].get_color()
    print(color)
    ax.axhline(y=df[col].mean(), label=col+' (mean)', linestyle='--', c=color)
plt.legend()
plt.show()

# Now try with bar plot: Access color via BarContainer
ax = df.plot(kind='bar')
for i, col in enumerate(df):
    color = ax.containers[i][0].get_facecolor()
    ax.axhline(y=df[col].mean(), label=col+' (mean)', linestyle='--', c=color)
plt.legend()
plt.show()

# Now try with bar plot: Access color via get_legend_handles_labels()
ax = df.plot(kind='bar')
for bars, col in zip(*ax.get_legend_handles_labels()):
    color = bars[0].get_facecolor()
    ax.axhline(y=df[col].mean(), label=col+' (mean)', linestyle='--', c=color)
plt.legend()
plt.show()

在此处输入图像描述

于 2021-09-15T11:56:01.377 回答