Как сделать столбчатую диаграмму значений фреймов данных в процентах в matplotlib/pandas

#python #pandas #matplotlib #bar-chart #stacked-chart

Вопрос:

У меня есть список 0,1 в фрейме данных. Как я могу построить процентную диаграмму в панд или matplotlib, чтобы в легенде 1,0 и написанной аннотации процентной доли 1,0 сравнивался со всем списком?

 import pandas as pd import matplotlib.pyplot as plt import numpy as np  list_1 = [1,0,1,1,1,0,0,1,0,1,1,1,0,0,1,0,1,1,1,0,0,1,0,1,1,1,0,0,1,0,1,1,1,0,0,] list_2 = [1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,0,1,1,1,0,1,1,0,1,1,1,0,1,1,0,1,1,1,1,0,] list_3 = [1,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,1,1,1,0,0,]  df1 = pd.DataFrame({'Data1': list_1,'Data2': list_2,'Data3': list_3})  df1 = df1.mean() df1.columns = ['1'] df2 = pd.DataFrame(1-df1) df2.columns = ['0'] df1 = pd.DataFrame(df1) df = pd.concat([df1,df2], axis=1) df.plot( kind='barh',stacked = True,mark_right = True) # this is ok  plt.text(1,2,'%', va = 'center', ha = 'center')  plt.show()  

Я понимаю этот сюжет: введите описание изображения здесь

Однако я бы получил процент от 1 и 0 для 3 списков, так что что-то вроде этого:

введите описание изображения здесь

Ответ №1:

Вы можете использовать seaborn histplot с multiple='fill'

 import matplotlib.pyplot as plt import seaborn as sns import pandas as pd  list_1 = [1,0,1,1,1,0,0,1,0,1,1,1,0,0,1,0,1,1,1,0,0,1,0,1,1,1,0,0,1,0,1,1,1,0,0] list_2 = [1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,0,1,1,1,0,1,1,0,1,1,1,0,1,1,0,1,1,1,1,0] list_3 = [1,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,1,1,1,0,0]  df = pd.DataFrame({'Data1': list_1, 'Data2': list_2, 'Data3': list_3}) sns.set(style='white') ax = sns.histplot(data=df, stat='percent', multiple='fill', discrete=True, shrink=0.8) sns.despine() ax.set_xticks([0, 1])  

sns.гистограмма множественная='заполнение'

Для горизонтальных полос и дальнейшей настройки это помогает преобразовать фрейм данных в длинный формат.

 import matplotlib.pyplot as plt from matplotlib.ticker import PercentFormatter import seaborn as sns import pandas as pd  list_1 = [1,0,1,1,1,0,0,1,0,1,1,1,0,0,1,0,1,1,1,0,0,1,0,1,1,1,0,0,1,0,1,1,1,0,0] list_2 = [1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,0,1,1,1,0,1,1,0,1,1,1,0,1,1,0,1,1,1,1,0] list_3 = [1,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,1,1,1,0,0]  df = pd.DataFrame({'Data1': list_1, 'Data2': list_2, 'Data3': list_3}) sns.set(style='white') fig, ax = plt.subplots(figsize=(10, 4)) sns.histplot(data=df.melt(var_name='Dataset', value_name='Value'), y='Value', hue='Dataset',  stat='percent', multiple='fill', discrete=True, shrink=0.8,  palette=['tomato', 'limegreen', 'cornflowerblue'], alpha=1, ax=ax) sns.despine() sns.move_legend(ax, bbox_to_anchor=(1.01, 1.02), loc='upper left') ax.set_yticks([0, 1]) ax.xaxis.set_major_formatter(PercentFormatter(1)) for p in ax.patches:  h, w, x, y = p.get_height(), p.get_width(), p.get_x(), p.get_y()  text = f'{w * 100:0.2f} %'  ax.annotate(text=text, xy=(x   w / 2, y   h / 2), ha='center', va='center', color='white', size=20) plt.tight_layout() plt.show()   

гистограмма сиборна, разделяющая 100%