如何使用colorbar将bbox保持在三面并且对于不同的图表保持不变

时间:2015-07-30 14:38:21

标签: python matplotlib colorbar

我需要对不同变量使用相同大小的雷达图像,以便我可以在网页上垂直对齐它们。

单位是不同的,并且颜色条的宽度(包括刻度标签和标签)相应地改变,因为一些颜色条的刻度值是负的并且仅需要比其他颜色更多的空间。使用bbox_inches ="紧" savefig命令中的选项会导致不同的图形宽度。如果我嵌入这些图,它们会被调整大小,但图中的框也会调整数据,并且框也不再对齐。

How it looks now. the time axes are not perfectly aligned because the colorbar of the lower plot is wider.

有没有办法可以防止bbox在一侧变紧,但在设置固定图像宽度的同时保持紧密?

这是我使用的代码的简化版本:

    import numpy as np
    import matplotlib.pyplot as plt
    import pylab

    method=1
    fs=12
    height=600
    width=3200
    my_dpi=200

    x, y = np.meshgrid(np.linspace(0,1000,100),np.linspace(0,31*100,32))
    if method ==1:
        z=numpy.random.rand(32,100)
    else:
        z=-3*numpy.random.rand(32,100)

    plt.figure(figsize=(width/my_dpi, height/my_dpi), dpi=my_dpi)
    plt.pcolor(x,y,z,cmap='jet', vmin=z.min(), vmax=z.max())
    cbar=plt.colorbar()

    plt.ylabel('Height above Radar [m]',fontsize=fs)
    plt.xlabel('Time UTC',fontsize=fs)

    plt.title("MRR roof 20150729")

    plt.axis([x.min(), x.max(),y.min(), y.max()])
    cbar.set_label('Reflectivity [dBZ]', rotation=90)

    plotname="somename"+str(method)+".png"
    pylab.savefig(plotname,dpi=my_dpi,bbox_inches='tight')

PS:使用子图不是一个选项,因为实际的网页将使用JavaScript,并且图表可以单独更改。

2 个答案:

答案 0 :(得分:0)

这可能不是最优雅的解决方案,但您可以将颜色条的标签对齐到右侧,并提供填充,以免它们与您的颜色条发生碰撞。

填充需要进行调整,以便无论数据范围如何都能正常工作

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

method=1
fs=12
height=600
width=3200
my_dpi=200

x, y = np.meshgrid(np.linspace(0,1000,100),np.linspace(0,31*100,32))
if method ==1:
    z=np.random.rand(32,100)
else:
    z=-3*np.random.rand(32,100)

fig = plt.figure(figsize=(width/my_dpi, height/my_dpi), dpi=my_dpi)
ax = fig.add_subplot(111)
a = ax.pcolor(x,y,z,cmap='jet', vmin=z.min(), vmax=z.max())
ax.set_ylabel('Height above Radar [m]',fontsize=fs)
ax.set_xlabel('Time UTC',fontsize=fs)
ax.set_title("MRR roof 20150729")
plt.axis([x.min(), x.max(),y.min(), y.max()])

cbar = plt.colorbar(a)
cbar.set_label('Reflectivity [dBZ]', rotation=90)
for T in cbar.ax.yaxis.get_ticklabels():
    T.set_horizontalalignment('right')
cbar.ax.yaxis.set_tick_params(pad=30)

plotname="somename"+str(method)+".png"
plt.savefig(plotname,dpi=my_dpi, bbox_inches='tight')

enter image description here enter image description here

答案 1 :(得分:0)

我找到了一个i.m.o的解决方案。比Diziet Asahi的答案更优雅(无论如何,谢谢。你的回答是这个解决方案的灵感)。我从here改编了它。

不是插入打击垫并将颜色条标签对齐到右边,而是手动将彩条标签作为文本插入,这样就可以将颜色条标签保持在每个变量的相同位置:

plt.text(1.065, .5, cbar_title,  fontsize=fs,
verticalalignment='center',rotation = 90, transform = ax.transAxes)

此外,我在pad=0.01命令中添加了plt.colorbar(),以便将颜色条移近图,这看起来更好一点。

以下是完整代码:

import numpy as np
import matplotlib.pyplot as plt

method=2
fs=12
height=600
width=3200
my_dpi=200

x, y = np.meshgrid(np.linspace(0,1000,100),np.linspace(0,31*100,32))
if method ==1:
    z=np.random.rand(32,100)
else:
    z=-3*np.random.rand(32,100)

fig = plt.figure(figsize=(width/my_dpi, height/my_dpi), dpi=my_dpi)
ax = fig.add_subplot(111)
a = ax.pcolor(x,y,z,cmap='jet', vmin=z.min(), vmax=z.max())
ax.set_ylabel('Height above Radar [m]',fontsize=fs)
ax.set_xlabel('Time UTC',fontsize=fs)
ax.set_title("MRR roof 20150729")
plt.axis([x.min(), x.max(),y.min(), y.max()])

cbar = plt.colorbar(a,pad=0.01)
cbar_title='Reflectivity [dBZ]'
plt.text(1.065, .5, cbar_title, fontsize=fs, verticalalignment='center',
         rotation = 90, transform = ax.transAxes)

plotname="somename"+str(method)+".png"
plt.savefig(plotname,dpi=my_dpi, bbox_inches='tight')

结果可见here