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

太喜欢了~,用Python做子弹图真是太简单了

时间:2023-03-25 22:41:41 Python

大家好,我是陈诚~众所周知,Python应用广泛。今天我们就来学习如何通过matplotlib库制作漂亮的子弹图。1.什么是子弹图?高度、位置和颜色编码数据以显示与目标和绩效区间相比的现实情况让我们首先看看子弹图可能是什么样子子弹图有一个主要指标(例如,当前年初至今的收入),比较将指标与一个或多个其他指标联系起来以丰富其含义(例如,与目标相比),并将其显示在性能的定性范围的上下文中,例如差、满意和好。定性范围显示为单一色调的不同强度,允许色盲人士辨别它们并将仪表板上的颜色使用保持在最低限度。嗯,差不多就是子弹图的应用场景和绘制标准了。让我们开始制作它们2.构建图表的思路大致是可以用一个堆积条形图来表示各种范围,用另一个更小的条形图来表示数值。最后,用垂直线标记目标。可以看出我们需要多一个组件层,用matplotlib来实现更方便importmatplotlib.pyplotaspltimportseabornassnsfrommatplotlib.tickerimportFuncFormatter%matplotlibinline这里我们也导入Seaborn,因为Seaborn有一些非常好用的工具来管理调色板,利用此功能比尝试以其他方式复制它更容易。我们需要生成调色板的主要原因是我们很可能希望为各种定性范围生成视觉上吸引人的配色方案。在下面的示例中,我们可以使用palplot便利函数来显示5种绿色色调的调色板sns.palplot(sns.light_palette("green",5))sns.palplot(sns.light_palette("purple",8,reverse=True))以相反的顺序制作8种不同深浅的紫色现在我们知道如何设置我们的调色板,让我们根据上面列出的原则使用Matplotlib创建一个简单的子弹图首先,定义我们想要的值toplotlimits=[80,100,150]data_to_plot=("Example1",105,120)这将创建3个范围:0-80、81-100、101-150和值为105的“示例”行和目标行为120接下来,构建一个蓝色调色板:palette=sns.color_palette("Blues_r",len(limits))接下来是构建范围堆叠条形图:fig,ax=plt.subplots()ax.set_aspect('equal')ax.set_yticks([1])ax.set_yticklabels([data_to_plot[0]])prev_limit=0foridx,liminenumerate(limits):ax.barh([1],lim-prev_limit,left=prev_limit,height=15,color=palette[idx])prev_limit=lim我们可以再添加一个更小的bar来代表105值:ax.barh([1],data_to_plot[1],color='black',height=5)已经成型。最后一步是使用axvline添加目标标记:ax.axvline(data_to_plot[2],color="gray",ymin=0.10,ymax=0.9)我已经完成了上面子弹图的简单制作,但是所有我们的测试值是硬编码的,所以我们写一个可以填任意值的代码3.最终代码defbulletgraph(data=None,limits=None,labels=None,axis_label=None,title=None,size=(5,3),palette=None,formatter=None,target_color="gray",bar_color="black",label_color="gray"):#确定调整条高度的最大值#除以10似乎工作得很好h=limits[-1]/10#使用green调色板作为一个明智的默认值如果调色板为无:调色板=sns.light_palette("green",len(limits),reverse=False)#必须能够通过多个子图处理一个或多个数据集iflen(data)==1:fig,ax=plt.subplots(figsize=size,sharex=True)else:fig,axarr=plt.subplots(len(data),figsize=size,sharex=True)#将每个子弹图条添加到subplotforidx,iteminenumerate(data):#从创建绘图时返回的坐标轴数组中获取坐标轴iflen(data)>1:ax=axarr[idx]######.set_aspect('equal')ax.set_yticklabels([item[0]])ax.set_yticks([1])ax.spines['bottom'].set_visible(False)ax.spines['top'].set_visible(假)ax.spines['right'].set_visible(False)ax.spines['left'].set_visible(False)prev_limit=0foridx2,liminenumerate(lim它的):#绘制barax.barh([1],lim-prev_limit,left=prev_limit,height=h,color=palette[idx2])我们正在测量的值#绘制我们正在测量的值ax.barh([1],item[1],height=(h/3),color=bar_color)#需要ymin和max以确保目标标记#适合ymin,ymax=ax.get_ylim()ax.vlines(item[2],ymin*.9,ymax*.9,linewidth=1.5,color=target_color)#现在制作一些标签如果无:对于rect,在zip中标记(rects,labels):height=rect.get.get_height()ax.text(rect.get_x()+rect.get.get_width()/2,-height*.4,label,label,ha='center',va='bottom',color=label_color)如果格式化程序:ax.xaxis.set_major_formatter(formatter)ifaxis_label:ax.set_xlabel(axis_label)iftitle:fig.suptitle(title,fontsize=14)fig.subplots_adjust(hspace=0)虽然代码看起来有点长,但实际上是上面的叠加脚步。比较简单,就不重复解释了。直接调用看看效果data_to_plot2=[("张三",105,120),("李四",99,110),("王舞",109,125),("赵六",135,123),("千玺",45,105)]bulletgraph(data_to_plot2,limits=[20,60,100,160],"OKor"Polabels"=[","Good","Excellent"],size=(8,5),axis_label="PerformanceMeasure",label_color="black",bar_color="#252525",target_color='#f7f7f7',title="Salesrepresentsperformance")我们还可以做一些优化,格式化x轴以更一致地显示信息在下面的示例中,我们可以衡量一家假设公司的营销预算的绩效defmoney(x,pos):'这两个参数是价值和报价位置'return"${:,.0f}".format(x)money_fmt=FuncFormatter(money)data_to_plot3=[("HR",50000,60000),("Marketing",75000,650("Sales",125000,80000),("R&D",195000,115000)]palette=sns.light_palette("grey",3,reverse=False)bulletgraph(data_to_plot3,limits=[50000,125000,"Belabslow=[200000],,"OnTarget","Above"],size=(10,5),axis_label="年度预算",label_color="black",bar_color="#252525",target_color='#f7f7f7',palette=调色板,title="营销渠道预算绩效",formatter=money_fmt)看来效果不错,怎么样,一起来吧!喜欢的话点个赞关注我吧~