Matplotlib将image和图表的尺寸对齐

最近接手一个问题,要将一幅热力图和一个折线图画在同一幅图内,且要保证两幅图的尺寸一致,保证对齐,另外还要求纵轴的label位置也对齐,效果如下:

由于两种图像是以不同的格式读取的,上面是三通道rgb图,下面是plt绘制的折线图,用subplot画出来尺寸会不一样。可以理解为上面的图的尺寸是固定的,但下面的图的尺寸是可伸缩的。

一时间没想到太好的处理方式,于是看到了一篇博文http://www.pythonheidong.com/blog/article/141424/里提到用matplotlib.gridspec来把画布划分成等尺寸的小格子的方法来实现,基本上能满足我的需求。

大致的思路就是把画布四等分为2x2的网格(为什么不用两行一列的网格我后面会说),两幅图分别占用同一列的两个网格即可。除此之外,由于纵轴的label距坐标轴的距离会随着纵轴刻度的长度变动,下图的纵轴数字较长(1000),上图的较短(100),会导致如下图的不对齐的情况

为了解决这种情况,我也搜了很多方案,最后还是认为用最原始的方法比较合适:隐藏自带的label,自己打一个text文本上去肉眼移动距离。。。虽然这个方法很不精确,但是对于图例展示来说足够用了

实现的代码如下:

import numpy as np
import os
import matplotlib.pyplot as plt
import matplotlib.gridspec as grd
from matplotlib.pyplot import MultipleLocator


'''读取数据'''
path = r"F:\我的坚果云\数据展示"
htmp1 = np.load(os.path.join(path,"318-loc.npy")) #读取热力图
#由于之前是用cv2存的图像,rgb通道和plt保存的顺序不一样,所以要倒一倒
htmp2 = []
for x in htmp1:
    yy = []
    for y in x:
        yy.append([y[2], y[1], y[0]])
    htmp2.append(yy)
htmp2 = np.array(htmp2) #再存为ndarray格式

cord = np.load(os.path.join(path, "318.npy")) #读取折线图数据


'''开始绘图'''
fig = plt.figure()
gs = grd.GridSpec(nrows=2,ncols=2, width_ratios=[1,1], hspace=0.2) #把fig划分成2x2网格,网格宽度比为1:1

#画热力图
ax = plt.subplot(gs[0]) #往左上网格填元素
p = ax.imshow(htmp2, interpolation='nearest')
xlabel = ['$0.0$', '$0.5$','$1.0$', '$1.5$', '$2.0$']
plt.xticks(np.arange(0, 201, 50), xlabel)
hpy = int(htmp2.shape[0]/2)
plt.text(-54.5,hpy,"Channel",rotation=90,verticalalignment="center", horizontalalignment="center") #这里text的横坐标是我目测出来的,纵坐标取整个坐标的中点

#画折线图
ax2 = plt.subplot(gs[2]) #设置左下网格画波形
ax2.plot(np.linspace(0,2,200),cord*1000000,'k',lw=0.5) #波形数据
plt.ylim(top=1000) #设置y轴刻度最大值
plt.xlabel("Time(s)")
plt.text(-0.7,0,"Voltage(uV)",rotation=90,verticalalignment="center", horizontalalignment="center") #这里的纵坐标直接对应纵坐标为0的位置
plt.savefig("318.eps", format="eps", dpi=600) #保存成矢量图

之所以没有使用两行一列的网格,是因为测试下来还是会不对齐。同理修改网格的宽度比(width_ratios)也会导致不对齐,具体为什么我也不是很清楚。。。另外,生成的图片会有一半留白,这块空白是另一列空白的网格占的位置,介意的话可以把图片重新载入再只保存一半的图片(也就是只保存矩阵一半的数据),或者像我一样保存成eps后用Adobe Illustrator后期一下。。。这样的图片质量还很高

如果有更好的解决方式希望你能留言,谢谢!!!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值