将哈希模式添加到seaborn条形图中

时间:2017-02-12 06:57:43

标签: python seaborn

我有一个使用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 个答案:

答案 0 :(得分:3)

删除面部颜色很简单,只需执行ax.set_facecolor('w'),但这会使网格线不可见。我建议您在绘图之前使用sns.set_style('whitegrid')代替,您将获得仅带有灰色水平网格线的白色背景。

至于不同的模式,这对于seaborn来说有点棘手,但它可以做到。您可以将hatch关键字参数传递给barplot,但它会应用于每个条形图,这并不能真正帮助您区分它们。不幸的是,在这里传递字典并不起作用。相反,您可以在构建它们以应用填充之后迭代条形图。您必须计算位置数量,但这对熊猫来说非常简单。事实证明,seaborn实际上绘制了每个色调,然后转移到下一个色调,所以在你的例子中它会绘制所有蓝色条,然后是所有绿色条,然后是所有红色条,所以逻辑非常简单:

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,因为它部分位于我计算机上的数字之外。