복붙노트

[PYTHON] matplotlib의 Figure에서 colorbar 제거

PYTHON

matplotlib의 Figure에서 colorbar 제거

이것은 쉬워야하지만 나는 그걸로 힘든 시간을 보내고있다. 기본적으로 함수가 호출 될 때마다 hexbin 플롯을 그리는 matplotlib의 서브 플로트가 있습니다. 그러나 함수를 호출 할 때마다 새 colorbar가 생기므로 실제로 colorbar를 업데이트해야합니다. . 불행하게도이 작업은 colorbar가 붙어있는 객체가 subplot.hexbin에 의해 재 작성되기 때문에 효과가없는 것처럼 보입니다.

def foo(self):
   self.subplot.clear()
   hb = self.subplot.hexbin(...)
   if self.cb:
      self.cb.update_bruteforce() # Doesn't work (hb is new)
   else:
      self.cb = self.figure.colorbar(hb)

나는 컬러 바 축을 모두 지우고 다시 만들려고하는 성가신 곳입니다. 안타깝게도 컬러 막대 축을 삭제하면 서브 플롯 축이 공간을 다시 차지하지 않으므로 self.subplot.reset_position ()을 호출하면 생각했던대로 수행되지 않습니다.

def foo(self):
   self.subplot.clear()
   hb = self.subplot.hexbin(...)
   if self.cb:
      self.figure.delaxes(self.figure.axes[1])
      del self.cb
      # TODO: resize self.subplot so it fills the 
      #    whole figure before adding the new colorbar
   self.cb = self.figure.colorbar(hb)

누구든지 어떤 제안이 있습니까?

매우 감사! 아담

해결법

  1. ==============================

    1.문제는 del을 사용하면 변수를 취소하지만 참조 된 객체 colorbar는 취소하지 않는다고 생각합니다. 컬러 막대를 플롯에서 제거하여 사라지게하려면 colorbar 인스턴스의 remove 메서드를 사용해야하며 이렇게하려면 두 가지 옵션이있는 변수에 컬러 막대가 있어야합니다.

    문제는 del을 사용하면 변수를 취소하지만 참조 된 객체 colorbar는 취소하지 않는다고 생각합니다. 컬러 막대를 플롯에서 제거하여 사라지게하려면 colorbar 인스턴스의 remove 메서드를 사용해야하며 이렇게하려면 두 가지 옵션이있는 변수에 컬러 막대가 있어야합니다.

    cb.remove () plt.draw () # 업데이트 플롯

  2. ==============================

    2.좋아, 내 해결책이있어. 대단히 우아하지는 않지만 끔찍한 해킹도 아닙니다.

    좋아, 내 해결책이있어. 대단히 우아하지는 않지만 끔찍한 해킹도 아닙니다.

    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)
    

    이것은 오직 하나의 서브 플로트 만 가지고 있기 때문에 내 필요에 맞게 작동합니다. 여러 서브 플롯을 사용하거나 색상 막대를 다른 위치에 그리는 경우 같은 문제가 발생하는 사용자는 조정해야합니다.

  3. ==============================

    3.나는 fig.clear () 및 display.clear_output ()을 사용하여 동일한 문제를 해결할 수있었습니다.

    나는 fig.clear () 및 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)
    
  4. ==============================

    4.비슷한 문제가 있었고 조금 놀았습니다. 약간 더 우아 할 수있는 두 가지 해결책을 생각해 냈습니다.

    비슷한 문제가 있었고 조금 놀았습니다. 약간 더 우아 할 수있는 두 가지 해결책을 생각해 냈습니다.

    나는 이것을 imshow로 시도했지만, 다른 plotting 방법과 비슷하게 작동하는 것으로 생각됩니다.

    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()
    
  5. ==============================

    5.이 블로그 게시물 (Joseph Long)의 저자로부터 아무 것도 가져 가고 싶지는 않지만 지금까지 발견 한 솔루션 중 가장 분명합니다. 코드 조각, 훌륭한 설명 및 많은 예제가 포함되어 있습니다.

    이 블로그 게시물 (Joseph Long)의 저자로부터 아무 것도 가져 가고 싶지는 않지만 지금까지 발견 한 솔루션 중 가장 분명합니다. 코드 조각, 훌륭한 설명 및 많은 예제가 포함되어 있습니다.

    요약하면, 명령의 축 ax의 출력으로부터 : plot, image, scatter, collection 등 :

    import matplotlib.pyplot as plt
    fig = plt.figure(figsize=(5,5), dpi=300)
    ax = fig.add_subplot(1, 1, 1)
    
    data = ax.plot(x,y)
    # or
    data = ax.scatter(x, y, z)
    # or
    data = ax.imshow(z)
    # or 
    data = matplotlib.collection(patches)
    ax.add_collection(data)
    

    make_axes_locatable과 플롯의 원래 축을 사용하여 색상 막대 축을 만듭니다.

    from mpl_toolkits.axes_grid1 import make_axes_locatable
    
    # the magical part
    divider = make_axes_locatable(ax)
    caxis = divider.append_axes("right", size="5%", pad=0.05)
    fig.colorbar(data, cax=caxis)
    
    plt.show()
    

    만든 colorbar는 figure 또는 subplot과 같은 크기를 가지며 divider.append_axes 명령을 사용할 때 width, location, padding을 수정할 수 있습니다.

  6. ==============================

    6.matplotlib 1.4.0을 사용하고 있습니다. 이 문제를 해결하는 방법은 다음과 같습니다.

    matplotlib 1.4.0을 사용하고 있습니다. 이 문제를 해결하는 방법은 다음과 같습니다.

    import matplotlib
    import numpy as np
    import matplotlib.cm as cm
    import matplotlib.mlab as mlab
    import matplotlib.pyplot as plt
    
    # A contour plot example:
    delta = 0.025
    x = np.arange(-3.0, 3.0, delta)
    y = np.arange(-2.0, 2.0, delta)
    X, Y = np.meshgrid(x, y)
    Z1 = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
    Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
    Z = 10.0 * (Z2 - Z1)
    #
    
    # first drawing
    fig = plt.figure()
    ax = fig.add_subplot(111)  # drawing axes
    c = ax.contourf(Z)   # contour fill c
    cb = fig.colorbar(c)  # colorbar for contour c
    
    # clear first drawimg
    ax.clear()  # clear drawing axes
    cb.ax.clear()  # clear colorbar axes
    
    # replace with new drawing
    # 1. drawing new contour at drawing axes
    c_new = ax.contour(Z)  
    # 2. create new colorbar for new contour at colorbar axes
    cb_new = ax.get_figure().colorbar(c_new, cax=cb.ax) 
    
    plt.show()
    

    위의 코드는 컬러 막대가있는 윤곽 채우기 플롯을 그려서 지우고 동일한 그림에 새 색상 막대가있는 새 윤곽 플롯을 그립니다.

    사용하여     cb.ax 컬러 바 축을 식별하고 오래된 컬러 바를 지울 수 있습니다. 그리고 cax = cb.ax를 지정하면 새로운 색상 막대가 이전 색상 막대 축에 그려집니다.

  7. ==============================

    7.내가 pcolormesh를 계획하고 있었고 컬러 바를 루프의 그림에 추가했기 때문에 컬러 바를 제거해야했습니다. 각 루프는 새로운 색상 막대를 만들고 10 개의 고리 뒤에 10 개의 색상 막대가 생깁니다. 그것은 나빴다.

    내가 pcolormesh를 계획하고 있었고 컬러 바를 루프의 그림에 추가했기 때문에 컬러 바를 제거해야했습니다. 각 루프는 새로운 색상 막대를 만들고 10 개의 고리 뒤에 10 개의 색상 막대가 생깁니다. 그것은 나빴다.

    컬러 바를 제거하기 위해 pcolormesh와 컬러 바의 이름을 변수로 지정한 다음 루프의 끝에서 각각을 제거합니다. pcolormesh를 제거하기 전에 색상 막대를 제거하는 것이 중요합니다.

    의사 코드 :

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

    다시 말하지만, pcolormesh 전에 컬러 바를 제거해야했습니다.

  8. ==============================

    8."on_mappable_changed"가 제 경우에 효과가있었습니다. 그러나 문서에 따르면 "일반적으로 수동으로 호출해서는 안됩니다."라는 방법이 있습니다.

    "on_mappable_changed"가 제 경우에 효과가있었습니다. 그러나 문서에 따르면 "일반적으로 수동으로 호출해서는 안됩니다."라는 방법이 있습니다.

    if self.cb:
        self.cb.on_mappable_changed(hb)
    else:
        self.cb = self.fig.colorbar(hb)
    
  9. from https://stackoverflow.com/questions/5263034/remove-colorbar-from-figure-in-matplotlib by cc-by-sa and MIT license