Matplotlib 将测量数据打印到条形图

Matplotlib 将测量数据打印到条形图,matplotlib,plot,bar-chart,Matplotlib,Plot,Bar Chart,我有一个数据框架,其中有“城市”、“性别”、“教育水平”和“你对某事的满意度”等栏 所以我试着把它画成条形图 #in here i select the neighbourhood as "X" #then i group it based on gender and try to plot it with the question of how satisfied are you about something. 这就是我得到的: 但我想得到这样的东西: 我想不出如何使这

我有一个数据框架,其中有“城市”、“性别”、“教育水平”和“你对某事的满意度”等栏

所以我试着把它画成条形图

#in here i select the neighbourhood as "X"
#then i group it based on gender and try to plot it with the question of how satisfied are you about something.
这就是我得到的:

但我想得到这样的东西:

我想不出如何使这些条的颜色与“你对某事的满意度”问题的答案相同


我希望能够在条形图的顶部添加百分比。如果有人能指引我,我将非常感激。谢谢。

您可以创建一个Seaborn,如下所示。对
x使用
gender
,将其放置在x轴上。使用
suited?
作为
hue
将性别的条形图划分为较小的条形图,并创建一个相应的图例。如果要确定这些值的特定顺序,可以使用
hue\u order
,也可以将列分类

将numpy导入为np
将matplotlib.pyplot作为plt导入
作为pd进口熊猫
导入seaborn作为sns
N=500
data=pd.DataFrame({'City':np.random.choice(['testcity','Other City'],N),
“性别”:np.random.choice(['Male','femal'],N),
“满意吗?”:np.random.choice(['1-非常差','2-差','3-中性','4-好','5-非常好'],N)})
sns.countplot(data=data[data['City']=='Test City'],x='Gender',palete='plasma',
色调=‘满意?’,色调顺序=[‘1-非常差’、‘2-差’、‘3-中性’、‘4-好’、‘5-非常好’)
plt.show()

在此基础上,可以进一步改进:

  • 更改酒吧高度,使每个性别的总和为一。这会将高度转换为百分比
  • 更改y轴的格式以显示百分比
  • 在改变高度的同时,也可以改变钢筋的宽度,在钢筋之间留一点间隙
  • 将图例放在底部,不带边框且带有方形标记
  • 将百分比作为文本添加到条形图上方
  • 添加水平轴网线
  • 隐藏脊骨
Seaborn有一个。最简单的方法是给出一个列表。但并不是说已经研究过现有调色板的颜色搭配得很好。可用于在许多情况下进行试验并找到颜色

代码中的变量
width\u scale
可用于设置间隙。在旧版本中,设置了
0.8
,留下了
0.2
的间隙。新示例的差距为
1.0-0.6=0.4

以下是一个例子:

将numpy导入为np
将matplotlib.pyplot作为plt导入
作为pd进口熊猫
导入seaborn作为sns
从matplotlib.ticker导入百分比格式化程序
N=500
data=pd.DataFrame({'City':np.random.choice(['testcity','Other City'],N),
“性别”:np.random.choice(['Male','Femal',N,p=[0.3,0.7]),N,
“满意吗?”:np.random.choice(['1-非常差','2-差','3-中性','4-好','5-非常好'],N)})
城市数据=数据[数据['city']=“测试城市”]
图,ax=plt.子批次(图尺寸=(14,4))
sns.countplot(data=city_data,x='Gender',order=['男','女'],ax=ax,
调色板=[‘绿松石’、‘番茄’、‘深蓝’、‘金色’、‘柠檬色’],
色调=‘满意?’,色调顺序=[‘1-非常差’、‘2-差’、‘3-中性’、‘4-好’、‘5-非常好’)
宽度\刻度=0.6 \钢筋的相对宽度,1.0表示钢筋接触;间隙将为1-宽度_刻度
对于ax容器中的棒材:
对于bar,zip中每个性别的总人数(bar,[sum(城市数据['gender']='Male')、sum(城市数据['gender']='Male')):
新建高度=条形图。获取高度()/每个性别的总高度
条形图。设置高度(新高度)
宽度=条。获取宽度()
x=bar.get_x()
设置宽度(宽度*宽度刻度)
条形图设置x(x+宽度*(1-宽度刻度)/2)#重新居中
如果np.isnan(新高度):
新高度=0
ax.text(x+width/2,新高度,f'{new_height*100:.1f}%\n',ha='center',va='bottom',旋转=90)
ax.设置x标签(“”)#删除多余的x标签
ax.set_ylabel(“”)
ax.tick_参数(axis='x',length=0,labelsize=14)#删除记号,加大文本
ax.yaxis.set\u major\u格式化程序(百分比格式化程序(1))
ax.grid(axis='y',ls=':',clip_on=False)
sns.sdespene(图,ax,顶部=真,右侧=真,左侧=真,底部=真)
ax.图例(ncol=5,bbox_至_锚定=(0.5,-0.1),loc=(上中心),frameon=False,handlelength=1,HandleLight=1)
ax.autoscale()#需要在更改高度后重新计算轴限制
ax.relim()
ax.边距(y=0.15,x=0.02)#在条顶部为文本留出一些空间
plt.紧_布局()
plt.show()

好的。我能做到,但如果我错了,请纠正我,如果我这次没有计算一个特定的标签,比如说“硕士生”,那么它就不会把它放在图表中了?最后一件事我想问的是,我怎么能将百分比文本向左改变90度?而不是这个“-”,我希望它像“|”一样。看起来,当前这些条的高度是“不是一个数字(
nan
)”而不是零。我更新了代码以测试
np.isnan()
。也许这对你有用?根据你想创作的情节类型,杰克·范德·普拉斯的作品似乎很有趣。github上提供了完整的内容和代码示例。除此之外,只需绘制您感兴趣的数据,尝试改进,在StackOverflow和官方文档中寻找答案。混乱的外观来自标签重叠。设置较小的字体大小会有所帮助。缩短文本(例如,省略空格和/或最后一位数字,如
f'{new\u height*100:.0f}%\n')
中所述也有帮助。您可以将位数设置为有条件的,例如
f'{new\u height*100:.1f}%\n'如果new\u height>0.001,则设置为'0%\n'