均值比较

本节介绍假设检验和方差分析中可能遇到的数据可视化方法。假设检验讨论单个总体和两个总体的均值比较问题,方差分析则讨论多个总体的均值比较问题。如果样本数据满足参数分析的要求,如满足正态性、方差齐性等要求,使用参数分析方法;如果不满足,可使用非参数的方法。[大谦Excel,dqexcel点com]

配对图

配对图如图5-26所示,可以有不同的样式。图中很多直线段,它们是两个样本中配对数据点相连得到的。使用配对图可以用图形直观地表现两个样本数据个别数据之间和总体数据之间的差异情况。

Document Image

图5-26 配对图

用Python xlwings自己绘制配对图,首先通过筛选得到两个分组的数据,然后绘制两组数据中配对点的连线,最后绘制左侧和右侧的散点。完整代码见:Samples->ch08 统计图表->24 配对图->py.py。

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')    #获取指定工作表对象
shp=sht.api.Shapes.AddChart2()    #创建空白图表
shp.Left=20
cht=shp.Chart    #获取图表
cht.ChartType=xw.constants.ChartType.xlXYScatter    #图表类型为散点图
ax1=cht.Axes(1)    #获取横轴
ax2=cht.Axes(2)    #获取纵轴
ax1.MinimumScale=0    #横轴最小值
ax1.MaximumScale=3
ax2.MinimumScale=0    #纵轴最小值
ax2.MaximumScale=0.35
set_style(cht)    #设置样式
cht.SeriesCollection().NewSeries()    #新建序列
data=sht.range('A2:B21').value    #获取数据
count1=0
count2=0
d1=[]
d2=[]
#筛选数据
for i in range(20):
    if data[i][1]==1:
        count1+=1
        d1.append(data[i][0])
    elif data[i][1]== 2:
        count2+=1
        d2.append(data[i][0])
#绘制配对连线
for i in range(10):
    bx=shape_x(cht,1)
    ex=shape_x(cht,2)
    by=shape_y(cht,d1[i])
    ey=shape_y(cht,d2[i])
    shp=cht.Shapes.AddLine(bx,by,ex,ey)
    shp.Line.Weight=1
    shp.Line.ForeColor.RGB=xw.utils.rgb_to_int((180,180,180))
#绘制左侧散点
for i in range(10):
    bx=shape_x(cht,1)
    by=shape_y(cht,d1[i])
    ex=cht.PlotArea.InsideWidth/(cht.Axes(1).MaximumScale-\
    cht.Axes(1).MinimumScale)*0.02
    ey=ex
    shp2=cht.Shapes.AddShape(9,bx,by,ex,ey)
#绘制右侧散点
for i in range(10):
    bx=shape_x(cht,2)
    by=shape_y(cht,d2[i])
    ex=cht.PlotArea.InsideWidth/(cht.Axes(1).MaximumScale-\
    cht.Axes(1).MinimumScale)*0.02
    ey=ex
    shp3=cht.Shapes.AddShape(1,bx,by,ex,ey)
    shp3.Fill.ForeColor.RGB=xw.utils.rgb_to_int((255,128,0))
    shp3.Line.ForeColor.RGB=xw.utils.rgb_to_int((255,128,0))

运行代码生成类似图5-26的配对图。

箱形图叠加配对图

进行两个总体的均值比较时,常常绘制两个样本数据的箱形图表现两组数据的整体差异。在箱形图上可以叠加绘制配对图,表现各配对数据的变化。

Document Image

图5-27 箱形图叠加配对图

用Python xlwings自己绘制箱形图并叠加绘制配对图,首先通过筛选得到两个分组的数据,然后绘制两组数据中配对点的连线,最后绘制两组数据的箱形图。完整代码见:Samples->ch08 统计图表->25 箱形图叠加配对图->py.py。

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')    #获取指定工作表对象
shp=sht.api.Shapes.AddChart2()    #创建空白图表
shp.Left=20
cht=shp.Chart    #获取图表
cht.ChartType=xw.constants.ChartType.xlXYScatter    #图表类型为散点图
ax1=cht.Axes(1)    #获取横轴
ax2=cht.Axes(2)    #获取纵轴
ax1.MinimumScale=0    #横轴最小值
ax1.MaximumScale=3
ax2.MinimumScale=0    #纵轴最小值
ax2.MaximumScale=0.35
ax1.CrossesAt=ax1.MinimumScale
ax2.CrossesAt=ax2.MinimumScale
set_style(cht)    #设置样式
cht.SeriesCollection().NewSeries()    #新建序列
data=sht.range('A2:B21').value    #获取数据
count1=0
count2=0
d1=[]
d2=[]
#筛选数据
for i in range(20):
    if data[i][1]==1:
        count1+=1
        d1.append(data[i][0])
    elif data[i][1]== 2:
        count2+=1
        d2.append(data[i][0])
#绘配对图
for i in range(10):
    bx=shape_x(cht,1)
    ex=shape_x(cht,2)
    by=shape_y(cht,d1[i])
    ey=shape_y(cht,d2[i])
    shp=cht.Shapes.AddLine(bx,by,ex,ey)
    shp.Line.Weight=1
    shp.Line.ForeColor.RGB=xw.utils.rgb_to_int((180,180,180))
#创建箱形图
draw_boxplot(app,cht,d1,count1,1,0,0,255,0.5,False)
draw_boxplot(app,cht,d2,count2,2,255,128,0,0.5,False)

运行代码生成类似图5-27的效果。

误差柱状图叠加配对图

误差柱状图叠加配对图的效果如图5-28所示,用误差柱状图表现两组数据之间总的差异,用配对图表现各配对数据个体之间的差异。

Document Image

图5-28 误差柱状图叠加配对图

绘制误差柱状图叠加配对图的完整代码见:Samples->ch08 统计图表->26 误差柱状图叠加配对图->py.py。

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')    #获取指定工作表对象
shp=sht.api.Shapes.AddChart2()    #创建空白图表
shp.Left=20
cht=shp.Chart    #获取图表
cht.ChartType=xw.constants.ChartType.xlXYScatter    #图表类型为散点图
ax1=cht.Axes(1)    #获取横轴
ax2=cht.Axes(2)    #获取纵轴
ax1.MinimumScale=0    #横轴最小值
ax1.MaximumScale=3
ax2.MinimumScale=0    #纵轴最小值
ax2.MaximumScale=0.35
set_style(cht)    #设置样式
cht.SeriesCollection().NewSeries()    #新建序列
data=sht.range('A2:B21').value    #获取数据
count1=0
count2=0
d1=[]
d2=[]
#筛选数据
for i in range(20):
    if data[i][1]==1:
        count1+=1
        d1.append(data[i][0])
    elif data[i][1]== 2:
        count2+=1
        d2.append(data[i][0])
mean1=app.api.WorksheetFunction.Average(d1)    #求分组数据的均值
mean2=app.api.WorksheetFunction.Average(d2)
#自己绘制柱状图
std1=app.api.WorksheetFunction.StDev(d1)
std2=app.api.WorksheetFunction.StDev(d2)
draw_bar(cht,mean1,1,0,0,255,0.5,False)
draw_bar(cht,mean2,2,255,128,0,0.5,False)
draw_error(cht,mean1,std1,std1,1,0,0,255)
draw_error(cht,mean2,std2,std2,2,255,128,0)
#绘配对图
for i in range(10):
    bx=shape_x(cht,1)
    ex=shape_x(cht,2)
    by=shape_y(cht,d1[i])
    ey=shape_y(cht,d2[i])
    shp=cht.Shapes.AddLine(bx,by,ex,ey)
    shp.Line.Weight=1
    shp.Line.ForeColor.RGB=xw.utils.rgb_to_int((180,180,180))

运行代码生成类似图5-28的效果。

误差柱状图标注检验显著性

进行假设检验或方差分析时,常绘制前面介绍的误差柱状图、散点柱状图和箱形图等比较各组数据,此时常常将均值比较的结果,包括假设检验的结果和方差分析多重比较的结果显示在图上。一般用“*”表示在5%的水平上显著,用“**”表示在1%的水平上显著。

编程实现时,先按前面介绍的方法绘制误差柱状图,然后添加标注线和表示检验显著性的文本。完整代码见:Samples->ch08 统计图表->27 误差柱状图标注检验显著性->py.py。

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')    #获取指定工作表对象
shp=sht.api.Shapes.AddChart2()    #创建空白图表
shp.Left=20
cht=shp.Chart    #获取图表
cht.ChartType=xw.constants.ChartType.xlXYScatter    #图表类型为散点图
ax1=cht.Axes(1)    #获取横轴
ax2=cht.Axes(2)    #获取纵轴
ax1.MinimumScale=0    #横轴最小值
ax1.MaximumScale=3
ax2.MinimumScale=0    #纵轴最小值
ax2.MaximumScale=0.4
set_style(cht)    #设置样式
cht.SeriesCollection().NewSeries()    #新建序列
data=sht.range('A2:B21').value    #获取数据
count1=0
count2=0
d1=[]
d2=[]
#筛选数据
for i in range(20):
    if data[i][1]==1:
        count1+=1
        d1.append(data[i][0])
    elif data[i][1]== 2:
        count2+=1
        d2.append(data[i][0])
mean1=app.api.WorksheetFunction.Average(d1)    #求均值
mean2=app.api.WorksheetFunction.Average(d2)
#自己绘制柱状图
std1=app.api.WorksheetFunction.StDev(d1)
std2=app.api.WorksheetFunction.StDev(d2)
draw_bar(cht,mean1,1,0,0,255,0.5,False)
draw_bar(cht,mean2,2,255,128,0,0.5,False)
draw_error(cht,mean1,std1,std1,1,0,0,255)
draw_error(cht,mean2,std2,std2,2,255,128,0)
#添加标注
bx=shape_x(cht,1)
ex=shape_x(cht,2)
by=shape_y(cht,0.35)
ey=shape_y(cht,0.35)
shp2=cht.Shapes.AddLine(bx,by,ex,ey)    #添加直线段
shp2.Line.Weight=1
shp2.Line.ForeColor.RGB=xw.utils.rgb_to_int((100,100,100))
bx=shape_x(cht,1)
ex=shape_x(cht,1)
by=shape_y(cht,0.35)
ey=shape_y(cht,0.27)
shp3=cht.Shapes.AddLine(bx,by,ex,ey)    #添加直线段
shp3.Line.Weight=1
shp3.Line.ForeColor.RGB=xw.utils.rgb_to_int((100,100,100))
bx=shape_x(cht,2)
ex=shape_x(cht,2)
by=shape_y(cht,0.35)
ey=shape_y(cht,0.32)
shp4=cht.Shapes.AddLine(bx,by,ex,ey)    #添加直线段
shp4.Line.Weight=1
shp4.Line.ForeColor.RGB=xw.utils.rgb_to_int((100,100,100))
bx=shape_x(cht,1.4)
by=shape_y(cht,0.39)
ex=cht.PlotArea.InsideWidth/(cht.Axes(1).MaximumScale-cht.Axes(1).MinimumScale)*1
ey=cht.PlotArea.InsideHeight/(cht.Axes(2).MaximumScale-cht.Axes(2).MinimumScale)*0.03
shp5=cht.Shapes.AddLabel(1,bx,by,ex,ey)    #添加显著性标注
shp5.TextFrame2.TextRange.Characters.Text='**'
shp5.TextFrame2.TextRange.Characters.Font.Size=10

运行代码生成图5-29。

Document Image

图5-29 误差柱状图添加检验显著性标注