I'm hoping to display the percentages in each subplot using Seaborn displot. Using below, I plot each unique value in Item
in different rows. While the each unique value in Num takes up the x-axis. The values from Label
are currently displayed, but I'm also hoping to display the percentages as text.
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
df = pd.DataFrame({
'Num' : [1,2,1,2,3,2,1,3,2,2,1,2,3,3,1,3],
'Label' : ['A','B','C','B','B','C','C','B','B','A','C','A','B','A','C','A'],
'Item' : ['Up','Left','Up','Left','Down','Right','Up','Down','Right','Down','Right','Up','Up','Right','Down','Left'],
})
g = sns.displot(data = df,
x = 'Num',
row = 'Item',
hue = 'Label',
row_order = ['Up','Down','Left','Right'],
discrete = True,
multiple = 'fill',
aspect = 4,
height = 2,
)
for ax in g.axes.flat:
ax.xaxis.labelpad = 8
ax.yaxis.labelpad = 8
ax.tick_params(which = 'both', width = 0.8, labelsize = 8)
for p in g.axes.flat:
txt = str(p.get_height().round(2)) + '%'
txt_x = p.get_x()
txt_y = p.get_height()
g.ax.text(txt_x,txt_y,txt)
The PercentFormatter
labels the y-axis in percentage format. To get access to the patches with the individual bars, you need to loop through the patches of each ax. Each bar has a xy position, a height and a width. The height indicates the percentage. The center of the bar can be calculated using x, y and half the width and height.
import matplotlib.pyplot as plt
from matplotlib.ticker import PercentFormatter, MultipleLocator
import seaborn as sns
import pandas as pd
df = pd.DataFrame({
'Num': [1, 2, 1, 2, 3, 2, 1, 3, 2, 2, 1, 2, 3, 3, 1, 3],
'Label': ['A', 'B', 'C', 'B', 'B', 'C', 'C', 'B', 'B', 'A', 'C', 'A', 'B', 'A', 'C', 'A'],
'Item': ['Up', 'Left', 'Up', 'Left', 'Down', 'Right', 'Up', 'Down', 'Right', 'Down', 'Right', 'Up', 'Up', 'Right',
'Down', 'Left'],
})
g = sns.displot(data=df,
x='Num',
row='Item',
hue='Label',
row_order=['Up', 'Down', 'Left', 'Right'],
discrete=True,
multiple='fill',
aspect=4,
height=2,
)
for ax in g.axes.flat:
ax.xaxis.labelpad = 8
ax.yaxis.labelpad = 8
ax.tick_params(which='both', width=0.8, labelsize=8)
ax.xaxis.set_major_locator(MultipleLocator(1)) # x ticks at multiples of 1
ax.yaxis.set_major_formatter(PercentFormatter(1)) # percentage using 1 for 100%
ax.set_ylabel('Percentage')
for p in ax.patches:
h = p.get_height()
if h > 0: # skip empty bars
txt = f'{h * 100:.2f} %'
txt_x = p.get_x() + p.get_width() / 2
txt_y = p.get_y() + h / 2
ax.text(txt_x, txt_y, txt, ha='center', va='center')
plt.subplots_adjust(left=0.09) # make a bit more room for the label
plt.show()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.