小提琴图由两个核密度估计曲线拼接而成,如图5-15所示;经常叠加箱形图,如图5-16所示。因为图形外观上像小提琴,取名为小提琴图。小提琴图的功能与箱形图的类似,都可以显示数据的分布特征。不同的是,箱形图用多个统计量进行描述,小提琴图则用连续的概率密度进行描述。[大谦Excel,dqexcel点com]
小提琴图样式1
最简单的小提琴样式直接用两个核密度估计曲线拼接而成,如图5-15所示。4.2节详细介绍了核密度估计曲线图,以及在Excel中如何绘制该图表,请参阅。
图5-15 小提琴图样式1
4.2节介绍了核密度估计曲线图的绘制,将曲线图立起来,并且与它关于基线的镜像曲线拼接,就得到简单的小提琴图。
用draw_violin函数绘制给定数据的小提琴图,需要指定所属Chart对象、绘图数据、数据个数、横坐标、颜色分量和y轴取值范围。完整代码见:Samples->ch08 统计图表->13 小提琴图->py.py。
code.python
def draw_violin(cht,y,n,x,r,g,b,miny,maxy):
kdey=[0 for _ in range(180)]
kdef=[0 for _ in range(180)]
kdef2=[0 for _ in range(180)]
kdep=[[0 for _ in range(2)] for _ in range(182)]
kdep2=[[0 for _ in range(2)] for _ in range(182)]
step=(maxy-miny)/180
for i in range(180):
kdey[i]=miny+(i+1)*step
kdef[i]=x+kde(y,kdey[i],0.5)
kdef2[i]=x-kde(y,kdey[i],0.5)
#核密度估计曲线图
for i in range(1,181):
kdep[i][0]=shape_x(cht,kdef[180-i])
kdep[i][1]=shape_y(cht,kdey[180-i])
kdep[181][0]=shape_x(cht,x)
kdep[181][1]=kdep[180][1]
kdep[0][0]=shape_x(cht,x)
kdep[0][1]=kdep[1][1]
shp=cht.Shapes.AddPolyline(kdep)
shp.Fill.ForeColor.RGB=xw.utils.rgb_to_int((r,g,b))
shp.Fill.Transparency=0.8
shp.Line.ForeColor.RGB=xw.utils.rgb_to_int((r,g,b))
shp.Line.Weight=1
#另一半核密度估计曲线图
for i in range(1,181):
kdep2[i][0]=shape_x(cht,kdef2[180-i])
kdep2[i][1]=shape_y(cht,kdey[180-i])
kdep2[181][0]=shape_x(cht,x)
kdep2[181][1]=kdep2[180][1]
kdep2[0][0]=shape_x(cht,x)
kdep2[0][1]=kdep2[1][1]
shp2=cht.Shapes.AddPolyline(kdep2)
shp2.Fill.ForeColor.RGB=xw.utils.rgb_to_int((r,g,b))
shp2.Fill.Transparency=0.8
shp2.Line.ForeColor.RGB=xw.utils.rgb_to_int((r,g,b))
shp2.Line.Weight=1
调用draw_violin函数绘小提琴图。
code.python
root=os.getcwd() #获取当前工作路径
app=xw.App(visible=True,add_book=False) #创建Excel应用
wb=app.books.open(root+r'/data.xlsx',read_only=False) #打开数据文件返回工作簿对象
sht=wb.sheets('Sheet1') #获取指定工作表对象
data=sht.range('A1:B180').value #获取数据
app.kill() #退出应用
#从comtypes包中导入CreateObject函数
from comtypes.client import CreateObject
app2=CreateObject("Excel.Application") #创建Excel应用
app2.Visible=True #应用窗口可见
app2.ScreenUpdating=False
wb2=app2.Workbooks.Open(root+r'/data.xlsx') #添加工作簿
sht2=wb2.Sheets('Sheet1') #获取第1个工作表
shp=sht2.Shapes.AddChart2() #创建空白图表
shp.Left=20
cht=shp.Chart #获取图表
cht.ChartType=-4169 #散点图
ax1=cht.Axes(1) #获取横轴
ax2=cht.Axes(2) #获取纵轴
ax1.MinimumScale=0 #横轴最小值
ax1.MaximumScale=7
ax2.MinimumScale=-4
ax2.MaximumScale=4
ax1.CrossesAt=ax1.MinimumScale
ax2.CrossesAt=ax2.MinimumScale
set_style(cht) #设置样式
cht.SeriesCollection().NewSeries() #新建序列
count1=0
count2=0
count3=0
count4=0
count5=0
count6=0
d1=[]
d2=[]
d3=[]
d4=[]
d5=[]
d6=[]
#筛选数据
for i in range(180):
if data[i][1]==1:
count1+=1
d1.append(data[i][0])
elif data[i][1]== 2:
count2+=1
d2.append(data[i][0])
elif data[i][1]== 3:
count3+=1
d3.append(data[i][0])
elif data[i][1]== 4:
count4+=1
d4.append(data[i][0])
elif data[i][1]== 5:
count5+=1
d5.append(data[i][0])
elif data[i][1]== 6:
count6+=1
d6.append(data[i][0])
#创建小提琴图
draw_violin(cht,d1,count1,1,0,0,255,-4,4)
draw_violin(cht,d2,count2,2,0,0,255,-4,4)
draw_violin(cht,d3,count3,3,0,0,255,-4,4)
draw_violin(cht,d4,count4,4,0,0,255,-4,4)
draw_violin(cht,d5,count5,5,0,0,255,-4,4)
draw_violin(cht,d6,count6,6,0,0,255,-4,4)
小提琴图样式2
图5-16所示的小提琴图更加常见。该样式的小提琴图在简单小提琴图的基础上叠加了箱形图,从图中不仅能探查任意处数据分布的概率密度,还可以通过箱形图查看数据的分散程度和偏态特征,以及是否有异常值等关键信息。
图5-16 小提琴图样式2
用draw_violin函数绘制简单小提琴图,用draw_boxplot函数叠加绘制箱形图。调用这两个函数绘制小提琴图。完整代码见:Samples->ch08 统计图表->14 小提琴图2->py.py。
code.python
#... 省略部分代码
#绘制小提琴图
draw_violin(cht,d1,count1,1,0,0,255,-4,4)
draw_violin(cht,d2,count2,2,0,0,255,-4,4)
draw_violin(cht,d3,count3,3,0,0,255,-4,4)
draw_violin(cht,d4,count4,4,0,0,255,-4,4)
draw_violin(cht,d5,count5,5,0,0,255,-4,4)
draw_violin(cht,d6,count6,6,0,0,255,-4,4)
#绘制箱形图
draw_boxplot(app2,cht,d1,count1,1,0,0,255,0.1,False)
draw_boxplot(app2,cht,d2,count2,2,0,0,255,0.1,False)
draw_boxplot(app2,cht,d3,count3,3,0,0,255,0.1,False)
draw_boxplot(app2,cht,d4,count4,4,0,0,255,0.1,False)
draw_boxplot(app2,cht,d5,count5,5,0,0,255,0.1,False)
draw_boxplot(app2,cht,d6,count6,6,0,0,255,0.1,False)
#... 省略部分代码
运行代码生成类似图5-16的小提琴图。