Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图

文章目录

  • 前言
  • 一、Matplotlib绘制箱线图介绍
    • 1. plt.boxplot()参数详解
      • 1.1、x:指定要绘制箱线图的数据
        • 1.1.1、代码如下(示例):
        • 1.1.2、输出结果如下:
      • 1.2、notch:是否以凹口的形式展现箱线图
        • 1.2.1、代码如下(示例):
        • 1.2.2、输出结果如下:
      • 1.3、sym:指定异常点的形状
        • 1.3.1、代码如下(示例):
        • 1.3.2、输出结果如下:
      • 1.4、vert:是否需要将箱线图垂直摆放,True:垂直,False:水平;默认垂直摆放
        • 1.4.1、代码如下(示例):
        • 1.4.2、输出结果如下:
      • 1.5、whis:指定上下须与上下四分位的距离,默认为1.5倍的四分位差
        • 1.5.1、代码如下(默认情况示例):
        • 1.5.2、输出结果如下:
        • 1.5.3、代码如下(指定whis=3时的示例):
        • 1.5.4、输出结果如下:
      • 1.6、positions:指定箱线图的位置,默认为[0,1,2…]
        • 1.6.1、代码如下(默认情况示例):
        • 1.6.2、输出结果如下:
        • 1.6.3、代码如下(positions=[4]时的示例):
        • 1.6.4、输出结果如下:
      • 1.7、widths=None:指定箱线图的宽度
        • 1.7.1、代码如下(widths=0.5时示例):
        • 1.7.2、输出结果如下:
        • 1.7.3、代码如下(widths=1时示例):
        • 1.7.4、输出结果如下:
      • 1.8、patch_artist:是否填充箱体的颜色,True:填充,False:不填充;默认False
        • 1.8.1、代码如下(patch_artist=True时示例):
        • 1.8.2、输出结果如下:
        • 1.8.1、代码如下(patch_artist=False时示例):
        • 1.8.2、输出结果如下:
      • 1.9、showmeans:是否显示均值,默认不显示
        • 1.9.1、代码如下(showmeans=True时示例):
        • 1.9.2、输出结果如下:
        • 1.9.3、代码如下(showmeans=False时示例):
        • 1.9.4、输出结果如下:
      • 1.10、meanline:是否用线的形式表示均值,默认用点来表示
        • 1.10.1、代码如下(meanline=True时示例):
        • 1.10.2、输出结果如下:
        • 1.10.3、代码如下(meanline=False时示例):
        • 1.10.4、输出结果如下:
      • 1.11、showcaps:是否显示箱线图顶端和末端的两条线,默认显示
        • 1.11.1、代码如下(showcaps=True时示例):
        • 1.11.2、输出结果如下:
        • 1.11.3、代码如下(showcaps=False时示例):
        • 1.11.4、输出结果如下:
      • 1.12、showbox:是否显示箱线图的箱体,默认显示
        • 1.12.1、代码如下(showbox=False时示例):
        • 1.12.2、输出结果如下:
      • 1.13、showfliers:是否显示异常值,默认显示
        • 1.13.1、代码如下(showfliers=False时示例):
        • 1.13.2、输出结果如下:
      • 1.14、labels:为箱线图添加标签,类似于图例的作用
        • 1.14.1、代码如下(示例):
        • 1.14.2、输出结果如下:
      • 1.15、boxprops:设置箱体的属性,如边框色,填充色等
        • 1.15.1-1、color 边框颜色
        • 1.15.1-2、输出结果如下:
        • 1.15.2-1、facecolor 箱体填充颜色(patch_artist必须为True)
        • 1.15.2-2、输出结果如下:
      • 1.16、filerprops:设置异常值的属性
        • 1.16.1、代码如下(示例):
        • 1.16.2、输出结果如下:
      • 1.17、medianprops:设置中位数的属性,如线的类型、粗细等
        • 1.17.1、代码如下(示例):
        • 1.17.2、输出结果如下:
      • 1.18、meanprops:设置均值的属性,如点的大小、颜色等(注:showmeans必须设置为True,不然均值不显示)
        • 1.18.1、代码如下(示例):
        • 1.18.2、输出结果如下:
        • 1.18.3、代码如下(示例):
        • 1.18.4、输出结果如下:
        • 1.18.5、代码如下(示例):
        • 1.18.6、输出结果如下:
      • 1.19、capprops:设置箱线图顶端和末端线条的属性,如颜色、粗细等
        • 1.19.1、代码如下(示例):
        • 1.19.2、输出结果如下:
      • 1.20、whiskerprops:设置须的属性,如颜色、粗细、线的类型等
        • 1.20.1、代码如下(示例):
        • 1.20.2、输出结果如下:
    • 2. 在箱线图上叠加散点图时图层参数设置(zorder)
    • 3. 回答往期文章《Python Matplotlib数据可视化绘图之(二)————箱线图》中的总结中所提的问题,文章网址链接为:https://blog.csdn.net/Mr_Dragon66/article/details/127814202?spm=1001.2014.3001.5501
      • 3.1、为什么我不直接在ax.boxplot()函数中直接用labels这个参数生成legend,反而要利用ax.scatter()函数中的label参数生成legend?
        • 3.1.1、首先我演示一下在ax.boxplot()函数中直接用labels这个参数,看是否能够生成legend
          • 3.1.1-1、代码如下(数据来自往期文章):
          • 3.1.1-2、输出结果如下:
          • 3.1.1-3、代码如下(数据来自往期文章):
          • 3.1.1-4、输出结果如下:
      • 3.2、还有什么方法能够生成箱线图的图例?
      • 3.3、箱线图的图例生成方法和柱状图、折线图、饼图、直方图、散点图等图的图例生成方法有什么不同之处或特别之处?
        • 3.3.1、方式一:既生成图例又在扇形旁显示标签
          • 3.3.1-1、代码如下:
          • 3.3.1-2、输出结果如下:
        • 3.3.2、方式二:只生成图例,且不在扇形旁显示标签
          • 3.3.2-1、代码如下:
          • 3.3.2-2、输出结果如下:
        • 3.3.3、方式三:只在扇形旁显示标签,且不生成图例
          • 3.3.3-1、代码如下:
          • 3.3.3-2、输出结果如下:
        • 3.3.4、方式四:只在扇形旁显示标签,且不生成图例,如果不想把扇形做分离,可以去掉explode参数
          • 3.3.4-1、代码如下:
          • 3.3.4-2、输出结果如下:
  • 二、多种颜色的普通分组箱线图和散点图的叠加图
    • 1.示例数据如下
    • 2.代码如下
      • 2.1 代码如下(示例):
        • 2.1.1 Case1:
  • 三、总结


前言

本文我们主要介绍利用Python中的Matplotlib模块进行箱线图的画法介绍,以及箱线图和散点图的叠加图的画法介绍,包括整张图片只有一种颜色的不分组箱线图和散点图的叠加图、整张图片有好几种颜色的不分组箱线图和散点图的叠加图、整张图片有好几种颜色的分组箱线图和散点图的叠加图等。


一、Matplotlib绘制箱线图介绍

1. plt.boxplot()参数详解

Python绘制箱线图主要用matplotlib库里的pyplot模块里的boxplot()函数。
plt.boxplot(x, # 指定要绘制箱线图的数据;
notch=None, # 是否是凹口的形式展现箱线图,默认非凹口;
sym=None, # 指定异常点的形状,默认为+号显示;
vert=None, # 是否需要将箱线图垂直摆放,默认垂直摆放;
whis=None, # 指定上下须与上下四分位的距离,默认为1.5倍的四分位差;
positions=None, # 指定箱线图的位置,默认为[0, 1, 2…];
widths=None, # 指定箱线图的宽度;
patch_artist=None, # 是否填充箱体的颜色;
bootstrap=None, #
usermedians=None, #
conf_intervals=None, #
meanline=None, # 是否用线的形式表示均值,默认用点来表示;
showmeans=None, # 是否显示均值,默认不显示;
showcaps=None, # 是否显示箱线图顶端和末端的两条线,默认显示;
showbox=None, # 是否显示箱线图的箱体,默认显示;
showfliers=None, # 是否显示异常值,默认显示;
boxprops=None, # 设置箱体的属性,如边框色,填充色等;
labels=None, # 为箱线图添加标签,类似于图例的作用;
flierprops=None, # 设置异常值的属性,如异常点的形状,大小,填充色等;
medianprops=None, # 设置中位数的属性,如线的类型、粗细等;
meanprops=None, # 设置均值的属性,如点的大小、颜色等;
capprops=None, # 设置箱线图顶端和末端线条的属性,如颜色、粗细等;
whiskerprops=None, # 设置须的属性,如颜色、粗细、线的类型等;
manage_xticks=True, #
autorange=False, #
zorder=None, #
hold=None, #
data=None) #


1.1、x:指定要绘制箱线图的数据

示例:x=[80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]

1.1.1、代码如下(示例):

import matplotlib.pyplot as plt
x = [80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]
plt.boxplot(x)
plt.show()

1.1.2、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第1张图片


1.2、notch:是否以凹口的形式展现箱线图

示例:x=[80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]

1.2.1、代码如下(示例):

import matplotlib.pyplot as plt
x = [80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]
plt.boxplot(x, notch=True)
plt.show()

1.2.2、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第2张图片


1.3、sym:指定异常点的形状

示例:x=[80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]

1.3.1、代码如下(示例):

import matplotlib.pyplot as plt
x = [80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]
plt.boxplot(x, sym='*')
plt.show()

1.3.2、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第3张图片


1.4、vert:是否需要将箱线图垂直摆放,True:垂直,False:水平;默认垂直摆放

示例:x=[80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]

1.4.1、代码如下(示例):

import matplotlib.pyplot as plt
x = [80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]
plt.boxplot(x, vert=False)
plt.show()

1.4.2、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第4张图片


1.5、whis:指定上下须与上下四分位的距离,默认为1.5倍的四分位差

示例:x=[80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]

1.5.1、代码如下(默认情况示例):

import matplotlib.pyplot as plt
x = [80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]
plt.boxplot(x)
plt.show()

1.5.2、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第5张图片

1.5.3、代码如下(指定whis=3时的示例):

import matplotlib.pyplot as plt
x = [80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]
plt.boxplot(x, whis=3)
plt.show()

1.5.4、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第6张图片


1.6、positions:指定箱线图的位置,默认为[0,1,2…]

示例:x=[80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]

1.6.1、代码如下(默认情况示例):

import matplotlib.pyplot as plt
x = [80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]
plt.boxplot(x)
plt.show()

1.6.2、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第7张图片

1.6.3、代码如下(positions=[4]时的示例):

import matplotlib.pyplot as plt
x = [80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]
plt.boxplot(x, positions=[4])
plt.show()

1.6.4、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第8张图片


1.7、widths=None:指定箱线图的宽度

示例:x=[80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]

1.7.1、代码如下(widths=0.5时示例):

import matplotlib.pyplot as plt
x = [80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]
plt.boxplot(x, widths=0.5)
plt.show()

1.7.2、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第9张图片

1.7.3、代码如下(widths=1时示例):

import matplotlib.pyplot as plt
x = [80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]
plt.boxplot(x, widths=1)
plt.show()

1.7.4、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第10张图片


1.8、patch_artist:是否填充箱体的颜色,True:填充,False:不填充;默认False

示例:x=[80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]

1.8.1、代码如下(patch_artist=True时示例):

import matplotlib.pyplot as plt
x = [80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]
plt.boxplot(x, patch_artist=True)
plt.show()

1.8.2、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第11张图片

1.8.1、代码如下(patch_artist=False时示例):

import matplotlib.pyplot as plt
x = [80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]
plt.boxplot(x, patch_artist=False)
plt.show()

1.8.2、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第12张图片


1.9、showmeans:是否显示均值,默认不显示

示例:x=[80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]

1.9.1、代码如下(showmeans=True时示例):

import matplotlib.pyplot as plt
x = [80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]
plt.boxplot(x, showmeans=True)
plt.show()

1.9.2、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第13张图片

1.9.3、代码如下(showmeans=False时示例):

import matplotlib.pyplot as plt
x = [80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]
plt.boxplot(x)
plt.show()

1.9.4、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第14张图片


1.10、meanline:是否用线的形式表示均值,默认用点来表示

示例:x=[80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]

1.10.1、代码如下(meanline=True时示例):

import matplotlib.pyplot as plt
x = [80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]
plt.boxplot(x, showmeans=True, meanline=True)
plt.show()

1.10.2、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第15张图片

1.10.3、代码如下(meanline=False时示例):

import matplotlib.pyplot as plt
x = [80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]
plt.boxplot(x, showmeans=True, meanline=False)
plt.show()

1.10.4、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第16张图片


1.11、showcaps:是否显示箱线图顶端和末端的两条线,默认显示

示例:x=[80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]

1.11.1、代码如下(showcaps=True时示例):

import matplotlib.pyplot as plt
x = [80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]
plt.boxplot(x)
plt.show()

1.11.2、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第17张图片

1.11.3、代码如下(showcaps=False时示例):

import matplotlib.pyplot as plt
x = [80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]
plt.boxplot(x, showcaps=False)
plt.show()

1.11.4、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第18张图片


1.12、showbox:是否显示箱线图的箱体,默认显示

示例:x=[80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]

1.12.1、代码如下(showbox=False时示例):

import matplotlib.pyplot as plt
x = [80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]
plt.boxplot(x, showbox=False)
plt.show()

1.12.2、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第19张图片


1.13、showfliers:是否显示异常值,默认显示

示例:x=[80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]

1.13.1、代码如下(showfliers=False时示例):

import matplotlib.pyplot as plt
x = [80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]
plt.boxplot(x, showfliers=False)
plt.show()

1.13.2、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第20张图片


1.14、labels:为箱线图添加标签,类似于图例的作用

示例:x=[80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]

1.14.1、代码如下(示例):

import matplotlib.pyplot as plt
# 设置字体, 解决中文乱码问题
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
# 解决图像中的'-'负号的乱码问题
plt.rcParams['axes.unicode_minus'] = False
x = [80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]
plt.boxplot(x, labels=['标签'])
plt.show()

1.14.2、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第21张图片


1.15、boxprops:设置箱体的属性,如边框色,填充色等

示例:x=[80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]

1.15.1-1、color 边框颜色

import matplotlib.pyplot as plt
# 设置字体, 解决中文乱码问题
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
# 解决图像中的'-'负号的乱码问题
plt.rcParams['axes.unicode_minus'] = False
x = [80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]
plt.boxplot(x, boxprops={'color': 'red'})
plt.show()

1.15.1-2、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第22张图片

1.15.2-1、facecolor 箱体填充颜色(patch_artist必须为True)

import matplotlib.pyplot as plt
# 设置字体, 解决中文乱码问题
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
# 解决图像中的'-'负号的乱码问题
plt.rcParams['axes.unicode_minus'] = False
x = [80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]
plt.boxplot(x, patch_artist=True, boxprops={'color': 'orangered', 'facecolor': 'pink'})
plt.show()

1.15.2-2、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第23张图片

1.16、filerprops:设置异常值的属性

示例:x=[80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]

1.16.1、代码如下(示例):

import matplotlib.pyplot as plt
# 设置字体, 解决中文乱码问题
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
# 解决图像中的'-'负号的乱码问题
plt.rcParams['axes.unicode_minus'] = False
x = [80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]
plt.boxplot(x, patch_artist=True, flierprops={'marker': 'o', 'markerfacecolor': 'pink'})
plt.show()

1.16.2、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第24张图片

1.17、medianprops:设置中位数的属性,如线的类型、粗细等

示例:x=[80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]

1.17.1、代码如下(示例):

import matplotlib.pyplot as plt
# 设置字体, 解决中文乱码问题
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
# 解决图像中的'-'负号的乱码问题
plt.rcParams['axes.unicode_minus'] = False
x = [80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]
plt.boxplot(x, medianprops={'linestyle': '--', 'linewidth': 3})
plt.show()

1.17.2、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第25张图片

1.18、meanprops:设置均值的属性,如点的大小、颜色等(注:showmeans必须设置为True,不然均值不显示)

示例:x=[80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]

1.18.1、代码如下(示例):

import matplotlib.pyplot as plt
# 设置字体, 解决中文乱码问题
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
# 解决图像中的'-'负号的乱码问题
plt.rcParams['axes.unicode_minus'] = False
x = [80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]
plt.boxplot(x, meanprops={'marker': 'D', 'markerfacecolor': 'white'})
plt.show()

1.18.2、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第26张图片

1.18.3、代码如下(示例):

import matplotlib.pyplot as plt
# 设置字体, 解决中文乱码问题
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
# 解决图像中的'-'负号的乱码问题
plt.rcParams['axes.unicode_minus'] = False
x = [80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]
plt.boxplot(x, showmeans=True, meanprops={'marker': 'D', 'markerfacecolor': 'white'})
plt.show()

1.18.4、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第27张图片

1.18.5、代码如下(示例):

import matplotlib.pyplot as plt
# 设置字体, 解决中文乱码问题
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
# 解决图像中的'-'负号的乱码问题
plt.rcParams['axes.unicode_minus'] = False
x = [80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]
plt.boxplot(x, showmeans=True, meanline=True, meanprops={'marker': 'D', 'markerfacecolor': 'white'})
plt.show()

1.18.6、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第28张图片

1.19、capprops:设置箱线图顶端和末端线条的属性,如颜色、粗细等

示例:x=[80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]

1.19.1、代码如下(示例):

import matplotlib.pyplot as plt
# 设置字体, 解决中文乱码问题
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
# 解决图像中的'-'负号的乱码问题
plt.rcParams['axes.unicode_minus'] = False
x = [80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]
plt.boxplot(x, capprops={'linestyle': '--', 'linewidth': 3, 'color': 'red'})
plt.show()

1.19.2、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第29张图片

1.20、whiskerprops:设置须的属性,如颜色、粗细、线的类型等

示例:x=[80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]

1.20.1、代码如下(示例):

import matplotlib.pyplot as plt
# 设置字体, 解决中文乱码问题
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
# 解决图像中的'-'负号的乱码问题
plt.rcParams['axes.unicode_minus'] = False
x = [80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]
plt.boxplot(x, whiskerprops={'linestyle': '--', 'linewidth': 3, 'color': 'red'})
plt.show()

1.20.2、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第30张图片


2. 在箱线图上叠加散点图时图层参数设置(zorder)

使用 “zorder=2”这样的确定叠加的图层的先后次序,数字越大,越后。因为现在是在箱线图上叠加散点图,所以需要先画箱线图,后画散点图,即画箱线图时zorder=1,画散点图时zorder=2


3. 回答往期文章《Python Matplotlib数据可视化绘图之(二)————箱线图》中的总结中所提的问题,文章网址链接为:https://blog.csdn.net/Mr_Dragon66/article/details/127814202?spm=1001.2014.3001.5501

3.1、为什么我不直接在ax.boxplot()函数中直接用labels这个参数生成legend,反而要利用ax.scatter()函数中的label参数生成legend?

3.1.1、首先我演示一下在ax.boxplot()函数中直接用labels这个参数,看是否能够生成legend

3.1.1-1、代码如下(数据来自往期文章):
import matplotlib.pyplot as plt
import numpy as np

# 设置字体, 解决中文乱码问题
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
# 解决图像中的'-'负号的乱码问题
plt.rcParams['axes.unicode_minus'] = False

ClassA_C = [80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]
ClassA_M = [70, 90, 95, 85, 75, 85, 90, 100, 100, 85, 90, 95, 98, 99, 85, 88, 86, 75, 78, 90]
ClassA_E = [90, 100, 100, 85, 75, 90, 100, 100, 75, 70, 85, 90, 95, 95, 90, 80, 70, 80, 70, 75]

ClassB_C = [60, 70, 80, 65, 75, 80, 73, 75, 85, 90, 95, 65, 70, 75, 80, 85, 95, 85, 80, 70]
ClassB_M = [60, 70, 75, 80, 75, 75, 65, 80, 60, 80, 90, 95, 95, 90, 80, 85, 75, 75, 60, 65]
ClassB_E = [70, 75, 75, 70, 60, 90, 98, 95, 85, 75, 70, 60, 65, 70, 75, 75, 80, 75, 70, 80]

ClassC_C = [60, 80, 100, 100, 100, 100, 90, 95, 95, 95, 85, 95, 95, 95, 95, 80, 95, 90, 90, 90]
ClassC_M = [100, 100, 100, 95, 95, 95, 95, 95, 90, 85, 90, 90, 90, 95, 90, 95, 95, 95, 95, 90]
ClassC_E = [80, 90, 100, 100, 100, 90, 95, 95, 95, 90, 95, 90, 95, 90, 95, 90, 95, 90, 95, 85]

fig = plt.figure(figsize=(8, 6), facecolor='#B0C4DE')
ax = fig.add_subplot(facecolor='white')

# 每个刻度标签下有几个group就有几个箱子
group_dataA = [ClassA_C, ClassA_M, ClassA_E]

boxplot_dataABC_C = [ClassA_C, ClassB_C, ClassC_C]
boxplot_dataABC_M = [ClassA_M, ClassB_M, ClassC_M]
boxplot_dataABC_E = [ClassA_E, ClassB_E, ClassC_E]

# 橙绿蓝
color_list = ['#FF8C00', '#00FF00', '#0000FF']

x_labels = ['甲班', '乙班', '丙班']
legend_labels = ['语文', '数学', '英语']
length = len(x_labels)
x_loc = np.arange(length)

labels = [['语文', '语文', '语文'], ['数学', '数学', '数学'], ['英语', '英语', '英语']]

group_number = len(group_dataA)
total_width = 0.6
box_total_width = total_width * 0.65
interval_total_width = total_width * 0.35
box_width = box_total_width / group_number

###################################################
if group_number == 1:
    interval_width = interval_total_width
else:
    interval_width = interval_total_width / (group_number - 1)

###################################################
if group_number % 2 == 0:
    x1_box = x_loc - (group_number / 2 - 1) * box_width - box_width / 2 - (group_number / 2 - 1) * interval_width - interval_width / 2
else:
    x1_box = x_loc - ((group_number - 1) / 2) * box_width - ((group_number - 1) / 2) * interval_width
x_list_box = [x1_box + box_width * i + interval_width * i for i in range(group_number)]


boxplot_data = [boxplot_dataABC_C, boxplot_dataABC_M, boxplot_dataABC_E]

for i in range(len(boxplot_data)):
    #####################################################################
    # 先画boxplot
    #######################
    # boxplot_data_num用来统计每组数据的长度, 画scatter图时会用到
    boxplot_data_num = []
    for j in boxplot_data[i]:
        boxplot_data_num_tmp = len(j)
        boxplot_data_num.append(boxplot_data_num_tmp)
    #######################
    ax.boxplot(boxplot_data[i], positions=x_list_box[i], widths=box_width, patch_artist=True,
               medianprops={'lw': 1, 'color': color_list[i]},
               boxprops={'facecolor': 'None', 'edgecolor': color_list[i]},
               capprops={'lw': 1, 'color': color_list[i]},
               whiskerprops={'ls': '-', 'lw': 1, 'color': color_list[i]},
               showfliers=False, zorder=1, labels=labels[i])
    # flierprops = {'marker': 'o', 'markerfacecolor': color_list[i], 'markeredgecolor': color_list[i], 'markersize': 8}
    #####################################################################
    # 再画scatter
    # 将每一组箱线图统计的所有点绘制在图上
    # spotx是每一组箱线图所有的点的横坐标
    spotx = []
    for j_spotx, k_spotx in zip(x_list_box[i], boxplot_data_num):
        spotx_tmp = [j_spotx] * k_spotx
        spotx.append(spotx_tmp)
    # print('$$$spotx:', spotx)
    ax.scatter(spotx, boxplot_data[i], c=color_list[i], s=30, zorder=2)
ax.grid(True, ls=':', color='b', alpha=0.3)
plt.title('甲乙丙各班语文/数学/英语成绩Box_chart分析', fontweight='bold')
ax.set_xticks(x_loc)
ax.set_xticklabels(x_labels, rotation=90)
ax.set_ylabel('分数/百分制', fontweight='bold')
################################################################################################################
################################################################################################################
plt.legend(title='学科', loc='center left', bbox_to_anchor=(1.02, 0.5), facecolor='None', edgecolor='#000000',
           frameon=True, ncol=1, markerscale=3, borderaxespad=0, handletextpad=0.1, fontsize='x-large',
           title_fontsize='x-large', labels=legend_labels)
################################################################################################################
################################################################################################################
plt.xticks(weight='bold')
plt.yticks(weight='bold')
fig.tight_layout()
plt.show()
3.1.1-2、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第31张图片

由输出结果可知,并没有像我们预期的那样生成正确的legend。原因是因为我们在画箱线图时,并不是按照Group来画的,即不是按照[甲班语文,甲班数学,甲班英语,乙班语文,乙班数学,乙班英语,丙班语文,丙班数学,丙班英语]的顺序,而是按照[甲班语文,乙班语文,丙班语文,甲班数学,乙班数学,丙班数学,甲班英语,乙班英语,丙班英语]的顺序来画的。
如果我们按照Group来画的,即按照[甲班语文,甲班数学,甲班英语,乙班语文,乙班数学,乙班英语,丙班语文,丙班数学,丙班英语]的顺序来画,请看3.1.1-3和3.1.1-4的内容:

3.1.1-3、代码如下(数据来自往期文章):
import matplotlib.pyplot as plt
import numpy as np

# 设置字体, 解决中文乱码问题
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
# 解决图像中的'-'负号的乱码问题
plt.rcParams['axes.unicode_minus'] = False

ClassA_C = [80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]
ClassA_M = [70, 90, 95, 85, 75, 85, 90, 100, 100, 85, 90, 95, 98, 99, 85, 88, 86, 75, 78, 90]
ClassA_E = [90, 100, 100, 85, 75, 90, 100, 100, 75, 70, 85, 90, 95, 95, 90, 80, 70, 80, 70, 75]

ClassB_C = [60, 70, 80, 65, 75, 80, 73, 75, 85, 90, 95, 65, 70, 75, 80, 85, 95, 85, 80, 70]
ClassB_M = [60, 70, 75, 80, 75, 75, 65, 80, 60, 80, 90, 95, 95, 90, 80, 85, 75, 75, 60, 65]
ClassB_E = [70, 75, 75, 70, 60, 90, 98, 95, 85, 75, 70, 60, 65, 70, 75, 75, 80, 75, 70, 80]

ClassC_C = [60, 80, 100, 100, 100, 100, 90, 95, 95, 95, 85, 95, 95, 95, 95, 80, 95, 90, 90, 90]
ClassC_M = [100, 100, 100, 95, 95, 95, 95, 95, 90, 85, 90, 90, 90, 95, 90, 95, 95, 95, 95, 90]
ClassC_E = [80, 90, 100, 100, 100, 90, 95, 95, 95, 90, 95, 90, 95, 90, 95, 90, 95, 90, 95, 85]

fig = plt.figure(figsize=(8, 6), facecolor='#B0C4DE')
ax = fig.add_subplot(facecolor='white')

# 每个刻度标签下有几个group就有几个箱子
group_dataA = [ClassA_C, ClassA_M, ClassA_E]

boxplot_dataA_CME = [ClassA_C, ClassA_M, ClassA_E]
boxplot_dataB_CME = [ClassB_C, ClassB_M, ClassB_E]
boxplot_dataC_CME = [ClassC_C, ClassC_M, ClassC_E]

boxplot_dataABC_C = [ClassA_C, ClassB_C, ClassC_C]
boxplot_dataABC_M = [ClassA_M, ClassB_M, ClassC_M]
boxplot_dataABC_E = [ClassA_E, ClassB_E, ClassC_E]

# 橙绿蓝
color_list = ['#FF8C00', '#00FF00', '#0000FF']

x_labels = ['甲班', '乙班', '丙班']
legend_labels = ['语文', '数学', '英语']
length = len(x_labels)
x_loc = np.arange(length)

labels = ['语文', '数学', '英语']

group_number = len(group_dataA)
total_width = 0.6
box_total_width = total_width * 0.65
interval_total_width = total_width * 0.35
box_width = box_total_width / group_number

###################################################
if group_number == 1:
    interval_width = interval_total_width
else:
    interval_width = interval_total_width / (group_number - 1)

###################################################
if group_number % 2 == 0:
    x1_box = x_loc - (group_number / 2 - 1) * box_width - box_width / 2 - (group_number / 2 - 1) * interval_width - interval_width / 2
else:
    x1_box = x_loc - ((group_number - 1) / 2) * box_width - ((group_number - 1) / 2) * interval_width
x_list_box = [x1_box + box_width * i + interval_width * i for i in range(group_number)]

x_list_box_new = []

for i in range(len(group_dataA)):
    for j in range(len(group_dataA)):
        x_list_box_new.append(x_list_box[i][j])
x_list_box_new = sorted(x_list_box_new)

x_list_box_final = []
for i in range(len(group_dataA)):
    x_list_box_final.append(x_list_box_new[3 * i:3 * (i + 1)])

bplot1 = plt.boxplot(boxplot_dataA_CME, positions=x_list_box_final[0], widths=box_width,
                     patch_artist=True, showfliers=False, zorder=1, labels=labels)

for patch, color in zip(bplot1['boxes'], color_list):
    patch.set_edgecolor(color)
    patch.set_facecolor('None')

bplot2 = plt.boxplot(boxplot_dataB_CME, positions=x_list_box_final[1], widths=box_width,
                     patch_artist=True, showfliers=False, zorder=1, labels=labels)

for patch, color in zip(bplot2['boxes'], color_list):
    patch.set_edgecolor(color)
    patch.set_facecolor('None')

bplot3 = plt.boxplot(boxplot_dataC_CME, positions=x_list_box_final[2], widths=box_width,
                     patch_artist=True, showfliers=False, zorder=1, labels=labels)

for patch, color in zip(bplot3['boxes'], color_list):
    patch.set_edgecolor(color)
    patch.set_facecolor('None')

########################################################################
########################################################################
boxplot_data = [boxplot_dataABC_C, boxplot_dataABC_M, boxplot_dataABC_E]

for i in range(len(boxplot_data)):
    # boxplot_data_num用来统计每组数据的长度, 画scatter图时会用到
    boxplot_data_num = []
    for j in boxplot_data[i]:
        boxplot_data_num_tmp = len(j)
        boxplot_data_num.append(boxplot_data_num_tmp)

    spotx = []
    for j_spotx, k_spotx in zip(x_list_box[i], boxplot_data_num):
        spotx_tmp = [j_spotx] * k_spotx
        spotx.append(spotx_tmp)

    ax.scatter(spotx, boxplot_data[i], c=color_list[i], s=30, zorder=2)
########################################################################
########################################################################

ax.grid(True, ls=':', color='b', alpha=0.3)
plt.title('甲乙丙各班语文/数学/英语成绩Box_chart分析', fontweight='bold')
ax.set_xticks(x_loc)
ax.set_xticklabels(x_labels, rotation=90)
ax.set_ylabel('分数/百分制', fontweight='bold')
################################################################################################################
################################################################################################################
plt.legend(handles=bplot1['boxes'], title='学科', loc='center left', bbox_to_anchor=(1.02, 0.5),
           facecolor='None', edgecolor='#000000', frameon=True, ncol=1, markerscale=3, borderaxespad=0,
           handletextpad=0.1, fontsize='x-large', title_fontsize='x-large', labels=legend_labels)
################################################################################################################
################################################################################################################
plt.xticks(weight='bold')
plt.yticks(weight='bold')
fig.tight_layout()
plt.show()
3.1.1-4、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第32张图片

由输出结果可知,这样操作才能输出我们想要的效果,但是这样生成图例的方法并不适用于数据集比较多的情况,也不适用于自动读取数据集并批量绘制箱线图的操作,所以我们在往期中没有采取这种生成图例的方式。


3.2、还有什么方法能够生成箱线图的图例?

详见3.1.1-3和3.1.1-4的内容,采取面向对象画图例的方式,bp[‘boxes’]是为了获取箱线图的箱体这个对象,它的属性也会被获取到,比如颜色和形状。


3.3、箱线图的图例生成方法和柱状图、折线图、饼图、直方图、散点图等图的图例生成方法有什么不同之处或特别之处?

柱状图采用plt.bar(label=‘字符串’);plt.legend()来生成图例;
折线图采用plt.plot(label=‘字符串’);plt.legend()来生成图例;
直方图采用plt.hist(label=‘字符串’);plt.legend()来生成图例;
散点图采用plt.scatter(label=‘字符串’);plt.legend()来生成图例;
饼图采用的方式如下所示:

3.3.1、方式一:既生成图例又在扇形旁显示标签

3.3.1-1、代码如下:
# 扇形图例标识
import matplotlib.pyplot as plt

# 这两行代码解决 plt 中文显示的问题
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 扇形图例标识
labels = ['0-10岁', '10-20岁', '20-30岁', '30-40岁', '40-100岁']

# 扇形大小
sizes = [40, 30, 20, 5, 5]
# 第二块扇形偏移
explode = [0, 0.1, 0, 0, 0]

# 创建图形
fig, ax = plt.subplots()

# 开始画饼图
ax.pie(sizes, labels=labels, explode=explode, autopct='%1.1f%%', shadow=True)

# 确保画的饼是圆的
ax.axis('equal')

ax.set_title('各年龄段长蛀牙情况')

# 设置图例
ax.legend()

plt.show()

3.3.1-2、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第33张图片

3.3.2、方式二:只生成图例,且不在扇形旁显示标签

3.3.2-1、代码如下:
# 扇形图例标识
import matplotlib.pyplot as plt

# 这两行代码解决 plt 中文显示的问题
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 扇形图例标识
labels = ['0-10岁', '10-20岁', '20-30岁', '30-40岁', '40-100岁']

# 扇形大小
sizes = [40, 30, 20, 5, 5]
# 第二块扇形偏移
explode = [0, 0.1, 0, 0, 0]

# 创建图形
fig, ax = plt.subplots()

# 开始画饼图
ax.pie(sizes, explode=explode, autopct='%1.1f%%', shadow=True)

# 确保画的饼是圆的
ax.axis('equal')

ax.set_title('各年龄段长蛀牙情况')

# 设置图例
ax.legend(labels=labels)

plt.show()

3.3.2-2、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第34张图片

3.3.3、方式三:只在扇形旁显示标签,且不生成图例

3.3.3-1、代码如下:
# 扇形图例标识
import matplotlib.pyplot as plt

# 这两行代码解决 plt 中文显示的问题
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 扇形图例标识
labels = ['0-10岁', '10-20岁', '20-30岁', '30-40岁', '40-100岁']

# 扇形大小
sizes = [40, 30, 20, 5, 5]
# 第二块扇形偏移
explode = [0, 0.1, 0, 0, 0]

# 创建图形
fig, ax = plt.subplots()

# 开始画饼图
ax.pie(sizes, labels=labels, explode=explode, autopct='%1.1f%%', shadow=True)

# 确保画的饼是圆的
ax.axis('equal')

ax.set_title('各年龄段长蛀牙情况')

# 设置图例
# ax.legend()

plt.show()

3.3.3-2、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第35张图片

3.3.4、方式四:只在扇形旁显示标签,且不生成图例,如果不想把扇形做分离,可以去掉explode参数

3.3.4-1、代码如下:
# 扇形图例标识
import matplotlib.pyplot as plt

# 这两行代码解决 plt 中文显示的问题
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 扇形图例标识
labels = ['0-10岁', '10-20岁', '20-30岁', '30-40岁', '40-100岁']

# 扇形大小
sizes = [40, 30, 20, 5, 5]
# 第二块扇形偏移
explode = [0, 0.1, 0, 0, 0]

# 创建图形
fig, ax = plt.subplots()

# 开始画饼图
ax.pie(sizes, labels=labels, autopct='%1.1f%%', shadow=True)

# 确保画的饼是圆的
ax.axis('equal')

ax.set_title('各年龄段长蛀牙情况')

# 设置图例
# ax.legend()

plt.show()

3.3.4-2、输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第36张图片


二、多种颜色的普通分组箱线图和散点图的叠加图

1.示例数据如下

表格如下(示例):


班别 语文成绩(分/100分制) 数学成绩(分/100分制) 英语成绩(分/100分制)
甲班 80 70 90
90 90 100
75 95 100
65 85 85
85 75 75
95 85 90
100 90 100
100 100 100
80 100 75
70 85 70
90 90 85
95 95 90
85 98 95
86 99 95
92 85 90
90 88 80
95 86 70
90 75 80
85 78 70
100 90 75
乙班 60 60 70
70 70 75
80 75 75
65 80 70
75 75 60
80 75 90
73 65 98
75 80 95
85 60 85
90 80 75
95 90 70
65 95 60
70 95 65
75 90 70
80 80 75
85 85 75
95 75 80
85 75 75
80 60 70
70 65 80
丙班 60 100 80
80 100 90
100 100 100
100 95 100
100 95 100
100 95 90
90 95 95
95 95 95
95 90 95
95 85 90
85 90 95
95 90 90
95 90 95
95 95 90
95 90 95
80 95 90
95 95 95
90 95 90
90 95 95
90 90 85

现在需要把表格中的数据绘制成箱线图,从而进一步分析每个班级的学生成绩情况。

2.代码如下

2.1 代码如下(示例):

2.1.1 Case1:

import matplotlib.pyplot as plt
import numpy as np

# 设置字体, 解决中文乱码问题
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
# 解决图像中的'-'负号的乱码问题
plt.rcParams['axes.unicode_minus'] = False

ClassA_C = [80, 90, 75, 65, 85, 95, 100, 100, 80, 70, 90, 95, 85, 86, 92, 90, 95, 90, 85, 100]
ClassA_M = [70, 90, 95, 85, 75, 85, 90, 100, 100, 85, 90, 95, 98, 99, 85, 88, 86, 75, 78, 90]
ClassA_E = [90, 100, 100, 85, 75, 90, 100, 100, 75, 70, 85, 90, 95, 95, 90, 80, 70, 80, 70, 75]

ClassB_C = [60, 70, 80, 65, 75, 80, 73, 75, 85, 90, 95, 65, 70, 75, 80, 85, 95, 85, 80, 70]
ClassB_M = [60, 70, 75, 80, 75, 75, 65, 80, 60, 80, 90, 95, 95, 90, 80, 85, 75, 75, 60, 65]
ClassB_E = [70, 75, 75, 70, 60, 90, 98, 95, 85, 75, 70, 60, 65, 70, 75, 75, 80, 75, 70, 80]

ClassC_C = [60, 80, 100, 100, 100, 100, 90, 95, 95, 95, 85, 95, 95, 95, 95, 80, 95, 90, 90, 90]
ClassC_M = [100, 100, 100, 95, 95, 95, 95, 95, 90, 85, 90, 90, 90, 95, 90, 95, 95, 95, 95, 90]
ClassC_E = [80, 90, 100, 100, 100, 90, 95, 95, 95, 90, 95, 90, 95, 90, 95, 90, 95, 90, 95, 85]

fig = plt.figure(figsize=(8, 6), facecolor='#B0C4DE')
ax = fig.add_subplot(facecolor='white')

# 每个刻度标签下有几个group就有几个箱子
group_dataA = [ClassA_C, ClassA_M, ClassA_E]

boxplot_dataABC_C = [ClassA_C, ClassB_C, ClassC_C]
boxplot_dataABC_M = [ClassA_M, ClassB_M, ClassC_M]
boxplot_dataABC_E = [ClassA_E, ClassB_E, ClassC_E]

# 橙绿蓝
color_list = ['#FF8C00', '#00FF00', '#0000FF']

x_labels = ['甲班', '乙班', '丙班']
legend_labels = ['语文', '数学', '英语']
length = len(x_labels)
x_loc = np.arange(length)

group_number = len(group_dataA)
total_width = 0.6
box_total_width = total_width * 0.65
interval_total_width = total_width * 0.35
box_width = box_total_width / group_number

###################################################
if group_number == 1:
    interval_width = interval_total_width
else:
    interval_width = interval_total_width / (group_number - 1)

###################################################
if group_number % 2 == 0:
    x1_box = x_loc - (group_number / 2 - 1) * box_width - box_width / 2 - (group_number / 2 - 1) * interval_width - interval_width / 2
else:
    x1_box = x_loc - ((group_number - 1) / 2) * box_width - ((group_number - 1) / 2) * interval_width
x_list_box = [x1_box + box_width * i + interval_width * i for i in range(group_number)]


boxplot_data = [boxplot_dataABC_C, boxplot_dataABC_M, boxplot_dataABC_E]

for i in range(len(boxplot_data)):
    #####################################################################
    # 先画boxplot
    #######################
    # boxplot_data_num用来统计每组数据的长度, 画scatter图时会用到
    boxplot_data_num = []
    for j in boxplot_data[i]:
        boxplot_data_num_tmp = len(j)
        boxplot_data_num.append(boxplot_data_num_tmp)
    #######################
    ax.boxplot(boxplot_data[i], positions=x_list_box[i], widths=box_width, patch_artist=True,
               medianprops={'lw': 1, 'color': color_list[i]},
               boxprops={'facecolor': 'None', 'edgecolor': color_list[i]},
               capprops={'lw': 1, 'color': color_list[i]},
               whiskerprops={'ls': '-', 'lw': 1, 'color': color_list[i]},
               showfliers=False, zorder=1)
    # flierprops = {'marker': 'o', 'markerfacecolor': color_list[i], 'markeredgecolor': color_list[i], 'markersize': 8}
    #####################################################################
    # 再画scatter
    # 将每一组箱线图统计的所有点绘制在图上
    # spotx是每一组箱线图所有的点的横坐标
    spotx = []
    for j_spotx, k_spotx in zip(x_list_box[i], boxplot_data_num):
        spotx_tmp = [j_spotx] * k_spotx
        spotx.append(spotx_tmp)
    # print('$$$spotx:', spotx)
    ax.scatter(spotx, boxplot_data[i], c=color_list[i], s=30, label=legend_labels[i], zorder=2)
ax.grid(True, ls=':', color='b', alpha=0.3)
plt.title('甲乙丙各班语文/数学/英语成绩Box_chart分析', fontweight='bold')
ax.set_xticks(x_loc)
ax.set_xticklabels(x_labels, rotation=90)
ax.set_ylabel('分数/百分制', fontweight='bold')
################################################################################################################
################################################################################################################
plt.legend(title='学科', loc='center left', bbox_to_anchor=(1.02, 0.5), facecolor='None', edgecolor='#000000',
           frameon=True, ncol=1, markerscale=3, borderaxespad=0, handletextpad=0.1, fontsize='x-large', title_fontsize='x-large')
################################################################################################################
################################################################################################################
plt.xticks(weight='bold')
plt.yticks(weight='bold')
fig.tight_layout()
plt.show()

输出结果如下:

Python Matplotlib数据可视化绘图之(五)————箱线图与散点图的叠加图_第37张图片

注意:如果想保存这种画布带背景颜色且轴域也带背景颜色的图片(在此图中,画布[fig]背景颜色为#B0C4DE,轴域[ax]背景颜色为white),需要使用以下语句保存到本地,具体语句如下:

plt.savefig(picture_name + '.jpg', facecolor=self.fig.get_facecolor())
# 其中picture_name为给图片命的名字

三、总结

以上就是今天要讲的内容,本文详细介绍了各种箱线图的绘制过程和方法,并用实例给大家演示了具体的实现代码和实现逻辑,并且在文中也详细回答了往期《Python Matplotlib数据可视化绘图之(二)————箱线图》(文章链接为:https://blog.csdn.net/Mr_Dragon66/article/details/127814202?spm=1001.2014.3001.5501)这篇文章中最后总结中所提的问题,希望对大家学习画箱线图有帮助。

你可能感兴趣的:(python,matplotlib,信息可视化,numpy)