【问题标题】:matplotlib plotting in loop, removing colorbar but whitespace remainsmatplotlib 在循环中绘图,删除颜色条但保留空白
【发布时间】:2015-12-03 14:40:47
【问题描述】:

我的代码(大致)是这样的:

更新:我已经用一些反映我的一般问题的实际模型代码重做了这个。此外,意识到颜色条的创建是在实际循环中,否则没有什么可以映射到的。很抱歉之前的代码,在工作日结束时绝望地输入它:)。

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

以前有没有人遇到过这个问题并设法解决它?希望这已经足够了 对于这个问题的想法,如果需要,我可以发布更多代码,但我认为如果我只是给出一个概述示例,那就不会那么混乱了。

谢谢。

【问题讨论】:

    标签: python matplotlib


    【解决方案1】:

    colorbar() 允许您明确设置要渲染到哪个轴 - 您可以使用它来确保它们始终出现在同一个位置,并且不会从另一个轴窃取任何空间。此外,您可以重置现有颜色条的.mappable 属性,而不是每次都重新定义它。

    带有显式轴的示例:

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

    【讨论】:

    • 嗨,我重做了上面的代码,让您可以重现我的问题(尽管可能希望将循环迭代减少数百次 :))。你能发布一些你在说什么的示例代码吗?
    • 干杯,这看起来对我有用,希望在星期一证明是真的:)!
    【解决方案2】:

    我遇到了一个非常相似的问题,我最终通过以类似的方式定义颜色条轴来解决这个问题: Multiple imshow-subplots, each with colorbar

    与 mdurant 的答案相比的优势在于它节省了手动定义轴位置。

    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)
    

    【讨论】: