I am trying to manipulate hatch of a countplot by hue. Here is the plot code and the corresponding plot I drew:
ax = sns.countplot(
data=data, y='M_pattern', hue='HHFAMINC',
palette=color_palette, lw=0.5, ec='black',
)
plt.yticks(rotation=45, ha='right')
legend_labels, _ = ax.get_legend_handles_labels()
hatches = ['-', ' ', 'x', '\\']
# Loop over the bars
for i,thisbar in enumerate(bar.patches):
# Set a different hatch for each bar
thisbar.set_hatch(hatches[i])
plt.legend(
legend_labels, [
'Less than 10,000$ to 50,000$',
'50,000$ to 100,000$',
'100,000 to 150,000$',
'More than 150,000'
]
, title='Income categories'
)
plt.ylabel('Mandatory trip pattern')
plt.show()
Is there an straightforward way to hatch each income category separately?
CodePudding user response:
ax.containers
contains a list of each group of bars. To access individual bars, you can first loop through the containers
and then through each of the bars. Instead of working with enumerate
, it is highly recommended to use zip
to simultaneously loop through two lists.
To rename legend entries, a replace
onto the elements of the hue columns makes sure the correspondence between value and long name keeps intact after the dataset would be updated.
Here is an example using seaborn's 'tips' dataset. Here 3*hatch_pattern
makes the hatching 3 times as dense.
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
data = sns.load_dataset('tips')
ax = sns.countplot(
data=data.replace({'day': {'Thur': 'Thursday', 'Fri': 'Friday', 'Sat': 'Saturday', 'Sun': 'Sunday'}}),
y='time', hue='day',
palette='Set2', lw=0.5, ec='black')
plt.yticks(rotation=45, ha='right')
hatches = ['-', ' ', 'x', '\\']
for hatch_pattern, these_bars in zip(hatches, ax.containers):
for this_bar in these_bars:
this_bar.set_hatch(3 * hatch_pattern)
ax.legend(loc='upper right', title='Days')
plt.show()