Как я могу обновить фигуру после изменения осей объекта в Matplotlib?

См. приведенный ниже пример. Добавляются два подграфика, и в каждый вставляется график Line2D. Затем я изменяю оси Line2D во втором подграфике, чтобы он был первым подграфиком. Судя по выходу get_geometry, это успешно. Однако на фактическом рисунке два графика Line2D все еще находятся на своих исходных подграфиках.

Что мне здесь не хватает? Как я могу обновить фигуру, чтобы отразить изменение осей?

Очевидно, что это довольно дебильный пример, реальное приложение носит скорее динамический характер.

Скрипт:

import matplotlib.pyplot as plt

fig = plt.figure()  
ax_1 = fig.add_subplot(2,1,1)
ax_2 = fig.add_subplot(2,1,2)
ax_1.plot([0,1,2],[0,1,2])
ax_2.plot([0,1,2],[2,1,0])

print 'before'
for line in ax_1.get_lines():
    print line.get_ydata()
    print line.get_axes().get_geometry()
    print id(line.get_axes())

for line in ax_2.get_lines():
    print line.get_ydata()
    print line.get_axes().get_geometry()
    print id(line.get_axes())

f = ax_2.get_lines()[0]
f.set_axes(ax_1)

print 'after'
for line in ax_1.get_lines():
    print line.get_ydata()
    print line.get_axes().get_geometry()
    print id(line.get_axes())

for line in ax_2.get_lines():
    print line.get_ydata()
    print line.get_axes().get_geometry()
    print id(line.get_axes())

plt.show()

Выход:

before
[0 1 2]
(2, 1, 1)
4330504912
[2 1 0]
(2, 1, 2)
4336262288
after
[0 1 2]
(2, 1, 1)
4330504912
[2 1 0]
(2, 1, 1)
4330504912

Вывод рисунка: Рисунок


person c00kiemonster    schedule 19.08.2011    source источник
comment
Чего вы пытаетесь достичь? может быть, есть лучший метод, чем рисовать линию на одном графике и переносить ее на другой?   -  person Eric O Lebigot    schedule 19.08.2011
comment
Как я уже сказал в исходном посте, приведенный выше пример глуп. Реальное приложение представляет собой графическое графическое приложение, которое немного сложнее, чем в примере. Однако независимо от приложения я не вижу смысла в функции set_axes, если она на самом деле ничего не меняет.   -  person c00kiemonster    schedule 19.08.2011
comment
Я думаю, что вам нужно axes.add_line(), но я пока не могу заставить его работать. До сих пор я создал новую линию, использовал update_from() для копирования f в эту новую строку, а затем добавил ее к другим осям. Это все еще не работает, но может быть для вашего приложения. Я не думаю, что это работает для меня, потому что я не думаю, что сплайны, используемые для создания линии, обновлены для новых осей, но я изучаю это....   -  person Yann    schedule 19.08.2011
comment
В настоящее время я копирую все данные (xydata) и метаданные (цвет, ширина линии и т. д.) из строки в старых осях. Затем я удаляю линию в старых осях и строю новую в новых осях (с извлеченными данными и метаданными линии). Я всегда делал это так. Затем буквально на днях я увидел set_axes в документах, но не могу заставить его работать (поскольку я предполагаю, что он должен работать). Возможно, я неправильно понял механику осей в matplotlib, но, насколько я вижу, я думаю, что это нелогичное поведение.   -  person c00kiemonster    schedule 20.08.2011


Ответы (2)


Я считаю, что одна проблема заключается в том, что ваши первые оси (ax_1) не имеют линии, которую вы хотите добавить (f) в свой список линий (ax_1.lines).

Вы можете «скопировать» строку со второго графика на первый с помощью

f = ax_2.lines.pop()  # Removes the line from the second plot
ax_1.plot(*f.get_data())  # Draws a new line in the first plot, but with the coordinates of the second line

(при таком способе f.set_axes(ax_1) делать явно не нужно). Другие аргументы для plot() можно использовать, чтобы также скопировать цвет и т. д., я думаю.

person Eric O Lebigot    schedule 19.08.2011
comment
Что ж, это просто еще один симптом той же проблемы, а именно то, что линия осей ax_2, f, не была изменена должным образом. После изменения осей оба объекта Line2D указывают на один и тот же объект осей. - person c00kiemonster; 19.08.2011
comment
@c00kiemonster: Не могли бы вы рассказать об этом подробнее? Я бы не ожидал, что f изменится на графике, пока он является частью ax_2.lines. Если вы хотите, чтобы он исчез, вам, вероятно, следует удалить его из ax_2.lines. - person Eric O Lebigot; 19.08.2011
comment
Но он не должен быть частью ax_2.lines, я изменил его оси на ax_1. Если я полностью неправильно понял matplotlib, разве обе строки не должны отображаться в одних и тех же осях (верхняя), если они имеют одни и те же оси? - person c00kiemonster; 19.08.2011
comment
В документации указано, что ось линии изменена (matplotlib.sourceforge.net/api/); это не говорит о том, что модифицируется сама ось. Это то, что вы наблюдаете. Однако я не уверен, каково типичное использование set_axis() в этих обстоятельствах (строка f остается в ax_2.lines, но указывает, что ее ось - ax_1, после вашего set_axis(): это кажется противоречивым…); Итак, я снял ваш вопрос. :) - person Eric O Lebigot; 19.08.2011
comment
Да я сам немного запутался, не совсем интуитивное поведение. Надеюсь, есть какой-нибудь гуру matplotlib, который может объяснить. - person c00kiemonster; 19.08.2011

Позже я разместил тот же вопрос здесь и это был ответ.

TL,DR Не поддерживается.

person c00kiemonster    schedule 30.08.2011