Как я могу (в Python) удалить художника matplotlib из сюжета с помощью блитинга?

Могу ли я удалить исполнителя matplotlib, например патч, с помощью блитинга?

    """Some background code:"""

    from matplotlib.figure import Figure
    from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas

    self.figure = Figure()
    self.axes = self.figure.add_subplot(111)
    self.canvas = FigureCanvas(self, -1, self.figure)

Чтобы добавить патч к графику matplotlib с помощью blit, вы можете сделать следующее:

    """square is some matplotlib patch"""

    self.axes.add_patch(square)
    self.axes.draw_artist(square)
    self.canvas.blit(self.axes.bbox)

Это работает. Однако могу ли я использовать blit, чтобы удалить этого же исполнителя из сюжета? Мне удалось удалить его с помощью square.remove(), и я могу обновить график с помощью функции self.canvas.draw(). Но, конечно, это медленно, и вместо этого я хотел бы использовать блиттинг.

    """square is some matplotlib patch"""

    square.remove()
    self.canvas.draw()

Не работает следующее:

    square.remove()
    self.canvas.blit(self.axes.bbox)

person Zwarte Viltstift    schedule 12.03.2018    source источник
comment
Не уверен, что правильно понял вопрос, но почему бы снова не засветить холст, только без квадрата?   -  person ImportanceOfBeingErnest    schedule 12.03.2018
comment
square.remove() и после этого self.canvas.blit(self.axes.bbox) не работает. Художник остается в сюжете.   -  person Zwarte Viltstift    schedule 12.03.2018


Ответы (1)


Идея удаления блит-объекта состоит в том, чтобы просто снова блитить ту же область, просто не отрисовывая объект заранее. Вы также можете удалить его, чтобы он также не был виден, если холст перерисовывается по какой-либо другой причине.

Кажется, в коде вопроса вы забыли позвонить restore_region. Полный набор команд, необходимых для копирования, см., например. этот вопрос.

Примером может служить следующий, где прямоугольник отображается, если вы щелкаете левой кнопкой мыши, и удаляется, если вы нажимаете правую кнопку.

import matplotlib.pyplot as plt
import numpy as np

class Test:
    def __init__(self):
        self.fig, self.ax = plt.subplots()
        # Axis with large plot
        self.ax.imshow(np.random.random((5000,5000)))
        # Draw the canvas once
        self.fig.canvas.draw()
        # Store the background for later
        self.background = self.fig.canvas.copy_from_bbox(self.ax.bbox)
        # create square
        self.square = plt.Rectangle([2000,2000],900,900, zorder=3, color="crimson")
        # Create callback to mouse movement
        self.cid = self.fig.canvas.callbacks.connect('button_press_event', 
                                                     self.callback)
        plt.show()

    def callback(self, event):
        if event.inaxes == self.ax:
            if event.button == 1:
                # Update point's location            
                self.square.set_xy((event.xdata-450, event.ydata-450))
                # Restore the background
                self.fig.canvas.restore_region(self.background)
                # draw the square on the screen
                self.ax.add_patch(self.square)
                self.ax.draw_artist(self.square)
                # blit the axes
                self.fig.canvas.blit(self.ax.bbox)
            else:
                self.square.remove()
                self.fig.canvas.restore_region(self.background)
                self.fig.canvas.blit(self.ax.bbox)

tt = Test()
person ImportanceOfBeingErnest    schedule 12.03.2018
comment
Спасибо! Просто реплицирование холста без квадрата работает. - person Zwarte Viltstift; 12.03.2018