Is it possible to add hatches to each individual bar in seaborn.barplot?

Question:

ax = sns.barplot(x="size", y="algorithm", hue="ordering", data=df2, palette=sns.color_palette("cubehelix", 4))

After (or before) creating a seaborn barplot, is there a way for me to pass in hatch (fill in patterns along with the colors) values for each bar?
A way to do this in seaborn or matplotlib would help a lot!

Asked By: kxirog

||

Answers:

You can loop over the bars created by catching the AxesSubplot returned by barplot, then looping over its patches. You can then set hatches for each individual bar using .set_hatch()

Here’s a minimal example, which is a modified version of the barplot example from here.

import matplotlib.pyplot as plt
import seaborn as sns

# Set style
sns.set(style="whitegrid", color_codes=True)

# Load some sample data
titanic = sns.load_dataset("titanic")

# Make the barplot
bar = sns.barplot(x="sex", y="survived", hue="class", data=titanic);

# Define some hatches
hatches = ['-', '+', 'x', '\', '*', 'o']

# Loop over the bars
for i,thisbar in enumerate(bar.patches):
    # Set a different hatch for each bar
    thisbar.set_hatch(hatches[i])

plt.show()

enter image description here

Thanks to @kxirog in the comments for this additional info:

for i,thisbar in enumerate(bar.patches) will iterate over each colour at a time from left to right, so it will iterate over the left blue bar, then the right blue bar, then the left green bar, etc.

Answered By: tmdavison

Hatches can be added to most polygons in Matplotlib, including bar, fill_between, contourf, and children of Polygon.

Hash demo

Hatch style reference

Hash styles:

hatches = ['/', '\', '|', '-', '+', 'x', 'o', 'O', '.', '*']
hatches = ['//', '\\', '||', '--', '++', 'xx', 'oo', 'OO', '..', '**']
hatches = ['/o', '\|', '|*', '-\', '+o', 'x*', 'o-', 'O|', 'O.', '*-']

Sample code:

import matplotlib.pyplot as plt; plt.rcdefaults()
import numpy as np
import matplotlib.pyplot as plt

labels = ['G1', 'G2', 'G3', 'G4', 'G5']
men_means = [20, 34, 30, 35, 27]
women_means = [25, 32, 34, 20, 25]

x = np.arange(len(labels))  # the label locations
width = 0.25  # the width of the bars

fig, ax = plt.subplots()
rects1 = ax.bar(x - width/2, men_means, width, label='Men', hatch="//")
rects2 = ax.bar(x + width/2, women_means, width, label='Women', hatch="++")

# Add some text for labels, title and custom x-axis tick labels, etc.
ax.set_ylabel('Scores')
ax.set_xlabel('x label')
ax.set_title('Scores by group and gender')
ax.set_xticks(x, labels)
ax.legend()

ax.bar_label(rects1, padding=3)
ax.bar_label(rects2, padding=3)

fig.tight_layout()

plt.show()

enter image description here

Answered By: kamyar