3

My code is something (roughly) like this:

UPDATE: I've redone this with some actual mock-up code that reflects my general problem. Also, realized that the colorbar creation is in the actual loop as otherwise there's nothing to map it to. Sorry for the code before, typed it up in frantic desperation at the very end of the workday :).

import numpy
import matplotlib as mplot
import matplotlib.pyplot as plt
import os

#make some mock data
x = np.linspace(1,2, 100)
X, Y = np.meshgrid(x, x)
Z = plt.mlab.bivariate_normal(X,Y,1,1,0,0)

fig = plt.figure()
ax = plt.axes()
   '''
   Do some figure-related stuff that take up a lot of time,
    I want to avoid having to do them in the loop over and over again. 
    They hinge on the presence of fig so I can't make 
    new figure to save each time or something, I'd have to do
    them all over again.
    '''  
for i in range(1,1000):
   plotted = plt.plot(X,Y,Z)
   cbar = plt.colorbar(ax=ax, orientation = 'horizontal')
   plt.savefig(os.path.expanduser(os.path.join('~/', str(i))))
   plt.draw()
   mplot.figure.Figure.delaxes(fig, fig.axes[1]) #deletes but whitespace remains

   ''' 
   Here I need something to remove the colorbar otherwise 
   I end up with +1 colorbar on my plot at every iteration. 
   I've tried various things to remove it BUT it keeps adding whitespace instead
   so doesn't actually fix anything.
   '''

Has anyone come across this problem before and managed to fix it? Hopefully this is enough for an idea of the problem, I can post more code if needed but thought it'd be less of a clutter if I just give an overview example.

Thanks.

areuexperienced
  • 1,991
  • 2
  • 17
  • 27

2 Answers2

2

colorbar() allows you explicitly set which axis to render into - you can use this to ensure that they always appear in the same place, and not steal any space from another axis. Furthermore, you could reset the .mappable attribute of an existing colorbar, rather than redefine it each time.

Example with explicit axes:

x = np.linspace(1,2, 100)
X, Y = np.meshgrid(x, x)
Z = plt.mlab.bivariate_normal(X,Y,1,1,0,0)

fig = plt.figure()
ax1 = fig.add_axes([0.1,0.1,0.8,0.7])
ax2 = fig.add_axes([0.1,0.85,0.8,0.05])
...    

for i in range(1,5):
   plotted = ax1.pcolor(X,Y,Z)
   cbar = plt.colorbar(mappable=plotted, cax=ax2, orientation = 'horizontal')
   #note "cax" instead of "ax"
   plt.savefig(os.path.expanduser(os.path.join('~/', str(i))))
   plt.draw()
mdurant
  • 27,272
  • 5
  • 45
  • 74
  • Hi, I've redone the code above in a way that should let you reproduce my problem (though might want to reduce the loop iterations by several hundred :)). Could you post some example code of what you're talking about? – areuexperienced Aug 01 '14 at 22:23
  • Cheers, that looks like it'll work for me, will hopefully prove true on Monday :)! – areuexperienced Aug 01 '14 at 23:05
1

I had a very similar problem, which I finally managed to solve by defining a colorbar axes in a similar fashion to: Multiple imshow-subplots, each with colorbar

The advantage compared to mdurant's answer is that it saves defining the axes location manually.

import matplotlib.pyplot as plt
import IPython.display as display
from mpl_toolkits.axes_grid1 import make_axes_locatable
from pylab import *
%matplotlib inline

def plot_res(ax,cax):
    plotted=ax.imshow(rand(10, 10))
    cbar=plt.colorbar(mappable=plotted,cax=cax)

fig, axarr = plt.subplots(2, 2)
cax1 = make_axes_locatable(axarr[0,0]).append_axes("right", size="10%", pad=0.05)
cax2 = make_axes_locatable(axarr[0,1]).append_axes("right", size="10%", pad=0.05)
cax3 = make_axes_locatable(axarr[1,0]).append_axes("right", size="10%", pad=0.05)
cax4 = make_axes_locatable(axarr[1,1]).append_axes("right", size="10%", pad=0.05)
# plt.subplots_adjust(left=0, bottom=0, right=1, top=1, wspace=0.3, hspace=0.3)
N=10
for j in range(N):
    plot_res(axarr[0,0],cax1)
    plot_res(axarr[0,1],cax2)
    plot_res(axarr[1,0],cax3)
    plot_res(axarr[1,1],cax4)
    display.clear_output(wait=True)
    display.display(plt.gcf())
display.clear_output(wait=True)
Community
  • 1
  • 1
kenissur
  • 171
  • 1
  • 2
  • 7