Как удалить строки на графике Matplotlib

Как удалить линию (или линии) осей matplotlib таким образом, чтобы она фактически собирала мусор и освобождала память? Приведенный ниже код удаляет строку, но никогда не освобождает память (даже при явных вызовах gc.collect ())

from matplotlib import pyplot import numpy a = numpy.arange(int(1e7)) # large so you can easily see the memory footprint on the system monitor. fig = pyplot.Figure() ax = pyplot.add_subplot(1, 1, 1) lines = ax.plot(a) # this uses up an additional 230 Mb of memory. # can I get the memory back? l = lines[0] l.remove() del l del lines # not releasing memory ax.cla() # this does release the memory, but also wipes out all other lines. 

Так есть способ просто удалить одну строку из осей и вернуть память? Это потенциальное решение также не работает.

  • Как переписать строку на диаграмме рассеяния в python?
  • Радарная диаграмма с несколькими шкалами на нескольких осях
  • Как изменить цвет фона?
  • построение различных цветов в matplotlib
  • Python / Matplotlib - изменить относительный размер подзаголовка
  • Что означает аргумент 4-элементного кортежа для 'bbox_to_anchor' в matplotlib?
  • как явно построить ось y с помощью python
  • Создание штрих-диаграмм в Python
  • Контуры рассеянности в Matplotlib
  • создание графиков разметки matplotlib из dataframes в пандах Python
  • Как оживить упорядоченную по времени последовательность графиков matplotlib
  • Ошибка matplotlib.animation. Система не может найти указанный файл.
  • 4 Solutions collect form web for “Как удалить строки на графике Matplotlib”

    Я показываю, что комбинация lines.pop(0) l.remove() и del l делает трюк.

     from matplotlib import pyplot import numpy, weakref a = numpy.arange(int(1e3)) fig = pyplot.Figure() ax = fig.add_subplot(1, 1, 1) lines = ax.plot(a) l = lines.pop(0) wl = weakref.ref(l) # create a weak reference to see if references still exist # to this object print wl # not dead l.remove() print wl # not dead del l print wl # dead (remove either of the steps above and this is still live) 

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

    Разумеется, более простой способ (если не проблема) – вытащить его из списка и вызывать remove объекта линии без создания жесткой ссылки на него:

     lines.pop(0).remove() 

    Это очень длинное объяснение, которое я набрал для моего коллеги. Я думаю, что здесь было бы полезно. Будьте терпеливы. Я добираюсь до настоящего вопроса, который у вас есть к концу. Так же, как тизер, проблема Line2D с дополнительными ссылками на ваши объекты Line2D .

    ПРЕДУПРЕЖДЕНИЕ: Еще одно замечание перед тем, как мы погрузимся. Если вы используете IPython для проверки этого, IPython сохраняет ссылки самостоятельно, и не все из них являются слабыми. Таким образом, проверка сборки мусора в IPython не работает. Это просто путает вопросы.

    Хорошо, мы пойдем. Каждый объект matplotlib ( Figure , Axes и т. Д.) Предоставляет доступ к его дочерним исполнителям через различные атрибуты. Следующий пример довольно длинный, но должен быть освещен.

    Мы начинаем с создания объекта Figure , а затем добавляем объект Axes к этой фигуре. Обратите внимание, что ax и fig.axes[0] – это один и тот же объект (тот же id() ).

     >>> #Create a figure >>> fig = plt.figure() >>> fig.axes [] >>> #Add an axes object >>> ax = fig.add_subplot(1,1,1) >>> #The object in ax is the same as the object in fig.axes[0], which is >>> # a list of axes objects attached to fig >>> print ax Axes(0.125,0.1;0.775x0.8) >>> print fig.axes[0] Axes(0.125,0.1;0.775x0.8) #Same as "print ax" >>> id(ax), id(fig.axes[0]) (212603664, 212603664) #Same ids => same objects 

    Это также распространяется на линии в объекте осей:

     >>> #Add a line to ax >>> lines = ax.plot(np.arange(1000)) >>> #Lines and ax.lines contain the same line2D instances >>> print lines [<matplotlib.lines.Line2D object at 0xce84bd0>] >>> print ax.lines [<matplotlib.lines.Line2D object at 0xce84bd0>] >>> print lines[0] Line2D(_line0) >>> print ax.lines[0] Line2D(_line0) >>> #Same ID => same object >>> id(lines[0]), id(ax.lines[0]) (216550352, 216550352) 

    Если вы должны были вызвать plt.show() используя то, что было сделано выше, вы увидите фигуру, содержащую набор осей и одну строку:

    Фигура, содержащая набор осей и одну линию

    Теперь, хотя мы видим, что содержание lines и ax.lines одинаково, очень важно отметить, что объект, на который ссылается переменная lines не совпадает с объектом, почитаемым ax.lines что видно следующие:

     >>> id(lines), id(ax.lines) (212754584, 211335288) 

    Как следствие, удаление элемента из lines ничего не делает для текущего графика, но удаление элемента из ax.lines удаляет эту строку из текущего графика. Так:

     >>> #THIS DOES NOTHING: >>> lines.pop(0) >>> #THIS REMOVES THE FIRST LINE: >>> ax.lines.pop(0) 

    Итак, если бы вы Line2D вторую строку кода, вы удалили Line2D объект Line2D содержащийся в ax.lines[0] из текущего графика, и он исчезнет. Обратите внимание, что это также можно сделать с помощью ax.lines.remove() что означает, что вы можете сохранить экземпляр Line2D в переменной, а затем передать его ax.lines.remove() чтобы удалить эту строку, например:

     >>> #Create a new line >>> lines.append(ax.plot(np.arange(1000)/2.0)) >>> ax.lines [<matplotlib.lines.Line2D object at 0xce84bd0>, <matplotlib.lines.Line2D object at 0xce84dx3>] 

    Фигура, содержащая набор осей и двух линий

     >>> #Remove that new line >>> ax.lines.remove(lines[0]) >>> ax.lines [<matplotlib.lines.Line2D object at 0xce84dx3>] 

    Фигура, содержащая набор осей и только вторую строку

    Все вышеперечисленные работы для fig.axes так же хорошо, как и для ax.lines

    Теперь настоящая проблема здесь. Если мы сохраним ссылку, содержащуюся в ax.lines[0] в объект weakref.ref , а затем weakref.ref удалить ее, мы заметим, что она не получает сбор мусора:

     >>> #Create weak reference to Line2D object >>> from weakref import ref >>> wr = ref(ax.lines[0]) >>> print wr <weakref at 0xb758af8; to 'Line2D' at 0xb757fd0> >>> print wr() <matplotlib.lines.Line2D at 0xb757fd0> >>> #Delete the line from the axes >>> ax.lines.remove(wr()) >>> ax.lines [] >>> #Test weakref again >>> print wr <weakref at 0xb758af8; to 'Line2D' at 0xb757fd0> >>> print wr() <matplotlib.lines.Line2D at 0xb757fd0> 

    Ссылка все еще жива! Зачем? Это связано с тем, что есть еще одна ссылка на объект Line2D , на который указывает ссылка в wr . Помните, как lines не имели того же идентификатора, что и ax.lines но содержали одни и те же элементы? Ну, это проблема.

     >>> #Print out lines >>> print lines [<matplotlib.lines.Line2D object at 0xce84bd0>, <matplotlib.lines.Line2D object at 0xce84dx3>] To fix this problem, we simply need to delete `lines`, empty it, or let it go out of scope. >>> #Reinitialize lines to empty list >>> lines = [] >>> print lines [] >>> print wr <weakref at 0xb758af8; dead> 

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

    Я пробовал много разных ответов на разных форумах. Я думаю, это зависит от машины, которую вы развиваете. Но я согласился использовать заявление

     ax.lines = [] 

    и работает отлично. Я не использую cla (), потому что он удаляет все определения, которые я сделал для графика

    Ex.

     pylab.setp(_self.ax.get_yticklabels(), fontsize=8) 

    но я пробовал удалять строки много раз. Также, используя библиотеку weakref, чтобы проверить ссылку на эту строку, пока я удалялся, но ничего не работало для меня.

    Надеюсь, что это работает для кого-то другого = D

    (используя тот же пример, что и парень выше)

     from matplotlib import pyplot import numpy a = numpy.arange(int(1e3)) fig = pyplot.Figure() ax = fig.add_subplot(1, 1, 1) lines = ax.plot(a) for i, line in enumerate(ax.lines): ax.lines.pop(i) line.remove() 
    Python - лучший язык программирования в мире.