当前位置: 首页 > 后端技术 > Python

你知道matplotlib吗?对称条形图和发散条形图

时间:2023-03-26 11:06:23 Python

前两篇文章介绍了几种常见的条形图。事实上,对于简单的条形图,可以探索许多设置!在体育赛事中,经常会出现对称的柱状图,比如比较两个当红球员或球队在各个方面的得分等等。这也是在普通水平柱状图的基础上绘制的,作为万能的Python,当然可以绘制这种图形!闲话少说,直接上代码!df=pd.read_excel(r"D:\data\football\ManchesterCityvsLiverpool.xlsx")df这是从历年英超球队积分数据中截取曼城和利物浦的数据,做一个对称的Bar图表以了解这两支球队在2010-2019年间的得分情况。这是原始数据。光看表格对比不是很明显。我们来尝试画一个对称的条形图:plt.figure(figsize=(10,6))ax=plt.gca()#获取坐标轴对象ax.spines['right'].set_color('none')#设置右边框颜色为无色,隐藏右边框ax.spines['top'].set_color('none')#设置上边框颜色为无色,隐藏上边框ax.spines['bottom'].set_color('none')#设置上边框颜色为无色,隐藏上边框ax.yaxis.set_ticks_position('left')#指定左边缘为y轴ax.spines['left'].set_position(('data',0))#指定数据设置的左边(即指定y轴)绑定到x轴的0点plt.xticks([])#去掉x轴刻度plt.yticks(df.iloc[:,0].tolist())#设置y轴刻度为年份#绘制利物浦队柱状图,颜色默认蓝色plt.barh(df.iloc[:,0],df.iloc[:,1],height=0.5,label="Liverpool")#绘制曼城柱状图,y-两边需要显示柱状图轴,所以曼城队数据为负数,颜色设置为粉红色plt.barh(df.iloc[:,0],-df.iloc[:,2],height=0.5,label="ManchesterCity",color="pink")#通过循环标记曼城队的每个单杠。标签位置在对应栏的顶部,内容为球队在zip(range(len(df)),[2010,2011,2012,2013,2014,2015,2016,2017中i,j的积分,2018,2019]):plt.text(-df.iloc[:,2][i]-5,j,df.iloc[:,2][i])#标记利物浦队的每个横条通过一个循环,标签位置在对应栏的顶部,内容为球队在zip(range(len(df)),[2010,2011,2012,2013,2014,2015,2016年,2017,2018,2019]):plt.text(df.iloc[:,1][i]+1,j,df.iloc[:,1][i])plt.legend(loc=4);#显示图例,loc参数指定的图例位置在右下角,请看效果图:是不是比看上面的表格更清晰更容易,可以看到点的对比两队年年一览,整体来说曼城队比利物浦队强。至于异常的2019年数据,不是全年的数据,所以和其他年份的数据差别很大。发散条形图对称条形图只能比较两个个体如果涉及多个个体,对称条形图就不是很有用了。还有一种图可以同时显示多个个体,那就是发散条形图!但它也是有限的。发散柱状图只能表现出多个个体在某个指标上的差异,而对称柱状图则表现出两个个体在多个指标上的比较,所以在实际应用中需要区分需要达到什么。什么情况,我们直接上代码看图:df_yc=pd.read_excel(r"D:\data\football\teamrankingscore2019.xlsx")df_yc.head(10)#查看前十itemsDataThisisthepremierleagueteamsdataofthePremierLeagueteamsin2019:这是2019年所有球队前十的球队信息,绘制时会包含所有球队的数据。虽然形式上有所不同条形图与对称条形图类似,条形像是两个相反方向的延伸,两者还是有一些区别的。对称条形图直接取自其中一种数据类型。负数,而发散条形图是从所有数据中减去整体数据的均值,这样大于均值的数据仍然是正数,而低于均值的数据将变为负数:df_yc.integral.mean()#Find所有球队的平均分df_yc.points=df_yc.points-df_yc.points.mean()#所有球队的得分减去均值df_yc.sort_values("points",inplace=True)#减去均值后的得分是升序排列df_yc.head(10)#查看最新的前十数据由于条形图在绘制过程中是从底部开始绘制的,所以我们希望最小值绘制在底部,从下到上排序升序,所以原始数据应该按升序排序。此时,可以不设置任何东西,直接输出图(做个心理构造,直图有点难看):plt.barh(y=df_yc.iloc[:,0],width=df_yc.iloc[:,1],height=0.3,color=colors,alpha=0.5);是不是跟我之前看到的发散柱状图一样长,只是有点丑。让我们进行一些改进并美化图形。改进后的代码可以多很多,如下:plt.figure(figsize=(12,8))#新建一个画布,大小为12*8colors=[]#在df_yc中为i指定bar颜色.iloc[:,1]:ifi>0:colors.append("g")#超过平均值的值为绿色else:colors.append("r")#低于平均值的值为red#绘制水平条形图,设置条形透明度为0.5,降低颜色饱和度,看起来更舒服plt.barh(y=df_yc.iloc[:,0],width=df_yc.iloc[:,1],height=0.3,color=colors,alpha=0.5)pos=[]#在df_yc.iloc[:,1]:ifi>0:pos.指定为i添加的文字的x轴位置。append(i+0.5)#如果该值高于平均值,则文本在x轴上的位置超过距离条形顶部0.5的距离else:pos.append(i-0.5)#如果value低于均值,则文本在x轴上的位置距离bar顶部的距离小于0.5foriinrange(len(df_yc)):#添加一个labelvalue如果pos[i]>0,e通过循环到达每个柱:#plt.text(x轴位置,y轴位置,添加的文本信息)plt.text(x=pos[i]+0.5,y=i,s=round(df_yc.iloc[:,1].iloc[i],2))否则:plt.text(x=pos[i]-2,y=i,s=round(df_yc.iloc[:,1].iloc[i],2))plt.title("2019英超球队积分榜(平均分30.25)")plt.grid(linestyle='--',alpha=0.5);#配置网格线渲染:是不是好看很多?事实上,画布的大小是为了让整个画面看起来不那么局促;然后控制bar的上下宽度,加上标签,方便查看每条bar的数据,加上网格线,看起来高大上很多。这张图清楚地表明,英超各队积分不齐。没有越过平均线的球队数量几乎是平均线球队数量的两倍。这也说明好球队特别好,平均分提高了,有很多糟糕的球队,但水平并不算太差;总的来说,好的球队更好,最好的球队比平均水平高出30分,最差的球队只比平均水平低16分。(本人完全不懂足球,只从2019年的数据中得到了一点点分析结果,之所以选择英超数据,纯粹是因为体育数据更容易获取,所以如果分析不好,请拍拍它。)