前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python-matplotlib 多子图共用colorbar

Python-matplotlib 多子图共用colorbar

作者头像
DataCharm
发布2021-02-22 15:05:58
10.4K0
发布2021-02-22 15:05:58
举报

01. 引言

在推出散点颜色密度图的matplotlib 绘制教程后,有小伙伴反应能否出一篇多子图共用一个colorbar的系列教程,这里也就使用自己的数据进行绘制(数据一共四列,具体为真实值和使用三个模型计算的预测值)。

02. 实现颜色和数值间的对应关系

在绘制多子图共用colorbar时,最重要的就是对颜色映射进行设置,这里使用了matplotlib.color.Normalize()进行颜色和数值对应设置。先看一下使用默认设置的结果,每个子图对应一个colorbar。效果如下:

可以看出,每个子图对应的值颜色都是不同,这样不利于对比,采用matplotlib.color.Normalize()操作后就可有效解决此问题:

代码语言:javascript
复制
#将颜色映射到 vmin~vmax 之间
norm = matplotlib.colors.Normalize(vmin=0, vmax=60)

效果如下:

至于其他拟合线、EE等的设置,可以参考之前的文章Python-matplotlib 学术散点图 EE 统计及绘制 Python-matplotlib 学术散点图完善

03. 详细代码

多子图共用colorbar的详细代码如下:

代码语言:javascript
复制
import pandas as pd
import numpy as np
import matplotlib
import matplotlib.cm as cm
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = ['Arial']

test_data = pd.read_excel('GBRT_SVR_DNN_esti_save_angle_process.xlsx')

x = test_data['true_data'].values.ravel() #真实值
y = test_data['model01_estimated'].values.ravel()#预测值
y2 = test_data['SVR_estimated'].values.ravel()#预测值2
y3 = test_data['DNN_model01_estimated'].values.ravel()#预测值3

nbins = 150
#模型一结果
H, xedges, yedges = np.histogram2d(x, y, bins=nbins)
H = np.rot90(H)
H = np.flipud(H)
Hmasked = np.ma.masked_where(H==0,H)

#模型二结果
H2, xedges2, yedges2 = np.histogram2d(x, y2, bins=nbins)
H2 = np.rot90(H2)
H2 = np.flipud(H2)
Hmasked2 = np.ma.masked_where(H2==0,H2)

#模型三结果
H3, xedges3, yedges3 = np.histogram2d(x, y3, bins=nbins)
H3 = np.rot90(H3)
H3 = np.flipud(H3)
Hmasked3 = np.ma.masked_where(H3==0,H3)

#可视化绘制
fig, (ax1, ax2,ax3) = plt.subplots(nrows=1,ncols=3,figsize=(12,3),dpi=200)

#将颜色映射到 vmin~vmax 之间
norm = matplotlib.colors.Normalize(vmin=0, vmax=60)

#模型一结果绘图
im1 = ax1.pcolormesh(xedges, yedges, Hmasked, cmap=cm.get_cmap('jet'),norm=norm)
#fig.colorbar(im1, ax=ax1)

#模型二结果绘图
im2 = ax2.pcolormesh(xedges2, yedges2, Hmasked2, cmap=cm.get_cmap('jet'), norm=norm)
#fig.colorbar(im2, ax=ax2)

#模型二结果绘图
im3 = ax3.pcolormesh(xedges3, yedges3, Hmasked3, cmap=cm.get_cmap('jet'), norm=norm,)
#fig.colorbar(im3, ax=ax3)

#前面三个子图的总宽度 为 全部宽度的 0.9;剩下的0.1用来放置colorbar
fig.subplots_adjust(right=0.9)
position = fig.add_axes([0.92, 0.12, 0.015, .78 ])#位置[左,下,右,上]
cb = fig.colorbar(im3, cax=position)

#设置colorbar标签字体等
colorbarfontdict = {"size":15,"color":"k",'family':'Times New Roman'}
cb.ax.set_title('Counts',fontdict=colorbarfontdict,pad=8)
cb.ax.tick_params(labelsize=11,direction='in')
cb.ax.set_yticklabels(['0','10','20','30','40','50','>60'],family='Times New Roman')
#suptitle()中x,y 属性的设置为调整title与子图(subplots)之间的距离
fig.suptitle('One Colorbar for Multiple Plot ',size=20,family='Times New Roman',x=.5,y=1.05)
plt.savefig(r'E:\Data_resourses\DataCharm 公众号\Python\学术图表绘制\scatter_One_Colorbar.png',
            width=7,height=5,dpi=900,bbox_inches='tight')
plt.show()

这里:

代码语言:javascript
复制
#设置colorbar标签字体等
colorbarfontdict = {"size":15,"color":"k",'family':'Times New Roman'}
cb.ax.set_title('Counts',fontdict=colorbarfontdict,pad=8)
cb.ax.tick_params(labelsize=11,direction='in')
cb.ax.set_yticklabels(['0','10','20','30','40','50','>60'],family='Times New Roman')

实现了对colorbar的定制化需求。

此外,我们设置colorbar也不是只绘制最后一个子图的colorbar,而其他子图不绘制,那样容易导致子图大小不一。这里单独绘制了colorbar,代码如下

代码语言:javascript
复制
fig.subplots_adjust(right=0.9)
position = fig.add_axes([0.92, 0.12, 0.015, .78 ])#位置[左,下,右,上]
cb = fig.colorbar(im3, cax=position)

这也是多子图共用一个colorbar避免大小不一的一个小技巧,希望大家可以记住。

04. 高斯核密度估计颜色映射

还有小伙伴想绘制如下的颜色密度散点图:

可以看出颜色密集部分出现“光滑”处理,其实就是通过核密度估计函数将 真实值和预测值之间进行密度值估计,再进行一个排序即可,详细代码如下:

代码语言:javascript
复制
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import gaussian_kde

x = test_data['true_data'].values.ravel() #真实值
y = test_data['model01_estimated'].values.ravel()#预测值
#计算点密度
#np.vstack:按垂直方向(行顺序)堆叠数组构成一个新的数组
xy = np.vstack([x,y])
z = gaussian_kde(xy)(xy)
idx = z.argsort()
x, y, z = x[idx], y[idx], z[idx]
fig, ax = plt.subplots(figsize=(7,5),dpi=200)
ax.scatter(x, y, c=z, s=3, edgecolor='')
plt.savefig(r'E:\Data_resourses\DataCharm 公众号\Python\学术图表绘制\scatter_gaussian_kde.png',
            width=7,height=5,dpi=900,bbox_inches='tight')
plt.show()

如果没有以下操作:

代码语言:javascript
复制
idx = z.argsort()
x, y, z = x[idx], y[idx], z[idx]

所绘制的结果如下:

可以看出红圈中还是和排序前的有较大不同的。

05. 总结

原创不易,整理代码和数据更是不易,希望大家多一份理解和支持啊!

为了大家更好的学习交流,DataCharm的学习交流群已经建立,由于群的二维码连接易失效,可以通过扫面下方二维码,添加本人微信,做自我介绍啊,要不然我都不知道是谁

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-08-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DataCharm 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 01. 引言
  • 02. 实现颜色和数值间的对应关系
  • 03. 详细代码
  • 04. 高斯核密度估计颜色映射
  • 05. 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档