小提琴图(Violin Plot)是一种数据可视化图表,通常用于显示数据分布和概率密度。它结合了箱线图(Box Plot)和核密度估计图(Kernel Density Plot)的特点,提供了更丰富的信息。
小提琴图(Violin Plot)由几个主要组成部分构成,主要包括以下元素:
- 小提琴体(Violin Body): 小提琴体是图表的主体部分,通常呈现为两个镜像的核密度估计图,沿着数轴展开。这部分展示了数据的分布情况,宽度表示在该位置的数据点密度,即频率。较宽的部分表示数据点较密集,较窄的部分表示数据点较稀疏。
- 箱线图(Box Plot): 小提琴图的中间通常包含一个箱线图,用于显示数据的五个统计指标:最小值、第一四分位数(Q1)、中位数、第三四分位数(Q3)、和最大值。这有助于识别数据的离群值。
- 顶端和底端: 小提琴图的两端是小提琴体的边界线,标志着数据点的密度分布情况。这些边界线通过核密度估计图来形成,反映了数据在不同位置的密度。边界线的形状和宽度取决于数据的分布,而且不一定对应于数据的最大和最小值。
- 异常值标记(Outliers): 小提琴图中的箱线图可能包含异常值标记,表示数据中的离群值。
小提琴图的整体形状提供了一种对数据分布的直观感受,结合了箱线图和核密度估计图的特点,使得它在展示数据集中趋势和分布形状时非常有用。
示例1:用numpy生成随机数据绘制单个小提琴图。代码如下:
#导入相关的模块
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 创建一个示例DataFrame
data1=pd.DataFrame()
#生成一些随机数据
data1['A']=[np.random.rand(1,20)]
# 绘制小提琴图
fig,ax=plt.subplots()
ax.violinplot(data1['A'],
vert=True, #垂直分布
showmedians=True) #标记中位数
ax.set_xlabel('A',fontsize=12) #设置x轴标签
ax.set_ylabel('Value',fontsize=12) #设置y轴标签
#保存图片
fig.savefig('小提琴图示例1.png',dpi=400)
# 显示图形
plt.show()
结果如图如下:
示例2:基于某站点2018年1月的温度数据绘制小提琴图。数据文件为"wendu.csv"。
代码如下:
#导入相关的库
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
plt.rcParams['font.sans-serif'] = ['simsun'] # 显示中文
#读入数据
data=pd.read_csv('wendu.csv',header=0)
data_1=pd.DataFrame()
data_1['Tmean']=data['Tmean']
data_2=pd.DataFrame()
data_2['Tmax']=data['Tmax']
data_3=pd.DataFrame()
data_3['Tmin']=data['Tmin']
#将每组数据放到一个列表中,方便绘图
plt_data=[data_1['Tmean'],
data_2['Tmax'],
data_3['Tmin']]
# 使用 Matplotlib 绘制小提琴图和箱线图
fig, ax = plt.subplots(figsize=(12, 8))
# 绘制小提琴图
violin_parts = ax.violinplot(plt_data,
showmedians=False, #不展示中位数
vert=True, #垂直分布
widths=0.7, #宽为0.7
showextrema=False) #不显示异常值
# 设置小提琴图的颜色
cmap = plt.cm.get_cmap('Accent')(np.linspace(0, 1, 3))
for pc, col in zip(violin_parts['bodies'], cmap):
pc.set_facecolor(col)
# 绘制箱线图
box_parts = ax.boxplot(plt_data,
sym='k+',
vert=True,
widths=0.1,
showmeans=True,
meanline=False,
meanprops=dict(marker='o',markerfacecolor='r'),
patch_artist=True,
medianprops=dict(color='red'),
boxprops=dict(facecolor='w'))
# # 设置箱线图的颜色
# for box in box_parts['boxes']:
# box.set_facecolor('white')
#绘制折线图,以各温度的均值为数据
x=list(np.arange(1,4))
y=[data_1['Tmean'].mean(),data_2['Tmax'].mean(),data_3['Tmin'].mean()]
ax.plot(x,y,c='b',ls=':')
# 添加标题和标签
ax.set_title('日序列温度小提琴图', fontsize=16)
ax.set_ylabel('温度($^\circ$C)', fontsize=12)
ax.set_xticks(np.arange(1, 4))
ax.set_xticklabels(['日平均温度','日最高温度','日最低温度'], fontsize=12)
#保存图片
fig.savefig('日序列温度小提琴图.png',dpi=400)
#展示图片
plt.show()
结果图如下: