¿Cómo vuelvo a dibujar solo un conjunto de ejes en una figura en python?

Tengo varias parcelas en una figura usando subparcela. Cada instancia de ejes se utiliza para hacer referencia a un conjunto específico de ejes. Al igual que:

ax[0] = fig.add_subplot(2, 2, 1)
ax[1] = fig.add_subplot(2, 1, 2)
ax[2] = fig.add_subplot(2, 2, 2,projection='3d')

Como puede ver, uno de mis conjuntos de ejes es un gráfico en 3D. Realizo un cambio en una de las propiedades de las otras parcelas así:

plt.setp(zh, xdata=event.xdata,ydata=event.ydata)

y volver a dibujar así:

zh.figure.canvas.draw();

Sin embargo, esto es volver a dibujar la figura COMPLETA con todas las subtramas, incluida la proyectada en 3D, lo que está ralentizando las cosas de manera significativa.

He intentado esto:

ax[0].draw_artist(zh)

Lo cual pensé que era prometedor, pero los ejes no se están actualizando. No recibo un error, simplemente no se está redibujando. También probé:

zh.axes.draw(zh,ax[0])

pero eso da el error:

AttributeError: 'Line2D' object has no attribute 'open_group'

¿Alguna idea de por qué sucede esto y cómo puedo volver a dibujar la instancia de los ejes que estoy cambiando en lugar de la figura completa?

EDIT:

zh es un objeto Line2D:

zh, = plt.plot(z.real, z.imag, 'x', ms=10)

preguntado el 12 de junio de 12 a las 19:06

por favor se un poco mas especifico - ¿Qué biblioteca en particular estás usando para dibujar esto? ¿Matplotlib, numpy, PyX, etc.? -

El uso de setp y Line2D marca esto como Matplotlib, diría yo. Agregué una etiqueta, el OP puede corregir si fue una suposición incorrecta. -

Martijn tiene razón, estoy usando matplotlib. -

podrías explicar que zh es ? -

zh es un objeto line2D. ver editar. -

1 Respuestas

No puede dibujar un solo eje, pero puede actualizar solo un solo eje.

Básicamente, necesitas blit cosas. Si el rango (y por lo tanto los ticks, etc.) de los ejes está cambiando, esto se vuelve más complicado. Por el momento, asumiré que no es el caso.

Como un ejemplo demasiado simplificado:

import matplotlib.pyplot as plt
import numpy as np

plt.ion()
x = np.linspace(0, 4*np.pi, 100)
fig, axes = plt.subplots(nrows=3)

fig.canvas.draw()
background = fig.canvas.copy_from_bbox(axes[0].bbox)

lines = [ax.plot(x, np.cos(x))[0] for ax in axes]
fig.canvas.draw()

for phase in range(1000):
    fig.canvas.restore_region(background)
    lines[0].set_ydata(np.cos(x + phase / 5.0))
    axes[0].draw_artist(lines[0])
    fig.canvas.blit(axes[0].bbox)

Sin embargo, el nuevo matplotlib.animations se encargará de hacer esto por ti, y solo bloqueará los ejes de los artistas que especifiques.

Aquí está el mismo ejemplo escrito usando matplotlib.animations.FuncAnimation:

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import numpy as np

x = np.linspace(0, 4*np.pi, 100)
fig, axes = plt.subplots(nrows=3)

lines = [axes[0].plot(x, np.cos(x), animated=True)[0]]
lines += [ax.plot(x, np.cos(x)) for ax in axes[1:]]

class Update(object):
    def __init__(self, line):
        self.phase = 0
        self.line = line
    def __call__(self, _):
        self.line.set_ydata(np.cos(x + self.phase / 5.0))
        self.phase += 1.0
        return [self.line]

anim = FuncAnimation(fig, Update(lines[0]), interval=0, blit=True) 
plt.show()

Los artistas que se animan (y los ejes que se actualizan) están controlados por los artistas que devuelve la función (o el objeto invocable, como en este caso).

Respondido el 13 de junio de 12 a las 21:06

Gracias por esta respuesta integral, realmente me diste un buen código para masticar. Terminé moviendo el gráfico 3D de la figura a su propio, solo para simplificar las cosas (y tenía un plazo bastante ajustado), pero estoy muy interesado en hacer que esto funcione usando el método anterior. - Stanri

¿Hay alguna forma de cambiar el color de fondo de una subparcela? - skjerns

@JoeKington, ¿le importaría ampliar la respuesta para incluir el caso en el que los rangos de datos varían, por favor? Estoy seguro de que ayudaría a muchas personas. - Guimoute

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.