1
密度图用于显示数据在连续数值(或时间段)的分布状况,是直方图的变种。由于密度图不受所使用分组数量的影响,所以能更好地界定分布形状。
基于seaborn(建议)
import seaborn as sns
import matplotlib.pyplot as plt
# 导入数据
df = sns.load_dataset('iris')
# 利用kdeplot函数绘制密度图
sns.kdeplot(df['sepal_width'])
plt.show()
2
基于matplotlib
import matplotlib.pyplot as plt
import numpy as np
from scipy.stats import gaussian_kde
# 导入数据
df = sns.load_dataset('iris')
# 根据数据集构建密度函数
density = gaussian_kde(df['sepal_width'])
density.covariance_factor = lambda : .25
density._compute_covariance()
# 构造向量 作为x轴刻度
xs = np.linspace(1.5, 5, 200)
# 初始化
plt.figure(figsize=(8, 6))
plt.plot(xs,density(xs))
plt.show()
3
自定义密度图一般是结合使用场景对相关参数进行修改,并辅以其他的绘图知识。参数信息可以通过官网进行查看,其他的绘图知识则更多来源于实战经验,大家不妨将接下来的绘图作为一种学习经验,以便于日后总结。
seaborn主要利用kdeplot
绘制密度图,可以通过seaborn.kdeplot[1]了解更多用法
修改参数
import seaborn as sns
import matplotlib.pyplot as plt
sns.set(font='SimHei', font_scale=0.8, style="darkgrid") # 解决Seaborn中文显示问题
# 导入数据
df = sns.load_dataset("iris")
# 构造子图
fig, ax = plt.subplots(1,3,constrained_layout=True, figsize=(12, 4))
# 水平密度图
ax_sub = sns.kdeplot(y=df['sepal_width'], fill=True, color="skyblue", ax=ax[0])
ax_sub.set_title('水平密度图')
# 增加阴影
ax_sub = sns.kdeplot(df['sepal_width'], fill=True, ax=ax[1])
ax_sub.set_title('增加阴影')
# 修改带宽,以突出数据分布的原始状态(避免过于平滑)
ax_sub = sns.kdeplot(df['sepal_width'], fill=True, bw_method=0.1, ax=ax[2])
ax_sub.set_title('降低带宽')
plt.show()
4
一图绘制多个变量
import seaborn as sns
import matplotlib.pyplot as plt
df = sns.load_dataset('iris')
sns.kdeplot(df['sepal_width'], fill=True, color="r", label='sepal_width')
sns.kdeplot(df['sepal_length'], fill=True, color="b", label='sepal_length')
plt.legend()
plt.xlabel('sepal_width/sepal_length') # 修改x标签
plt.show()
5
# 引申-镜像密度图:可用来对比两个变量的分布
import numpy as np
from numpy import linspace
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from scipy.stats import gaussian_kde
# 自定义数据
df = pd.DataFrame({
'var1': np.random.normal(size=1000),
'var2': np.random.normal(loc=2, size=1000) * -1
})
# 初始化
plt.rcParams["figure.figsize"]=12,8
# 绘制密度图1
sns.kdeplot(data=df, x="var1", fill=True, alpha=1)
# 绘制密度图2
kde = gaussian_kde(df.var2)
x_range = linspace(min(df.var2), max(df.var2), len(df.var2))
# 乘以-1进行反转(绘制镜像图)
sns.lineplot(x=x_range*-1, y=kde(x_range) * -1, color='orange')
plt.fill_between(x_range*-1, kde(x_range) * -1, color='orange')
# 轴名称
plt.xlabel("numbers")
plt.axhline(y=0, linestyle='-',linewidth=1, color='black')
plt.show()
6
分组密度图
import seaborn as sns
import matplotlib.pyplot as plt
# 导入数据
from plotnine.data import diamonds # dataset
# alpha:修改透明度
sns.kdeplot(data=diamonds, x="price", hue="cut", fill=True, common_norm=False, alpha=0.4)
plt.show()
7
# 利用FacetGrid以多网格展示
import seaborn as sns
import matplotlib.pyplot as plt
# 导入数据
diamonds = sns.load_dataset('diamonds')
# 绘制网格(共用坐标轴)
g = sns.FacetGrid(diamonds, col='cut', hue='cut', col_wrap=3)
# 绘制密度图
g = g.map(sns.kdeplot,"price", cut=0, fill=True, common_norm=False, alpha=1, legend=False)
# 每个网格的标题
g = g.set_titles("{col_name}")
plt.show()
8
引申-绘制堆积图
import seaborn as sns
import matplotlib.pyplot as plt
# 导入数据
diamonds = sns.load_dataset('diamonds')
# 绘制堆积图
sns.kdeplot(data=diamonds, x="price", hue="cut", common_norm=False, multiple="fill", alpha=1)
plt.show()
9
以上通过seaborn的kdeplot
可以快速绘制密度图,也可通过gaussian_kde
构建密度函数后再通过matplotlib进行简单绘制,并通过修改参数或者辅以其他绘图知识自定义各种各样的密度图来适应相关使用场景。
共勉~
[1]
seaborn.kdeplot: https://seaborn.pydata.org/generated/seaborn.kdeplot.html