У чому різниця між малюванням ділянок за допомогою сюжету, осей або фігури в matplotlib?


100

Я трохи заплутаний у тому, що відбувається в серверній панелі, коли малюю графіки в 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. У чому різниця між усіма трьома, я маю на увазі те, що відбувається під капотом, коли викликається будь-який з 3 методів?

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


8
Я це вже читав, але відповідь взагалі не знайшов задовільною. Це пояснює ієрархію, але також викликає плутанину, чому не існує звичайного способу, чому фігура-предмет навіть виставляється?
hashcode55

Я не впевнений, що ви вказали саме цю документацію matplotlib.org/users/artists.html . Це відповідає на ваше запитання, чому фігура взагалі оголена. Особисто це найкраще пояснення matplotlib, яке я знайшов. Об'єкт "Рисунок" дозволяє додавати власних виконавців безпосередньо без осей, хоча це використовується рідко, якщо ви не хочете налаштувати "патч" самої фігури тощо. Зверніть увагу, що рисунок є батьківським контейнером і містить осі та виконавці.
Сандіп

Відповіді:


54

Спосіб 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.
Хенді

34

Назви предметів

Matplotlib є сильно об'єктно-орієнтованим, і його основними об'єктами є фігура та осі (я вважаю назву axesтрохи оманливою, але, мабуть, це лише я).

Ви можете уявити малюнок як полотно , для якого ви зазвичай вказуєте розміри і, можливо, наприклад, колір тла тощо. Ви використовуєте полотно, рисунок , по суті, двома способами, розміщуючи на ньому інші предмети (переважно осі , але також текстові мітки тощо) та збереження його вмісту за допомогою savefig.

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

pltінтерфейс

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

У кожен момент ви можете мати дескриптор цих прихованих об'єктів за допомогою plt.gcfта plt.gca, і це іноді потрібно, коли один із методів об'єкта не був перенесений на метод у просторі імен plt .

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

Ваші приклади

1-й спосіб

plt.plot(x, y)

Тут ви використовуєте лише інтерфейс plt , ви можете використовувати лише одні осі на кожному малюнку , але це те, що ви хочете, коли ви проводите дослідження ваших даних, швидкий рецепт, який дозволяє виконати роботу ...

2-й спосіб

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

Тут ви використовуєте зручний метод у просторі імен 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магічною командою, а також у контексті дослідницького блокнота Юпітера.

З іншого боку, об’єктно-орієнтований підхід, а також кілька plt зручних методів - це шлях

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

Між цими крайнощами є велика сіра зона, і якщо ви запитаєте мене, що робити, я просто скажу "Це залежить" ...


2
"Я вважаю осі назв дещо оманливими, але, мабуть, це лише я" - ні, це теж я. Неможливо змінити.
Laryx Decidua,

1
Інша річ, яку я просто не можу зрозуміти, чому люди використовують fig, ax = plt.subplot()ідіому, коли не хочуть підзаголовків. У таких випадках мені було простіше "процедурний" стиль. "Але, мабуть, це лише я ..." :-)
Laryx Decidua

@LaryxDecidua Я бачу одразу дві вагомі причини ① "Явний краще, ніж неявний" ② ви хочете використовувати методи Рисунка чи Осі, які недоступні в процедурному API, - але, можливо, є й інші ...
gboffi

Так, я повністю підписуюсь на 1). Щодо 2): більшості випадків достатньо процедурного API. Зрештою, я думаю, це зводиться до особистих уподобань - з приводу чого не варто сперечатися :-)
Laryx Decidua
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.