近期频繁处理数据,很多绘图上的操作用完就忘,开几个帖子记录一下。
需求
如果不要求对数据点进行详细区分(比如点的颜色、形状、大小等),可以直接调用seanborn的jointplot方法,即可很方便的绘制;
但是在论文中,为了能够看清数据,一般不同组的点要用不同的颜色和形状加以区分,这是seaborn.jointplot无法完成的,需要自己码代码;
接下来的内容就是要完成上述需求
导入包
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns # 基于matplotlib的高级绘图包
import pandas as pd
生成数据
data = pd.DataFrame(
{
'c_1': np.random.normal(10, 1, 1000),
'c_2': np.random.normal(5, 1, 1000),
'type': np.random.choice([1,2,3], size=1000)
}
)
data.head()
生成数据展示
c_1 c_2 type
0 9.710552 4.844736 1
1 9.162280 5.541102 1
2 10.118956 4.736274 3
3 11.165022 3.839247 3
4 10.415387 5.417838 3
绘图代码
fig = plt.figure(figsize=(8,8))
ax1 = fig.add_axes([0.1, 0.1, 0.8, 0.8]) # 散点图位置
ax2 = fig.add_axes([0.1, 0.9, 0.8, 0.1]) # 边际分布图位置
ax3 = fig.add_axes([0.9, 0.1, 0.1, 0.8]) # 边际分布图位置
color = ['#023047', '#FF8402', '#219EBC'] # 预设颜色
marker = ['o', '+', 'x'] # 预设点形状
# 遍历三种类型的点,分别绘制散点图
for tp in [0, 1, 2]:
tmp = data[data['type']==tp]
ax1.scatter(tmp['c_1'], tmp['c_2'], color=color[tp], marker=marker[tp], alpha=0.3, label='type_' + str(tp))
ax1.set_xlim(tmp['c_1'].min(), tmp['c_1'].max())
ax1.set_ylim(tmp['c_2'].min(), tmp['c_2'].max())
# 分别绘制边际分布图
sns.kdeplot(data=data, x='c_1', hue='type', shade=True, alpha=0.5, ax=ax2, legend=False, palette=['#023047', '#FF8402', '#219EBC'])
sns.kdeplot(data=data, x='c_2', hue='type', shade=True, alpha=0.5, vertical=True, ax=ax3, legend=False, palette=['#023047', '#FF8402', '#219EBC'])
# 设置子图格式
ax1.grid()
[ax1.spines[x].set_visible(False) for x in ['right', 'top']]
ax1.legend(loc=2, prop={'size':12})
ax1.set_xlabel('c_1', fontsize=15, labelpad=8.5)
ax1.set_ylabel('c_2', fontsize=15, labelpad=8.5)
ax1.tick_params(labelsize=12)
ax2.set_ylim(bottom=-0.01)
ax2.set_xlabel(None)
ax2.set_ylabel(None)
ax2.set_xticks([])
ax2.set_yticks([])
[ax2.spines[x].set_visible(False) for x in ['right', 'top', 'left']]
ax3.set_xlim(left=-0.01)
ax3.set_xlabel(None)
ax3.set_ylabel(None)
ax3.set_xticks([])
ax3.set_yticks([])
[ax3.spines[x].set_visible(False) for x in ['right', 'top', 'bottom']]