创建使用百分比而不是计数的 matplotlib 或 seaborn 直方图?
Creating a matplotlib or seaborn histogram which uses percent rather than count?
具体来说,我正在处理 Kaggle Titanic 数据集。我绘制了一个堆叠直方图,显示了在泰坦尼克号上幸存和死亡的年龄。下面的代码。
figure = plt.figure(figsize=(15,8))
plt.hist([data[data['Survived']==1]['Age'], data[data['Survived']==0]['Age']], stacked=True, bins=30, label=['Survived','Dead'])
plt.xlabel('Age')
plt.ylabel('Number of passengers')
plt.legend()
我想更改图表以显示该年龄组幸存者百分比的每个箱子的单个图表。例如。如果一个 bin 包含 10-20 岁之间的年龄,并且该年龄组泰坦尼克号上 60% 的人幸存下来,那么高度将沿 y 轴排列 60%。
编辑:我可能对我正在寻找的内容给出了错误的解释。我没有更改 y 轴值,而是希望根据幸存百分比更改条形的实际形状。
图表中的第一个 bin 显示该年龄组大约有 65% 的人存活下来。我希望这个 bin 在 65% 处与 y 轴对齐。以下 bin 看起来分别为 90%、50%、10%,依此类推。
图表实际上看起来像这样:
pd.Series.hist
在下面使用 np.histogram
。
让我们探讨一下
np.random.seed([3,1415])
s = pd.Series(np.random.randn(100))
d = np.histogram(s, normed=True)
print('\nthese are the normalized counts\n')
print(d[0])
print('\nthese are the bin values, or average of the bin edges\n')
print(d[1])
these are the normalized counts
[ 0.11552497 0.18483996 0.06931498 0.32346993 0.39278491 0.36967992
0.32346993 0.25415494 0.25415494 0.02310499]
these are the bin edges
[-2.25905503 -1.82624818 -1.39344133 -0.96063448 -0.52782764 -0.09502079
0.33778606 0.77059291 1.20339976 1.6362066 2.06901345]
我们可以在计算平均 bin 边缘时绘制这些图
pd.Series(d[0], pd.Series(d[1]).rolling(2).mean().dropna().round(2).values).plot.bar()
实际答案
或者
我们可以简单地将 normed=True
传递给 pd.Series.hist
方法。它将它传递给 np.histogram
s.hist(normed=True)
首先,如果您创建一个按年龄组拆分数据的函数会更好
# This function splits our data frame in predifined age groups
def cutDF(df):
return pd.cut(
df,[0, 10, 20, 30, 40, 50, 60, 70, 80],
labels=['0-10', '11-20', '21-30', '31-40', '41-50', '51-60', '61-70', '71-80'])
data['AgeGroup'] = data[['Age']].apply(cutDF)
然后你可以绘制你的图表如下:
survival_per_age_group = data.groupby('AgeGroup')['Survived'].mean()
# Creating the plot that will show survival % per age group and gender
ax = survival_per_age_group.plot(kind='bar', color='green')
ax.set_title("Survivors by Age Group", fontsize=14, fontweight='bold')
ax.set_xlabel("Age Groups")
ax.set_ylabel("Percentage")
ax.tick_params(axis='x', top='off')
ax.tick_params(axis='y', right='off')
plt.xticks(rotation='horizontal')
# Importing the relevant fuction to format the y axis
from matplotlib.ticker import FuncFormatter
ax.yaxis.set_major_formatter(FuncFormatter(lambda y, _: '{:.0%}'.format(y)))
plt.show()
也许以下内容会有所帮助...
根据'Survived'
拆分数据帧
df_survived=df[df['Survived']==1]
df_not_survive=df[df['Survived']==0]
创建素材箱
age_bins=np.linspace(0,80,21)
使用np.histogram生成直方图数据
survived_hist=np.histogram(df_survived['Age'],bins=age_bins,range=(0,80))
not_survive_hist=np.histogram(df_not_survive['Age'],bins=age_bins,range=(0,80))
计算每个 bin 中的存活率
surv_rates=survived_hist[0]/(survived_hist[0]+not_survive_hist[0])
情节
plt.bar(age_bins[:-1],surv_rates,width=age_bins[1]-age_bins[0])
plt.xlabel('Age')
plt.ylabel('Survival Rate')
library Dexplot能够返回组的相对频率。目前,您需要使用 cut
函数将 pandas 中的 age
变量装箱。然后,您可以使用 Dexplot。
titanic['age2'] = pd.cut(titanic['age'], range(0, 110, 10))
将您要计算的变量 (age2
) 传递给 count
函数。使用 split
参数细分计数并按 age2
归一化。此外,这可能是堆积条形图的好时机
dxp.count('age2', data=titanic, split='survived', stacked=True, normalize='age2')
对于Seaborn,使用可以有多个值的参数stat
,see documentation。
seaborn.histplot(
data=data,
x='variable',
discrete=True,
stat='count'
)
stat
后的结果改为probability
。
seaborn.histplot(
data=data,
x='variable',
discrete=True,
stat='probability'
)
根据 documentation,目前支持的 stat
参数值为:
count
显示观察次数
frequency
显示观察数除以 bin 宽度
density
归一化计数,使直方图的面积为 1
probability
标准化计数,使条形高度之和为 1
具体来说,我正在处理 Kaggle Titanic 数据集。我绘制了一个堆叠直方图,显示了在泰坦尼克号上幸存和死亡的年龄。下面的代码。
figure = plt.figure(figsize=(15,8))
plt.hist([data[data['Survived']==1]['Age'], data[data['Survived']==0]['Age']], stacked=True, bins=30, label=['Survived','Dead'])
plt.xlabel('Age')
plt.ylabel('Number of passengers')
plt.legend()
我想更改图表以显示该年龄组幸存者百分比的每个箱子的单个图表。例如。如果一个 bin 包含 10-20 岁之间的年龄,并且该年龄组泰坦尼克号上 60% 的人幸存下来,那么高度将沿 y 轴排列 60%。
编辑:我可能对我正在寻找的内容给出了错误的解释。我没有更改 y 轴值,而是希望根据幸存百分比更改条形的实际形状。
图表中的第一个 bin 显示该年龄组大约有 65% 的人存活下来。我希望这个 bin 在 65% 处与 y 轴对齐。以下 bin 看起来分别为 90%、50%、10%,依此类推。
图表实际上看起来像这样:
pd.Series.hist
在下面使用 np.histogram
。
让我们探讨一下
np.random.seed([3,1415])
s = pd.Series(np.random.randn(100))
d = np.histogram(s, normed=True)
print('\nthese are the normalized counts\n')
print(d[0])
print('\nthese are the bin values, or average of the bin edges\n')
print(d[1])
these are the normalized counts
[ 0.11552497 0.18483996 0.06931498 0.32346993 0.39278491 0.36967992
0.32346993 0.25415494 0.25415494 0.02310499]
these are the bin edges
[-2.25905503 -1.82624818 -1.39344133 -0.96063448 -0.52782764 -0.09502079
0.33778606 0.77059291 1.20339976 1.6362066 2.06901345]
我们可以在计算平均 bin 边缘时绘制这些图
pd.Series(d[0], pd.Series(d[1]).rolling(2).mean().dropna().round(2).values).plot.bar()
实际答案
或者
我们可以简单地将 normed=True
传递给 pd.Series.hist
方法。它将它传递给 np.histogram
s.hist(normed=True)
首先,如果您创建一个按年龄组拆分数据的函数会更好
# This function splits our data frame in predifined age groups
def cutDF(df):
return pd.cut(
df,[0, 10, 20, 30, 40, 50, 60, 70, 80],
labels=['0-10', '11-20', '21-30', '31-40', '41-50', '51-60', '61-70', '71-80'])
data['AgeGroup'] = data[['Age']].apply(cutDF)
然后你可以绘制你的图表如下:
survival_per_age_group = data.groupby('AgeGroup')['Survived'].mean()
# Creating the plot that will show survival % per age group and gender
ax = survival_per_age_group.plot(kind='bar', color='green')
ax.set_title("Survivors by Age Group", fontsize=14, fontweight='bold')
ax.set_xlabel("Age Groups")
ax.set_ylabel("Percentage")
ax.tick_params(axis='x', top='off')
ax.tick_params(axis='y', right='off')
plt.xticks(rotation='horizontal')
# Importing the relevant fuction to format the y axis
from matplotlib.ticker import FuncFormatter
ax.yaxis.set_major_formatter(FuncFormatter(lambda y, _: '{:.0%}'.format(y)))
plt.show()
也许以下内容会有所帮助...
根据'Survived'
拆分数据帧df_survived=df[df['Survived']==1] df_not_survive=df[df['Survived']==0]
创建素材箱
age_bins=np.linspace(0,80,21)
使用np.histogram生成直方图数据
survived_hist=np.histogram(df_survived['Age'],bins=age_bins,range=(0,80)) not_survive_hist=np.histogram(df_not_survive['Age'],bins=age_bins,range=(0,80))
计算每个 bin 中的存活率
surv_rates=survived_hist[0]/(survived_hist[0]+not_survive_hist[0])
情节
plt.bar(age_bins[:-1],surv_rates,width=age_bins[1]-age_bins[0]) plt.xlabel('Age') plt.ylabel('Survival Rate')
library Dexplot能够返回组的相对频率。目前,您需要使用 cut
函数将 pandas 中的 age
变量装箱。然后,您可以使用 Dexplot。
titanic['age2'] = pd.cut(titanic['age'], range(0, 110, 10))
将您要计算的变量 (age2
) 传递给 count
函数。使用 split
参数细分计数并按 age2
归一化。此外,这可能是堆积条形图的好时机
dxp.count('age2', data=titanic, split='survived', stacked=True, normalize='age2')
对于Seaborn,使用可以有多个值的参数stat
,see documentation。
seaborn.histplot(
data=data,
x='variable',
discrete=True,
stat='count'
)
stat
后的结果改为probability
。
seaborn.histplot(
data=data,
x='variable',
discrete=True,
stat='probability'
)
根据 documentation,目前支持的 stat
参数值为:
count
显示观察次数frequency
显示观察数除以 bin 宽度density
归一化计数,使直方图的面积为 1probability
标准化计数,使条形高度之和为 1