удалить colorbar из рисунка в matplotlib
Это должно быть легко, но мне трудно с этим. В принципе, у меня есть подзаголовок в matplotlib, в котором я рисую график hexbin каждый раз, когда вызывается функция, но каждый раз, когда я вызываю функцию, я получаю новую цветовую панель, поэтому я действительно хотел бы обновить цветовую панель. К сожалению, это не работает, так как объект, к которому прикреплена цветовая панель, воссоздается подзаголовком.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)
Я сейчас в этом раздражающем месте, где я пытаюсь удалить оси colorbar в целом и просто воссоздать его. К сожалению, когда я удаляю оси colorbar, оси вложенных планов не восстанавливают пространство и вызывают self.сюжетная линия.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)
есть ли у кого-нибудь предложения?
высоко ценится! Адам!--3-->
8 ответов
Я думаю, проблема в том, что с del
вы отменяете переменную,но не связанную с объектом colorbar.
Если вы хотите, чтобы цветовая панель была удалена из графика и исчезла, вы должны использовать метод remove
экземпляра colorbar и для этого вам нужно иметь colorbar в переменной, для которой у вас есть два варианта:
- удержание цветовой полосы в значении в момент создания, как показано в других ответах, например
cb=plt.colorbar()
- загрузить существующую colorbar, что вы можете сделать следующее (и upvoting :)) то, что я написал здесь:Как получить экземпляр colorbar из рисунка в matplotlib затем:
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)
это работает для моих нужд, так как у меня есть только один подзаголовок. Люди, которые сталкиваются с одной и той же проблемой при использовании нескольких подзаголовков или при рисовании цветовой полосы в другом положении, должны будут настроить.
мне удалось решить ту же самую проблему, используя рис.очистить () и отобразить.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)
У меня была аналогичная проблема, и я немного поиграл. Я придумал два решения, которые могут быть немного более элегантно:
очистите всю фигуру и снова добавьте подзаголовок (+colorbar, если хотите).
Если всегда есть цветовая панель, вы можете просто обновить оси с помощью autoscale, который также обновляет цветовую панель.
Я пробовал это с 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()
не хочу ничего отнимать у автора этой блоге (Джозеф лонг) но это явно лучшее решение, которое я нашел до сих пор. Он включает в себя фрагменты кода, отличные объяснения и множество примеров.
подводя итог, из любого вывода оси ax команды: участка, изображения, разброс, коллекция, etc. например:
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)
вы создаете ось цветовой полосы, используя the 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()
созданная цветовая панель будет иметь тот же размер, что и рисунок или подзаголовок, и вы можете изменить ее ширина, расположение, обивка при использовании делитель.append_axes.
Я с использованием библиотек 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()
выше код рисует контур заполнить участок с colorbar, очистить его и нарисовать новый контур участок с новым colorbar на том же рисунке.
С помощью
cb.ax
я могу идентифицировать оси colorbar и очистить старую цветовую панель.
И уточнение cax=cb.ax
просто рисует новый colorbar в старых осях colorbar.
Мне нужно было удалить colorbars, потому что я строил pcolormesh и добавлял colorbar к фигуре в цикле. Каждый цикл создаст новую цветовую панель, и после десяти циклов у меня будет десять цветовых панелей. Это было плохо.
чтобы удалить colorbars, я называю pcolormesh и colorbar переменной, затем в конце моего цикла я удаляю каждый. Важно удалить colorbar до удаление pcolormesh.
Psudo Код:
for i in range(0,10):
p = plt.pcolormesh(datastuff[i])
cb = plt.colorbar(p)
plt.savefig('name_'+i)
cb.remove()
p.remove()
опять же, это необходимо было удалить цветовую панель перед pcolormesh
"on_mappable_changed" работал в моем случае. Однако, согласно документам, метод "обычно"... не следует вызывать вручную."
if self.cb:
self.cb.on_mappable_changed(hb)
else:
self.cb = self.fig.colorbar(hb)