Seaborn的
jointplot
(官方文档)提供了一个较为方便的绘制联合分布的方法,但是它的封装程度较高,在有一些特殊的需求时调整起来很不方便。比如我的需求是要在画布上同时绘制多张联合分布图,在一个联合分布内还要展示多种不同的分布形式,此外还有对图像的边框,线型等样式的调整等等。因此,为了满足上面的几个需求,使用Matplotlib来实现应该更加方便直观且易于扩展一些。
首先导入必要的包
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec
然后以网格的方式在画布上分割出多个绘图子区域。
fig = plt.figure(figsize=(18, 6))
gs = GridSpec(4, 14)
ax1_xy, ax1_x, ax1_y = fig.add_subplot(gs[1:4, 0:3]), fig.add_subplot(gs[0, 0:3]), fig.add_subplot(gs[1:4, 3])
ax2_xy, ax2_x, ax2_y = fig.add_subplot(gs[1:4, 5:8]), fig.add_subplot(gs[0, 5:8]), fig.add_subplot(gs[1:4, 8])
ax3_xy, ax3_x, ax3_y = fig.add_subplot(gs[1:4, 10:13]), fig.add_subplot(gs[0, 10:13]), fig.add_subplot(gs[1:4, 13])
编写一个函数来设置绘图区域的样式,主要是隐藏一些刻度和边框让整体看起来不要过于凌乱。
def set_ax(ax: plt.axes, xy: tuple, tblr: tuple, label_xy: bool, title: str):
"""
设置绘图区域ax的样式
:param ax: 绘图区域
:param xy: (bool, bool) 控制x和y轴的刻度是否可见
:param tblr: (bool, bool, bool, bool) 控制上下左右的边框是否可见
:param label_xy: bool 控制是否显示x和y轴的标签
:param title: str 绘图区域的标题
:return: 0
"""
if title:
ax.set_title(title)
if label_xy:
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.tick_params(bottom=False, top=False, left=False, right=False) # 隐藏刻度间隔线
ax.axes.xaxis.set_visible(xy[0]) # 设置刻度
ax.axes.yaxis.set_visible(xy[1]) # 设置刻度
drc = ['top', 'bottom', 'left', 'right']
for idx in range(4):
ax.spines[drc[idx]].set_visible(tblr[idx])
return 0
使用一下看看效果。
set_ax(ax1_xy, (1, 1), (0, 1, 1, 0), True, '')
set_ax(ax1_x, (0, 0), (0, 1, 0, 0), False, '(a)')
set_ax(ax1_y, (0, 0), (0, 0, 1, 0), False, '')
最后就是用数据画图了,其中有个额外的操作是使用了zorder
参数设置了散点图和KDE图的前后层次。
x1, y1 = np.random.random(100), np.random.random(100) # 生成红色数据点
x2, y2 = np.random.random(100)+0.2, np.random.random(100)+0.1 # 生成绿色数据点
sns.kdeplot(x1, y1, ax=ax1_xy, color='r', zorder=10) # 绘制红色数据的联合KDE图
ax1_xy.scatter(x2, y2, marker='.', color='g', zorder=30) # 绘制绿色数据的散点图
sns.kdeplot(x=x1, ax=ax1_x, color='r') # 绘制红色数据x的KDE图
sns.kdeplot(y=y1, ax=ax1_y, color='r')
sns.kdeplot(x=x2, ax=ax1_x, color='g')
sns.kdeplot(y=y2, ax=ax1_y, color='g')
剩下的部分如法炮制就可以了。
网友评论