Как я могу прикрепить функцию pyplot к экземпляру фигуры?

Ранее у меня была проблема с интерференцией между несколькими фигурами Matplotlib. Наконец, я обнаружил, что некоторые проблемы Pyplot не прикрепляются к экземпляру фигуры, но могут отображаться в некоторых других экземплярах рисунка, которые создаются параллельно.

Вот пример кода:

from django.http import HttpResponse
from numpy import arange, meshgrid
from matplotlib.mlab import bivariate_normal

def show_chart(request):
    delta = 0.025
    x = arange(-3.0, 3.0, delta)
    y = arange(-2.0, 2.0, delta)
    X, Y = meshgrid(x, y)
    Z1 = bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
    Z2 = bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
    Z = 10.0 * (Z2 - Z1)

    from matplotlib.pyplot import figure, contour
    fig1 = figure(figsize=(4, 4), facecolor='white')
    contour(X, Y, Z)

    response = HttpResponse(content_type='image/png')
    fig1.savefig(response, format='png')
    fig1.clear()
    return response

Функция контура pyplot в приведенном выше примере может отображаться на рис. 1, но иногда также на каком-то другом рисунке, который генерируется параллельно. Это очень раздражает. Есть ли способ прикрепить контурную функцию pyplot к fig1?

2 ответа

Решение

Вы можете создать участок и затем вызвать contour метод подзаговора:

fig1 = figure(figsize=(4, 4), facecolor='white')
ax = fig1.add_subplot(111)
ax.contour(X, Y, Z)

plt.subplots позволяет удобно создавать фигуры и сюжеты одним вызовом:

import matplotlib.pyplot as plt

fig, ax = plt.subplots()

В качестве небольшого объяснения того, что здесь происходит, matplotlib имеет два полунезависимых интерфейса; конечный автомат и интерфейс ОО.

Код конечного автомата предназначен для работы в интерактивной оболочке (и имитирует интерфейс Matlab). Это делается путем обертывания интерфейса OO в набор команд, которые отслеживают то, что текущий figure а также axes являются. Когда вы используете команду из matplotlib.pyplot (Я подозреваю, что у вас есть from matploblib.pyplot import * в вашем коде) в более или менее эквивалентно делать gcf().gca().contour(...), Когда вы создаете новую фигуру, она автоматически становится текущей (что вам нужно, если вы используете ее в итеративной оболочке), поэтому поведение, которое вы видите, является "правильным". Интерфейс конечного автомата также содержит код, который позволяет перерисовывать фигуры при необходимости, управлять циклами событий графического интерфейса и т. Д. (Все, что вам нужно сделать, чтобы интерактивный интерфейс работал плавно). Как Хайден упомянул в комментариях, работает ipython --pylab будет автоматически запускаться from matplotlib.pyplot import *, который дает вам очень хорошую интерактивную оболочку.

Интерфейс ОО предназначен для программного взаимодействия с matplotlib, То, что он добавляет в многословии (теперь вы должны выполнять большую часть работы конечного автомата), он компенсирует в ясности. В ОО-модели большинство (возможно, все) функций построения графиков связаны с Axes объекты ( doc) (так как с рисунком может быть связано несколько осей (например, для подсюжетов с использованием gridspec).

Альтернативный способ решить вашу проблему

ax = fig1.gca()

который будет захватывать текущие оси fig1, создавая, если это необходимо. Это может быть полезно, если вы отслеживаете объекты вашей фигуры, но не объекты вашей оси и хотите добавить другой график к фигуре.

Другие вопросы по тегам