В чем разница между рисованием графиков с использованием графика, осей или фигуры в matplotlib?

101

Я немного смущен тем, что происходит на бэкэнде, когда я рисую графики в matplotlib, tbh, я не понимаю иерархию сюжета, осей и фигуры. Я прочитал документацию, и это было полезно, но я все еще не понимаю ...

Приведенный ниже код рисует один и тот же сюжет тремя разными способами:

#creating the arrays for testing
x = np.arange(1, 100)
y = np.sqrt(x)
#1st way
plt.plot(x, y)
#2nd way
ax = plt.subplot()
ax.plot(x, y)
#3rd way
figure = plt.figure()
new_plot = figure.add_subplot(111)
new_plot.plot(x, y)

Теперь мой вопрос -

  1. В чем разница между всеми тремя, я имею в виду, что происходит под капотом при вызове любого из трех методов?

  2. Какой метод следует использовать, когда и каковы плюсы и минусы использования любого из них?

хэш-код55
источник
8
Я уже читал это, но я не нашел ответ удовлетворительным. Это объясняет иерархию, но также вызывает недоумение: почему нет обычного способа, почему объект-фигура вообще открыт?
hashcode55
Я не уверен, ссылались ли вы именно на эту документацию matplotlib.org/users/artists.html . Это отвечает на ваш вопрос, почему фигура вообще выставлена. Лично это лучшее объяснение matplotlib, которое я нашел. Объект Figure позволяет вам добавлять ваших собственных художников напрямую без осей, хотя это редко используется, если вы не хотите настраивать «патч» самой фигуры и т. Д. Обратите внимание, что figure является родительским контейнером и содержит оси и художников.
Sandeep

Ответы:

55

Способ 1

plt.plot(x, y)

Это позволяет построить только одну фигуру с координатами (x, y). Если вы хотите получить только одно изображение, вы можете использовать этот способ.

Способ 2

ax = plt.subplot()
ax.plot(x, y)

Это позволяет отображать одну или несколько фигур в одном окне. Когда вы его напишете, вы построите только одну фигуру, но вы можете сделать что-то вроде этого:

fig1, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2)

Вы построите 4 фигуры с именами ax1, ax2, ax3 и ax4 каждая, но в одном окне. В моем примере это окно будет разделено на 4 части.

Способ 3

fig = plt.figure()
new_plot = fig.add_subplot(111)
new_plot.plot(x, y)

Не использовал, но документацию можно найти.

Пример:

import numpy as np
import matplotlib.pyplot as plt

# Method 1 #

x = np.random.rand(10)
y = np.random.rand(10)

figure1 = plt.plot(x,y)

# Method 2 #

x1 = np.random.rand(10)
x2 = np.random.rand(10)
x3 = np.random.rand(10)
x4 = np.random.rand(10)
y1 = np.random.rand(10)
y2 = np.random.rand(10)
y3 = np.random.rand(10)
y4 = np.random.rand(10)

figure2, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2)
ax1.plot(x1,y1)
ax2.plot(x2,y2)
ax3.plot(x3,y3)
ax4.plot(x4,y4)

plt.show()

введите описание изображения здесь введите описание изображения здесь

Другой пример:

введите описание изображения здесь

Эссекс
источник
@ hashcode55 каждая цифра независима. Я покажу вам пример
Эссекс
1
@ hashcode55 Я отредактирую на примере (просто цифра из моих исследований в астрофизике, сценарий слишком длинный (1300 строк));) Каждая цифра независима;)
Эссекс
3
Я знаю, что это мелочь, но я делаю это, потому что matplotlibязык сбивал меня с толку, и этот вопрос появляется при поиске «оси против фигуры в matplotlib». Для других новичков этот вопрос помог ответить на этот вопрос . Я думаю, что формулировка здесь может быть более ясной, что subplots()вернет Axesобъекты на сингле figure.
Hendy
35

Имена предметов

Matplotlib строго объектно-ориентирован, и его основными объектами являются фигура и оси (я считаю, что название axesнемного вводит в заблуждение, но, вероятно, это только я).

Вы можете думать о фигуре как о холсте , для которого вы обычно указываете размеры и, возможно, цвет фона и т.д. и т. Д. Вы используете холст, фигуру , по существу, двумя способами, размещая на ней другие объекты (в основном оси , но также текстовые метки и т. д.) и сохраняя его содержимое с помощью savefig.

Вы можете думать о топоре как о швейцарском армейском ноже, удобном предмете, который предлагает инструмент (например .plot, .scatterи .histт. Д.) Для всего, в основном. Вы можете разместить одну, две, ... много осей внутри фигуры, используя один из множества различных методов.

pltинтерфейс

Рх процедурный интерфейс был первоначально разработан , чтобы имитировать интерфейс MATLAB ™ , но на самом деле не отличается от интерфейса объектно - ориентированным, даже если вы не сделаете прямую ссылку на основные объекты (то есть, фигура и Ан оси ) эти объекты создается автоматически, и каждый метод plt , по сути, транслируется в вызов одного из методов базовых фундаментальных объектов: например, a plt.plot()- это, hidden_axes.plotа a plt.savefig- это hidden_figure.savefig.

В любой момент вы можете управлять этими скрытыми объектами с помощью plt.gcfи plt.gca, и это иногда необходимо, когда один из методов объекта не был перенесен в метод в пространстве имен plt .

Я хотел бы добавить, что пространство имен plt также содержит ряд удобных методов для создания экземпляров фигур и осей разными способами .

Ваши примеры

1-й способ

plt.plot(x, y)

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

2-й способ

ax = plt.subplot()
ax.plot(x, y)

Здесь вы используете удобный метод в пространстве имен plt, чтобы дать имя (и дескриптор) вашему объекту осей , но, кстати, есть также скрытая фигура . Позже вы можете использовать объект оси для построения графика, построения гистограммы и т.д., всего, что вы можете делать с интерфейсом plt , но вы также можете получить доступ ко всем его атрибутам и изменить их с большей свободой.

3-й способ

figure = plt.figure()
new_plot = figure.add_subplot(111)
new_plot.plot(x, y)

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

Можно обойти удобный метод plt ( matplotlib.figure.Figure), но затем вам придется настроить фигуру для лучшего интерактивного взаимодействия (в конце концов, это удобный метод).

Персональные рекомендации

Я предлагаю голый plt.plot, plt.scatterв контексте интерактивного сеанса, возможно, использовать IPython с его %matplotlibволшебной командой, а также в контексте исследовательской записной книжки Jupyter.

С другой стороны, объектно-ориентированный подход плюс несколько plt удобных методов - это лучший вариант.

  • если у вас есть постоянная проблема, которую нужно решить раз и навсегда с помощью индивидуализированного набора точно настроенных подзаголовков,
  • если вы хотите встроить Matplotlib в пользовательский интерфейс программы, которую вы пишете.

Между этими крайностями есть большая серая зона, и если вы спросите меня, что делать, я просто скажу: «Это зависит от обстоятельств» ...

gboffi
источник
2
«Я считаю, что названия топоров немного вводят в заблуждение, но, вероятно, это только я» - нет, это тоже я. Однако изменить нельзя.
Laryx Decidua
1
Другое дело, что я просто не могу понять, почему люди используют fig, ax = plt.subplot()идиому, когда им не нужны подсюжеты. В таких случаях мне было проще "процедурный" стиль. «Но, наверное, это только я ...» :-)
Laryx Decidua
@LaryxDecidua Я сразу вижу две веские причины ① «Явное лучше, чем неявное» ② вы хотите использовать методы Figure или Axes, которые недоступны в процедурном API - но, возможно, есть и другие…
gboffi
Да, полностью подписываюсь под 1). К вопросу 2): в большинстве случаев достаточно процедурного API. В конце концов, я думаю, что все сводится к личным предпочтениям - о чем не стоит спорить :-)
Laryx Decidua