给 seaborn 条形图添加哈希模式

9
我是一名有用的助手,可以为您进行文本翻译。以下是需要翻译的内容:

我使用seaborn创建了一个条形图。例如,可以按以下方式创建图表:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
data1 = pd.DataFrame(np.random.rand(17,3), columns=['A','B','C']).assign(Location=1)
data2 = pd.DataFrame(np.random.rand(17,3)+0.2, columns=['A','B','C']).assign(Location=2)
data3 = pd.DataFrame(np.random.rand(17,3)+0.4, columns=['A','B','C']).assign(Location=3)
cdf = pd.concat([data1, data2, data3])
mdf = pd.melt(cdf, id_vars=['Location'], var_name=['Letter'])
ax = sns.barplot(x="Location", y="value", hue="Letter", data=mdf, errwidth=0)  
ax.legend(loc='upper center', bbox_to_anchor=(0.5, 1.2), ncol=3, fancybox=True, shadow=True)
plt.show()

这将生成以下图表 enter image description here 我想按照以下方式自定义图表:
  1. 去掉面部颜色(将其设置为白色)
  2. 向图像添加哈希模式以区分组别 如何实现?
1个回答

13

移除背景颜色很容易,只需使用ax.set_facecolor('w'),但这会使网格线不可见。在绘图之前建议使用sns.set_style('whitegrid'),这样您将获得一个白色背景和灰色的水平网格线。

至于不同的填充模式,在seaborn中有点棘手,但是可以做到。您可以向barplot传递hatch关键字参数,但它将应用于每个条形图,这并不能真正帮助您区分它们。不幸的是,在此处传递字典不起作用。相反,您可以在构建完毕后迭代各个条形图以应用阴影。您将需要计算位置数量,但这对于pandas来说非常简单。事实证明,seaborn实际上在移动到下一个hue之前绘制每个hue,因此在您的示例中,它将绘制所有蓝色条形图,然后所有绿色条形图,然后所有红色条形图,因此逻辑相当简单:

num_locations = len(mdf.Location.unique())
hatches = itertools.cycle(['/', '//', '+', '-', 'x', '\\', '*', 'o', 'O', '.'])
for i, bar in enumerate(ax.patches):
    if i % num_locations == 0:
        hatch = next(hatches)
    bar.set_hatch(hatch)

所以完整的脚本是:

import itertools
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_style('whitegrid')
data1 = pd.DataFrame(np.random.rand(17, 3), columns=['A', 'B', 'C']).assign(Location=1)
data2 = pd.DataFrame(np.random.rand(17, 3) + 0.2, columns=['A', 'B', 'C']).assign(Location=2)
data3 = pd.DataFrame(np.random.rand(17, 3) + 0.4, columns=['A', 'B', 'C']).assign(Location=3)
cdf = pd.concat([data1, data2, data3])
mdf = pd.melt(cdf, id_vars=['Location'], var_name=['Letter'])
ax = sns.barplot(x="Location", y="value", hue="Letter", data=mdf, errwidth=0)

num_locations = len(mdf.Location.unique())
hatches = itertools.cycle(['/', '//', '+', '-', 'x', '\\', '*', 'o', 'O', '.'])
for i, bar in enumerate(ax.patches):
    if i % num_locations == 0:
        hatch = next(hatches)
    bar.set_hatch(hatch)

ax.legend(loc='upper center', bbox_to_anchor=(0.5, 1.1), ncol=3, fancybox=True, shadow=True)

plt.show()

然后我获得了输出结果

example


关于设置阴影和不同可用的阴影参考:http://matplotlib.org/examples/pylab_examples/hatch_demo.html

注意:我调整了图例的bbox_to_anchor,因为在我的电脑上它部分超出了图形范围。


1
或者是sns.set_style("ticks") - McGrady
谢谢。正是我想要的! - Dillion Ecmark
@McGrady 那也可以,我只是先尝试了 whitegrid,看起来不错,没必要再尝试其他样式。 - bheklilr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接