удалить цветовой барьер с рисунка в matplotlib - PullRequest
23 голосов
/ 10 марта 2011

Это должно быть легко, но мне тяжело с этим.По сути, у меня есть подплот в 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)

У кого-нибудь есть предложения?

Очень ценю!Адам

Ответы [ 8 ]

20 голосов
/ 04 декабря 2015

Я думаю, что проблема в том, что с del вы отменяете переменную, но не указанную цветовую панель объекта. Если вы хотите, чтобы цветовая полоса была удалена из графика и исчезла, вы должны использовать метод remove экземпляра цветовой шкалы, и для этого вам нужно иметь цветную полосу в переменной, для которой у вас есть две опции:

  1. удержание цветовой шкалы в значении на момент создания, как показано в других ответах, например, cb=plt.colorbar()
  2. восстановить существующую цветовую панель, которую вы можете сделать, следуя (и голосуя :)), что я написал здесь: Как получить экземпляр цветовой панели из рисунка в matplotlib то:

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

9 голосов
/ 10 марта 2011

Хорошо, вот мое решение. Не очень элегантно, но и не страшно.

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)

Это работает для моих нужд, так как у меня только один участок. Людям, которые сталкиваются с одной и той же проблемой при использовании нескольких вспомогательных участков или при рисовании цветовой шкалы в другом положении, потребуется настроить.

4 голосов
/ 25 ноября 2015

Мне удалось решить ту же проблему, используя 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)
3 голосов
/ 27 мая 2013

У меня была похожая проблема, и я немного поиграл. Я придумал два решения, которые могли бы быть немного более элегантными:

  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()
1 голос
/ 20 ноября 2017

Не хочу ничего отнимать у автора этого сообщения в блоге (Джозеф Лонг), но это, безусловно, лучшее решение, которое я нашел до сих пор. Он включает в себя фрагменты кода, отличные объяснения и множество примеров.

Подводя итог, с любого выхода оси ax команды: plot , image , scatter , коллекция и т. д., например:

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

Созданная цветовая панель будет иметь тот же размер, что и рисунок или подзаговор, и вы можете изменить ее width , location , padding при использовании divr.append_axes команда.

0 голосов
/ 06 октября 2016

Мне нужно было удалить цветные полосы, потому что я рисовал pcolormesh и добавлял цветные полосы к фигуре в цикле. Каждый цикл будет создавать новую цветовую панель, и после десяти циклов у меня будет десять цветных полос. Это было плохо.

Чтобы удалить цветные полосы, я называю переменную pcolormesh и colorbar переменной, затем в конце цикла я удаляю каждую. Важно удалить цветную полосу до удаления 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

0 голосов
/ 03 ноября 2014

«on_mappable_changed» сработало в моем случае.Однако, согласно документам, метод «Обычно ... не следует вызывать вручную».

if self.cb:
    self.cb.on_mappable_changed(hb)
else:
    self.cb = self.fig.colorbar(hb)
0 голосов
/ 26 августа 2014

Я использую 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 просто рисует новую цветовую панель по осям старой цветной панели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...