1

I need plots of radar images to have the same size for different variables such that I can vertically align them on a web page.

The units are different and the width of the colorbar (including tick lables and label) changes accordingly, since the tick values of some colorbars are negative and just need more space than others. Using the bbox_inches="tight" option in the savefig command however leads to different figure widths. If I embed the plots, they are resized, but the box within the figure where the data is drawn, is adjusted, too, and the boxes are not aligned anymore.

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

Is there a way how I can prevent the bbox to be tight on one side, but keep it tight on the others while setting a fixed image width?

Here's a simplified version of the code I use:

    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: Using subplots is not an option, because the actual web page will use JavaScript and the plots will be changeable individually.

pagraf
  • 11
  • 3

2 Answers2

0

This is probably not the most elegant solution, but you could align your colorbar's tick label to the right, and provide padding so they don't collide with your colorbar.

The padding would need to be adjusted so it works regardless of the range of the data

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 hereenter image description here

Diziet Asahi
  • 38,379
  • 7
  • 60
  • 75
  • You're right, it's not the most elegant solution. However, it solves my problem :-) Thanks a lot! – pagraf Aug 03 '15 at 09:08
0

I found a solution which is i.m.o. a bit more elegant than the answer of Diziet Asahi (Thanks anyways. Your answer was the inspiration for this solution). I adapted it from here.

Instead of inserting a pad and aligning the colorbar ticklabels to the right, it manually inserts the colorbar label as text, which keeps the colorbar label at the same location for every variable:

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

Additionally, I added pad=0.01 to the plt.colorbar() command, to move the colorbar closer to the plot, which looks a bit better.

Here is the full code:

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')

The result can be seen here.

Community
  • 1
  • 1
pagraf
  • 11
  • 3