удалить панель цветов из рисунка в 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, оси подзаголовков не освобождают пространство и вызывают 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)
У кого-нибудь есть какие-либо предложения?
Очень признателен! Адам
8 ответов:
Я думаю, что проблема в том, что с помощью
del
вы отменяете переменную, но не ссылаетесь на объект colorbar. Если вы хотите, чтобы цветовая панель была удалена из графика и исчезла, вы должны использовать методremove
экземпляра colorbar, и для этого вам нужно иметь цветовую панель в переменной, для которой у вас есть два варианта:
- удержание цветовой полосы в значении в момент создания, как показано в других ответах, например
cb=plt.colorbar()
- извлеките существующую цветовую панель, что вы можете сделать ниже (и upvoting :)) то, что я написал здесь: Как получить экземпляр colorbar из figure в 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 () и 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)
У меня была похожая проблема, и я немного поиграл. Я придумал два решения, которые могли бы быть немного более элегантными:
Очистите всю фигуру и снова добавьте подзаголовок (+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 команды: plot, изображение, разброс, коллекция и др. например:
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()
Созданная цветовая панель будет иметь тот же размер, что и рисунок или подзаголовок, и вы можете изменить ее ширину , расположение, заполнение при использовании разделителя .команда 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, очищает его и рисует новый график контура с помощью new colorbar на том же рисунке.
С помощью
cb.ax
я могу идентифицировать оси цветовых полос и очистить старую цветовую полосу. А указаниеcax=cb.ax
просто рисует новую цветовую панель в старых осях цветовых панелей.
Мне нужно было удалить colorbars, потому что я строил pcolormesh и добавлял colorbar к фигуре в цикле. Каждый цикл будет создавать новую цветовую панель, и после десяти циклов у меня будет десять цветовых панелей. Это было плохо.
Чтобы удалить colorbars, я называю pcolormesh и 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()
Опять же, необходимо было удалить colorbar перед pcolormesh