Иерархия в матплотлиб
Согласно этой статье, все в matplotlib
организован в иерархии. На вершине иерархии находится matplotlib
"среда конечного автомата", которая обеспечивается matplotlib.pyplot
модуль. На этом уровне простые функции используются для добавления элементов графика (линий, изображений, текста и т. Д.) К текущим осям на текущем рисунке. Следующий уровень в иерархии - это первый уровень объектно-ориентированного интерфейса, в котором pyplot
используется только для нескольких функций, таких как создание фигур, а пользователь явно создает и отслеживает объекты фигур и осей. На этом уровне пользователь использует pyplot
для создания фигур, и с помощью этих фигур можно создать один или несколько объектов осей. Эти объекты осей затем используются для большинства графических действий. Есть также другие термины, такие как рисунок, оси, оси, художник (есть хорошая картинка, которая объясняет все это, на упомянутой странице). В итоге:
- Все принадлежит
matplotlib.pyplot
модуль - Рисунок - отслеживает все дочерние топоры, совокупность "специальных" художников (названия, легенды фигур и т. Д.)
- Оси - область изображения с пространством данных - принадлежит рисунку
- Ось - строки, помечающие галочки (координаты x,y,z и т. Д.) - принадлежит осям
- Artist - все, что вы видите на рисунке (даже объекты Figure, Axes и Axis) - принадлежит Figure
Самый простой способ создать новую фигуру - это pyplot:
fig = plt.figure() # an empty figure with no axes
fig, ax_lst = plt.subplots(2, 2) # a figure with a 2x2 grid of Axes
Я часто видел, как эти два подхода взаимозаменяемы, и я надеялся, что они в основном эквивалентны. Но я не могу достичь того же результата, используя fig, ax = plt.subplots()
как я использую fig = plt.figure()
а также ax = fig.add_subplot(111, projection='3d')
Вот мои эксперименты, для plt.figure()
:
In [1]: from mpl_toolkits.mplot3d import Axes3D
In [2]: import matplotlib.pyplot as plt
In [3]: fig = plt.figure()
In [4]: ax = fig.add_subplot(111, projection='3d')
In [5]: fig
Out[5]: <matplotlib.figure.Figure at 0x7f8377ca0610>
In [6]: ax
Out[6]: <matplotlib.axes._subplots.Axes3DSubplot at 0x7f8377bfb310>
In [7]:
Вот мои эксперименты, для plt.subplots()
:
In [1]: from mpl_toolkits.mplot3d import Axes3D
In [2]: import matplotlib.pyplot as plt
In [3]: fig, ax = plt.subplots()
In [4]: fig
Out[4]: <matplotlib.figure.Figure at 0x7f3dcf96e710>
In [5]: ax
Out[5]: <matplotlib.axes._subplots.AxesSubplot at 0x7f3dced564d0>
In [6]:
Как вы можете видеть первый создает matplotlib.axes._subplots.Axes3DSubplot
объект в то время как второй создает matplotlib.axes._subplots.AxesSubplot
объект. Я искал через help(plt.subplots)
за projection
Ключевое слово, но я не нашел ничего. Поэтому я попытался использовать те же аргументы для plt.subplots
что касается fig.add_subplot
но я получаю следующую ошибку:
In [7]: fig, ax = plt.subplots(111, projection='3d')
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-7-a905adad48f5> in <module>()
----> 1 fig, ax = plt.subplots(111, projection='3d')
/usr/lib/python2.7/dist-packages/matplotlib/pyplot.pyc in subplots(nrows, ncols, sharex, sharey, squeeze, subplot_kw, gridspec_kw, **fig_kw)
1076 gridspec_kw = {}
1077
-> 1078 fig = figure(**fig_kw)
1079 gs = GridSpec(nrows, ncols, **gridspec_kw)
1080
/usr/lib/python2.7/dist-packages/matplotlib/pyplot.pyc in figure(num, figsize, dpi, facecolor, edgecolor, frameon, FigureClass, **kwargs)
433 frameon=frameon,
434 FigureClass=FigureClass,
--> 435 **kwargs)
436
437 if figLabel:
/usr/lib/python2.7/dist-packages/matplotlib/backends/backend_tkagg.pyc in new_figure_manager(num, *args, **kwargs)
78 """
79 FigureClass = kwargs.pop('FigureClass', Figure)
---> 80 figure = FigureClass(*args, **kwargs)
81 return new_figure_manager_given_figure(num, figure)
82
TypeError: __init__() got an unexpected keyword argument 'projection'
Вопрос:
Являются fig, ax = plt.subplots()
а также fig = plt.figure(); ax = fig.add_subplot(111, projection='3d')
эквиваленты, если да, как я могу использовать fig, ax = plt.subplots()
в моем примере?
На указанной странице также есть следующий код:
#!/bin/env python
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 2, 100)
# The first call to plt.plot will automatically create the necessary figure and axes to achieve the desired plot.
plt.plot(x, x, label='linear')
# Subsequent calls to plt.plot re-use the current axes and each add another line.
plt.plot(x, x**2, label='quadratic')
plt.plot(x, x**3, label='cubic')
# Setting the title, legend, and axis labels also automatically use the current axes and set the title, create the legend, and label the axis respectively.
plt.xlabel('x label')
plt.ylabel('y label')
plt.title("Simple Plot")
plt.legend()
plt.show()
Как видите, таких функций нет fig = plt.figure()
ни fig, ax_lst = plt.subplots(2, 2)
Вопрос:
Как поддерживается иерархия в этом примере, рисунок создан по умолчанию или что происходит?
1 ответ
Вопрос 1
Я думаю, вы сами показали, что команды не совсем эквивалентны, и просто хотите еще раз убедиться в этом.
Чтобы делать то, что вы хотите сделать - вы можете пройти в projection
к add_subplot()
вызовы, которые используются "под прикрытием" путем установки словаря аргументов подзаговора и передачи их, например,
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
subplot_args = {'projection':'3d'}
fig, ax = plt.subplots(subplot_kw=subplot_args)
Использование именованного аргумента subplot_kw
описано в документации здесь.
вопрос 2
Оси фигур и т. Д. Все создаются "под обложками" в начале первой строки plt.plot
, pyplot
Модуль поддерживает состояние и повторно использует один и тот же экземпляр фигуры и экземпляр осей, пока вы не вызовете plt.show()
,
Обратите внимание, что у вас нет дескриптора этих экземпляров. Вы всегда можете получить ручку, если хотите, например, позвонив
fig = plt.gcf()
а также
ax = plt.gca()
где gcf()
а также gca()
получить текущую фигуру и получить текущие оси соответственно. Это смоделировано на функциональности matlab, на которой изначально был основан matplotlib.
Если вы действительно хотите увидеть, как происходит автоматическое создание - все это с открытым исходным кодом. Вы можете увидеть звонок plot()
создает экземпляр Axes путем вызова gca()
в коде здесь. Это в свою очередь призывает gcf()
, который ищет FigureManager
(что на самом деле поддерживает государство). Если он существует, он возвращает фигуру, которой управляет, в противном случае он создает новую, используя plt.figure()
, Опять же, этот процесс в некоторой степени наследуется от Matlab, где первоначальный вызов обычно figure
перед любой операцией заговора.
добавление
Я думаю, что вы можете двигаться в том, как использовать matplotlib.pyplot
функции как plt.plot()
и т.д. дают вам доступ к иерархии, как описано в документации. Ответ в том, что если вы хотите действительно мелкозернистый контроль, то иногда это не так. Вот почему люди используют
fig, ax = plt.subplots()
шаблон или подобный, так что они имеют ручки для фигур и осей объектов напрямую и могут манипулировать ими, как им нравится.