【问题标题】:How to to add stacked bar plot hatching in pandas? (...or how to get BarContainer vs AxisSubplot in pandas plot vs. matplotlib?)如何在熊猫中添加堆叠条形图孵化? (......或如何在熊猫情节与matplotlib中获得BarContainer vs AxesSubplot?)
【发布时间】:2020-04-22 10:40:54
【问题描述】:

我有一个使用matplotlib.pyplot.plot() 的代码示例,我想复制它以在堆叠条形图上制作阴影条形段。但是,我一直在使用pandas.DataFrame.plot() 而不是matplotlib.pyplot.plot() 制作我所有的其他图形,并且我也想在这里继续。示例代码返回一个BarContainer 对象的元组,pandas.DataFrame.plot() 返回一个AxisSubplot 对象,我不知道如何在两者之间导航。

关于如何从pandas.DataFrame.plot() 中获取BarContainer 对象以便我可以使用它们来复制示例的任何建议?

如果没有,对于如何使用pandas.DataFrame.plot() 在堆叠条形图上为每个彩色条形段添加阴影的目标,有什么建议吗?

使用我的数据,阴影有助于区分相似的颜色,因为我有很多类别和项目,否则结果看起来很相似。 (我知道我也可以找到一种方法来绘制更简单的东西,但这样做对我的探索性数据分析很有帮助。)谢谢!


用于填充堆叠条形图的每个彩色条形段的示例工作代码(来自此处:https://matplotlib.org/examples/pylab_examples/hatch_demo.html):

import pandas as pd
import numpy as np  
import matplotlib.pyplot as plt

fig = plt.figure()
ax2 = fig.add_subplot(111)
bars = ax2.bar(range(1, 5), range(1, 5), color='yellow', ecolor='black') + \
    ax2.bar(range(1, 5), [6] * 4, bottom=range(1, 5), color='green', ecolor='black')

patterns = ('-', '+', 'x', '\\', '*', 'o', 'O', '.')
for bar, pattern in zip(bars, patterns):
    bar.set_hatch(pattern)


我希望每个彩色条段都有阴影的代码(带有简化数据):

df = pd.DataFrame(np.random.uniform(0,10, size=(5,26)))
df.columns=['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
ax = df.plot.barh(stacked=True, width=0.98, figsize=(10,5), cmap='gist_ncar')

【问题讨论】:

  • 每种颜色都有 26 个独特的补丁? (还有那么多吗?)
  • @ ALollz - 不,即使只是几个补丁也可以正常工作。目的是更好地区分具有相似颜色的类别,例如,以不同的方式孵化浅绿色、中绿色和深绿色等。为此,可以将相同的图案重复用于不同的颜色,而不是相邻的颜色.

标签: python pandas matplotlib bar-chart stacked


【解决方案1】:

如何从 pandas.DataFrame.plot() 中获取 BarContainer 对象

将它们从 Axes' 容器属性中过滤掉

>>> import matplotlib as mpl
>>> ax = df.plot.barh(stacked=True, width=0.98, figsize=(10,5), cmap='gist_ncar')
>>> ax.containers[:4]
[<BarContainer object of 5 artists>, <BarContainer object of 5 artists>, <BarContainer object of 5 artists>, <BarContainer object of 5 artists>]
>>> bars = [thing for thing in ax.containers if isinstance(thing,mpl.container.BarContainer)]

在每个 BarContainer 的 Rectangles 上设置影线。

import itertools
patterns = itertools.cycle(('-', '+', 'x', '\\', '*', 'o', 'O', '.'))
for bar in bars:
    for patch in bar:
        patch.set_hatch(next(patterns))
L = ax.legend()    # so hatches will show up in the legend

这样做可以确保您不会抓取不属于栏的补丁。


如何让相同的补丁显示在不同项目的相同颜色上

也许在遍历每个条中的补丁时,检查它的 facecolor (patch.get_facecolor) 并维护 {facecolor:hatchsymbol} 的字典 - 如果 facecolor 在字典集中 that孵化否则得到一个新的孵化符号,将它和颜色添加到字典中设置孵化。

d = {}
for bar in bars:
    for patch in bar:
        pat = d.setdefault(patch.get_facecolor(), next(patterns))
        patch.set_hatch(pat)
L = ax.legend()    

Matplotlib Tutorials 值得努力。

【讨论】:

  • 或者只是ax.patches
  • @ALollz - 是的,您必须访问每个 BarContainer 中的补丁来设置阴影。 ..你为什么要删除,我要删除我的。
  • 我不确定为每种颜色获得相同的阴影是否很棒。感觉有点像 hack 虽然随意添加它
  • 谢谢,知道如何让阴影也显示在图例中的颜色中吗?
  • 或者如何让相同的补丁显示在不同项目的相同颜色上(例如,如果项目 0 的红色是“+”,那么项目 1-4 的红色是“+”也)?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-10-13
  • 2019-08-03
  • 2020-02-04
  • 1970-01-01
  • 2021-11-10
  • 2018-10-05
  • 1970-01-01
相关资源
最近更新 更多