小提琴图

小提琴图由两个核密度估计曲线拼接而成,如图5-15所示;经常叠加箱形图,如图5-16所示。因为图形外观上像小提琴,取名为小提琴图。小提琴图的功能与箱形图的类似,都可以显示数据的分布特征。不同的是,箱形图用多个统计量进行描述,小提琴图则用连续的概率密度进行描述。[大谦Excel,dqexcel点com]

小提琴图样式1

最简单的小提琴样式直接用两个核密度估计曲线拼接而成,如图5-15所示。4.2节详细介绍了核密度估计曲线图,以及在Excel中如何绘制该图表,请参阅。

Document Image

图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所示的小提琴图更加常见。该样式的小提琴图在简单小提琴图的基础上叠加了箱形图,从图中不仅能探查任意处数据分布的概率密度,还可以通过箱形图查看数据的分散程度和偏态特征,以及是否有异常值等关键信息。

Document Image

图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的小提琴图。