remove colorbar from figure in matplotlib

后端 未结 9 512
终归单人心
终归单人心 2020-12-08 14:14

This should be easy but I\'m having a hard time with it. Basically, I have a subplot in matplotlib that I\'m drawing a hexbin plot in every time a function is called, but ev

相关标签:
9条回答
  • 2020-12-08 14:46

    I think the problem is that with del you cancel the variable, but not the referenced object colorbar. If you want the colorbar to be removed from plot and disappear, you have to use the method remove of the colorbar instance and to do this you need to have the colorbar in a variable, for which you have two options:

    1. holding the colorbar in a value at the moment of creation, as shown in other answers e.g. cb=plt.colorbar()
    2. retrieve an existing colorbar, that you can do following (and upvoting :)) what I wrote here: How to retrieve colorbar instance from figure in matplotlib then:

    cb.remove() plt.draw() #update plot

    0 讨论(0)
  • 2020-12-08 14:47

    If you have a matplotlib figure object you just need to do fig.delaxes(fig.axes[1])

    For example:

    Plot with colorbar

    import matplotlib.pyplot as plt
    
    # setup some generic data
    N = 37
    x, y = np.mgrid[:N, :N]
    Z = (np.cos(x*0.2) + np.sin(y*0.3))
    
    # mask out the negative and positive values, respectively
    Zpos = np.ma.masked_less(Z, 0)
    Zneg = np.ma.masked_greater(Z, 0)
    
    fig, ax1 = plt.subplots(figsize=(13, 3), ncols=1)
    
    # plot just the positive data and save the
    # color "mappable" object returned by ax1.imshow
    pos = ax1.imshow(Zpos, cmap='Blues', interpolation='none')
    
    # add the colorbar using the figure's method,
    # telling which mappable we're talking about and
    # which axes object it should be near
    fig.colorbar(pos, ax=ax1)
    

    Remove colorbar

    import matplotlib.pyplot as plt
    
    # setup some generic data
    N = 37
    x, y = np.mgrid[:N, :N]
    Z = (np.cos(x*0.2) + np.sin(y*0.3))
    
    # mask out the negative and positive values, respectively
    Zpos = np.ma.masked_less(Z, 0)
    Zneg = np.ma.masked_greater(Z, 0)
    
    fig, ax1 = plt.subplots(figsize=(13, 3), ncols=1)
    
    # plot just the positive data and save the
    # color "mappable" object returned by ax1.imshow
    pos = ax1.imshow(Zpos, cmap='Blues', interpolation='none')
    
    # add the colorbar using the figure's method,
    # telling which mappable we're talking about and
    # which axes object it should be near
    fig.colorbar(pos, ax=ax1)
    
    fig.delaxes(fig.axes[1])
    

    0 讨论(0)
  • 2020-12-08 14:51

    Alright, here's my solution. Not terribly elegant, but not a terrible hack either.

    def foo(self):
       self.subplot.clear()
       hb = self.subplot.hexbin(...)
       if self.cb:
          self.figure.delaxes(self.figure.axes[1])
          self.figure.subplots_adjust(right=0.90)  #default right padding
       self.cb = self.figure.colorbar(hb)
    

    This works for my needs since I only ever have a single subplot. People who run into the same problem when using multiple subplots or when drawing the colorbar in a different position will need to tweak.

    0 讨论(0)
  • 2020-12-08 14:59

    I needed to remove colorbars because I was plotting a pcolormesh and adding colorbar to a figure in a loop. Each loop would create a new colorbar and after ten loops I would have ten colorbars. That was bad.

    To remove colorbars, I name the pcolormesh and colorbar a variable, then at the end of my loop I remove each. It is important to remove the colorbar before removing the pcolormesh.

    Psudo Code:

     for i in range(0,10):
       p = plt.pcolormesh(datastuff[i])
       cb = plt.colorbar(p)
       plt.savefig('name_'+i)
    
       cb.remove()
       p.remove()
    

    Again, it was necessary to remove the colorbar before the pcolormesh

    0 讨论(0)
  • 2020-12-08 15:00

    I managed to solve the same issue using fig.clear() and display.clear_output()

    import matplotlib.pyplot as plt
    import IPython.display as display
    import matplotlib.tri as tri
    from pylab import *
    %matplotlib inline
    
    def plot_res(fig):
        ax=fig.add_axes([0,0,1,1])
        ax.set_xlabel("x")
        ax.set_ylabel('y')
        plotted=ax.imshow(rand(250, 250))
        ax.set_title("title")
        cbar=fig.colorbar(mappable=plotted)
        display.clear_output(wait=True)
        display.display(plt.gcf())
        fig.clear()
    
    fig=plt.figure()
    N=20
    for j in range(N):
        plot_res(fig)
    
    0 讨论(0)
  • 2020-12-08 15:02

    I had a similar problem and played around a little bit. I came up with two solutions which might be slightly more elegant:

    1. Clear the whole figure and add the subplot (+colorbar if wanted) again.

    2. If there's always a colorbar, you can simply update the axes with autoscale which also updates the colorbar.

    I've tried this with imshow, but I guess it works similar for other plotting methods.

    from pylab import *
    close('all') #close all figures in memory
    
    #1. Figures for fig.clf method
    fig1 = figure()
    fig2 = figure()
    cbar1=None
    cbar2=None
    data = rand(250, 250)
    
    def makefig(fig,cbar):
      fig.clf()
      ax = fig.add_subplot(111)
      im = ax.imshow(data)
      if cbar:
        cbar=None
      else:
        cbar = fig.colorbar(im)
      return cbar
    
    
    #2. Update method
    fig_update = figure()
    cbar3=None
    data_update = rand(250, 250)
    img=None
    
    def makefig_update(fig,im,cbar,data):
      if im:
        data*=2 #change data, so there is change in output (look at colorbar)
        #im.set_data(data) #use this if you use new array
        im.autoscale()
        #cbar.update_normal(im) #cbar is updated automatically
      else:
        ax = fig.add_subplot(111)
        im = ax.imshow(data)
        cbar=fig.colorbar(im)
      return im,cbar,data
    
    #Execute functions a few times
    for i in range(3):
      print i
      cbar1=makefig(fig1,cbar1)
      cbar2=makefig(fig2,cbar2)
      img,cbar3,data_update=makefig_update(fig_update,img,cbar3,data_update)
    cbar2=makefig(fig2,cbar2)
    
    fig1.show()
    fig2.show()
    fig_update.show()
    
    0 讨论(0)
提交回复
热议问题