Использование библиотеки Matplotlib. Применение объектно-ориентированного стиля

Немного рекламы

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

  1. #!/usr/bin/env python
  2. # -*- coding: UTF-8 -*-
  3.  
  4. import numpy
  5.  
  6. # Импортируем один из пакетов Matplotlib
  7. import pylab
  8.  
  9.  
  10. if __name__ == '__main__':
  11.     x = numpy.arange (0.0, 4 * numpy.pi, 0.01)
  12.     y = numpy.sin (x) * numpy.cos (3 * x)
  13.  
  14.     pylab.plot (x, y, '-k', label=u'y = f(x)')
  15.     pylab.grid()
  16.     pylab.ylim ([-2, 2])
  17.     pylab.legend()
  18.     pylab.show()

В результате с помощью этого кода мы рисуем одну кривую, включаем сетку, меняем пределы по оси Y, отображаем легенду и показываем окно. Результат выглядит следующим образом:

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

Проще всего (и желательно так делать) для этого воспользоваться все теми же функциями из модуля pylab, используя тот факт, что многие функции модуля возвращают какие-то объекты. Изменим предыдущий пример таким образом, чтобы получить некоторые такие объекты, после чего настройки графика изменим, используя полученные экземпляры классов.

  1. #!/usr/bin/env python
  2. # -*- coding: UTF-8 -*-
  3.  
  4. import numpy
  5.  
  6. # Импортируем один из пакетов Matplotlib
  7. import pylab
  8.  
  9.  
  10. if __name__ == '__main__':
  11.     x = numpy.arange (0.0, 4 * numpy.pi, 0.01)
  12.     y = numpy.sin (x) * numpy.cos (3 * x)
  13.  
  14.     # Получим экземпляр класса Figure
  15.     figure = pylab.figure()
  16.     print type (figure)
  17.  
  18.     # Получим экземпляр класса осей
  19.     axes = figure.add_subplot (1, 1, 1)
  20.     print type (axes)
  21.  
  22.     # Получим список новых кривых
  23.     curves = axes.plot (x, y, '--k', label=u'y = f(x)')
  24.     print curves
  25.  
  26.     # Изменим настройки осей
  27.     axes.grid()
  28.     axes.set_ylim ([-2, 2])
  29.     axes.set_xlabel (u'angle, radians')
  30.     axes.set_ylabel (u'U, mV')
  31.  
  32.     # Создадим легенду и получим экземпляр класса Legend
  33.     legend = pylab.legend()
  34.     print type (legend)
  35.  
  36.     # Изменим заголовок легенды
  37.     legend.set_title (u'Title')
  38.  
  39.     pylab.show()

Теперь наше окно выглядит следующим образом:

Кроме того, этот пример последовательно выводит названия типов классов. Так, после создания окна с будущим графиком с помощью функции pylab.figure, мы получили экземпляр класса matplotlib.figure.Figure, затем мы создали оси с помощью метода add_subplot и получили экземпляр класса matplotlib.axes.AxesSubplot - класс, производный от matplotlib.axes.Axes, который хорошо документирован, в отличие от matplotlib.axes.AxesSubplot.

Затем, уже используя класс осей, мы нарисовали кривую, используя хорошо известный нам метод plot, но уже вызываемый непосредственно для класса matplotlib.axes.Axes или его производных. Этот метод возвращает список объектов, описываеющих содержимое графика. Метод plot возвращает список классов matplotlib.lines.Line2D, другие методы рисования возвращают другие объекты.

После этого мы возвращаемся к экземпляру класса осей axes и меняем их настройки.

Затем мы создаем легенду с помощью знакомой функции pylab.legend, которая возвращает экземпляр класса matplotlib.legend.Legend, и, используя экземпляр этого класса, меняем заголовок легенды с помощью метода set_title.

Обратите внимание, что методы классов очень напоминают функции модуля pylab, возможно с приставками set_ или get_. Например, pylab.xlim <--> Axes.set_ylim, pylab.xlabel <--> Axes.set_xlabel и т.п.

В предыдущем примере мы могли бы расписать 23-ю строку (curves = axes.plot (x, y, '-k', label=u'y = f(x)')) по-другому, устанавливая параметры кривой в несколько этапов, как показано в следующем примере:

  1. #!/usr/bin/env python
  2. # -*- coding: UTF-8 -*-
  3.  
  4. import numpy
  5.  
  6. # Импортируем один из пакетов Matplotlib
  7. import pylab
  8.  
  9.  
  10. if __name__ == '__main__':
  11.     x = numpy.arange (0.0, 4 * numpy.pi, 0.01)
  12.     y = numpy.sin (x) * numpy.cos (3 * x)
  13.  
  14.     # Получим экземпляр класса Figure
  15.     figure = pylab.figure()
  16.     print type (figure)
  17.  
  18.     # Получим экземпляр класса осей
  19.     axes = figure.add_subplot (1, 1, 1)
  20.     print type (axes)
  21.  
  22.     # Получим список новых кривых
  23.     curves = axes.plot (x, y)
  24.     print curves
  25.  
  26.     curves[0].set_linestyle ('--')
  27.     curves[0].set_color ('k')
  28.     curves[0].set_label (u'y = f(x)')
  29.  
  30.     # Изменим настройки осей
  31.     axes.grid()
  32.     axes.set_ylim ([-2, 2])
  33.     axes.set_xlabel (u'angle, radians')
  34.     axes.set_ylabel (u'U, mV')
  35.  
  36.     # Создадим легенду и получим экземпляр класса Legend
  37.     legend = pylab.legend()
  38.     print type (legend)
  39.  
  40.     # Изменим заголовок легенды
  41.     legend.set_title (u'Title')
  42.  
  43.     pylab.show()

Результат будет выглядеть точно также.

Оси мы могли бы создать с помощью функции pylab.axes, заменив в предыдущем примере 19-ю строку (axes = figure.add_subplot (1, 1, 1)) на

axes = pylab.axes ((0.1, 0.1, 0.8, 0.8))

В этом случае переменная axes будет хранить экземпляр класса matplotlib.axes.Axes, что не скажется на остальной код. Переданный в функцию axes кортеж задает координаты левого нижнего угла будущего графика, а также его ширину и высоту. Координаты угла и размеры задаются в нормированных координатах, где (0.0; 0.0) - координаты левого нижнего угла окна, а (1.0; 1.0) - координаты правого верхнего угла окна.

После всего написанного выше может возникнуть желание пойти дальше и вообще отказаться от использования модуля pylab, а вызывать конструкторы Figure, Axes и Legend вручную. Теоретически это можно попробовать сделать, но это не просто, поскольку "под капотом" модуля pylab происходит некая магия, связанная с так называемыми менеджерами фигур.

Если вам интересно покопаться в исходниках matplotlib (а там код сравнительно понятный), то можете начинать свое изучение с файла lib/matplotlib/pyplot.py - там описаны все функции модуля pylab, затем вам понадобится синглтон Gcf из файла lib/matplotlib/_pylab_helpers.py, и вообще придется задействовать функции, не предназначенные для вызова пользователями. Но это все уже другая, хотя и достаточно интересная, тема.

Другие статьи про Matplotlib

Немного рекламы

Вы можете подписаться на новости сайта через RSS, Группу Вконтакте или Канал в Telegram.
0 stars Пока еще нет оценок




Подписаться на комментарии
Автор:
Тема:
 Ваш комментарий
 
 
Введите код 381