簡體   English   中英

從 matplotlib 中的圖形中刪除顏色條

[英]remove colorbar from figure in matplotlib

這應該很容易,但我很難做到。 基本上,我在 matplotlib 中有一個子圖,每次調用函數時我都會在其中繪制一個十六進制圖,但是每次調用該函數時我都會得到一個新的顏色條,所以我真正想做的是更新顏色條. 不幸的是,這似乎不起作用,因為顏色條附加到的對象正在由 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)

有沒有人有什么建議?

非常感激! 亞當

我認為問題在於使用del取消變量,而不是引用的對象顏色條。 如果要從繪圖中刪除顏色條並消失,則必須使用顏色條實例的remove方法,為此,您需要將顏色條置於變量中,對此您有兩個選擇:

  1. 在創建時將cb=plt.colorbar()保持在一個值中,如其他答案所示,例如cb=plt.colorbar()
  2. 檢索現有的顏色條,您可以執行以下操作(並投票:))我在這里寫的內容: How to retrieve colorbar instance from figure in matplotlib then:

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

好的,這是我的解決方案。 不是非常優雅,但也不是一個可怕的黑客。

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)

這適合我的需要,因為我只有一個子圖。 在使用多個子圖或在不同位置繪制顏色條時遇到相同問題的人需要進行調整。

我設法使用 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)

我有一個類似的問題,玩了一點。 我想出了兩個可能更優雅的解決方案:

  1. 清除整個圖形並再次添加子圖(如果需要,請添加顏色條)。

  2. 如果總是有一個顏色條,您可以簡單地使用自動縮放更新軸,這也會更新顏色條。

我已經用 imshow 嘗試過這個,但我想它對其他繪圖方法的工作方式類似。

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

我需要刪除顏色條,因為我正在繪制 pcolormesh 並將顏色條添加到循環中的圖形中。 每個循環都會創建一個新的顏色條,十個循環后我會有十個顏色條。 那很糟糕。

要刪除顏色條,我將 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 之前刪除顏色條

如果你有一個 matplotlib 圖形對象,你只需要執行fig.delaxes(fig.axes[1])

例如:

用顏色條繪圖

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)

在此處輸入圖片說明

刪除顏色條

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

在此處輸入圖片說明

我正在使用 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我能夠識別cb.ax軸並清除舊的顏色條。 並且指定cax=cb.ax只是在舊的cax=cb.ax繪制新的cax=cb.ax

不想從這篇博文(Joseph Long)的作者那里拿走任何東西,但這顯然是我迄今為止找到的最好的解決方案。 它包括代碼片段、很好的解釋和許多示例。

總而言之,從命令的軸ax的任何輸出: plotimagescattercollection等,例如:

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

創建的顏色條將與圖形或子圖具有相同的大小,您可以在使用divider.append_axes命令時修改它的寬度位置填充

我的解決方案包括擁有一個軸,其唯一目的是保持顏色條,並在需要時完全清除它。

例如,定義一次:

figure, ax = plt.subplots() # All the plotting is done on `ax`.
cax = ax.inset_axes([1.03, 0, 0.1, 1], transform=ax.transAxes) # Colorbar is held by `cax`. 

然后根據需要多次執行此操作:

cax.clear()
colorbar = figure.colorbar(mpl.cm.ScalarMappable(norm=norm, cmap=cmap),
                           ax=ax,
                           cax=cax,
                           **kwargs)

在此處輸入圖片說明

“on_mappable_changed”在我的情況下有效。 但是,根據文檔,該方法“通常......不應手動調用”。

if self.cb:
    self.cb.on_mappable_changed(hb)
else:
    self.cb = self.fig.colorbar(hb)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM