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!
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()
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.
Hatches can be added to most polygons in Matplotlib
, including bar
, fill_between
, contourf
, and children of Polygon
.
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()
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!
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()
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.
Hatches can be added to most polygons in Matplotlib
, including bar
, fill_between
, contourf
, and children of Polygon
.
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()