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

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

Дата публикации: 18.12.2014
Дата последней правки: 11.10.2023

Содержание

Модуль pylab. Историческая справка

Matplotlib разрабатывается уже на протяжении долгого времени, и поэтому в недрах этой библиотеки можно найти следы различных исторических эпох в развитии этой библиотеки. Например, в древности Matplotlib использовалась через модуль pylab, который предоставляет функции по внешнему виду напоминающие функции из Matlab. На сайте Matplotlib до сих пор можно найти следы древних строк документации, рассказывающие о том, что когда-то подразумевалось, что программисты будут импортировать этот модуль через команду from pylab import *, чтобы импортировать множество функций, похожих на функции Matlab, причем эти функции относятся не только к построению графиков, но также туда входят различные математические функции из библиотек numpy, numpy.fft и numpy.linalg. Понятно, что в современном мире в приличной компании подобный импорт библиотек, мягко говоря, не поощряется, и поэтому модуль pylab сейчас считается устаревшим и оставлен только для обратной совместимости с древними письменами программами.

В качестве исторической справки приведем пример программы, использующей такой подход. Внимание!!! Сейчас так делать не надо!

  1. # -*- coding: utf-8 -*-
  2.  
  3. from pylab import *
  4.  
  5.  
  6. if __name__ == "__main__":
  7.     x = arange(0.0, 4 * pi, 0.01)
  8.     y = sin(x) * cos(3 * x)
  9.  
  10.     figure()
  11.     plot(x, y, "-k", label="y = f(x)")
  12.     grid()
  13.     xlim([0, 14])
  14.     ylim([-2, 2])
  15.     xlabel("t, нс")
  16.     ylabel("U, В")
  17.     title("Периодический сигнал")
  18.     legend(title="Сигналы")
  19.     show()

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

Модуль matplotlib.pyplot

Предыдущий пример, конечно компактный и может понравится тем, кто переходит с Matlab на Python, но не выдерживает никакой критики с точки зрения идеологии современного программирования. Поэтому через какое-то время в Matplotlib появился отдельный модуль matplotlib.pyplot, в котором были собраны аналогичные функции создания графиков, как и в pylab, но этот модуль не подразумевает импорт функций с помощью звездочки. Кроме того, в отличие от модуля pylab, модуль pyplot не содержит в себе функции из numpy, и поэтому их нужно импортировать в явном виде.

При импорте этого модуля принято давать ему псевдоним plt:

import matplotlib.pyplot as plt

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

import numpy as np
import matplotlib.pyplot as plt


if __name__ == "__main__":
    x = np.arange(0.0, 4 * np.pi, 0.01)
    y = np.sin(x) * np.cos(3 * x)

    plt.figure()
    plt.plot(x, y, "-k", label="y = f(x)")
    plt.grid()
    plt.xlim([0, 14])
    plt.ylim([-2, 2])
    plt.xlabel("t, нс")
    plt.ylabel("U, В")
    plt.title("Периодический сигнал")
    plt.legend(title="Сигналы")
    plt.show()

Используем объекты

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

Например, используемая в предыдущем примере функция plt.figure() возвращает экземпляр класса Figure, упомянутый выше. Мы можем воспользоваться этим и создать новые оси для графика с помощью метода add_subplot() из класса Figure, и этот метод нам вернет экземпляр класса Axes, используя который мы можем нарисовать график и настроить его внешний вид. Изменим для этого предыдущий пример.

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3.  
  4.  
  5. if __name__ == "__main__":
  6.     x = np.arange(0.0, 4 * np.pi, 0.01)
  7.     y = np.sin(x) * np.cos(3 * x)
  8.  
  9.     # Получим экземпляр класса Figure
  10.     fig = plt.figure()
  11.     print(type(fig))
  12.  
  13.     # Получим экземпляр класса осей Axes
  14.     axes = fig.add_subplot(1, 1, 1)
  15.     print(type(axes))
  16.  
  17.     # Получим список новых кривых
  18.     curves = axes.plot(x, y, "-k", label="y = f(x)")
  19.     print(curves)
  20.  
  21.     # Изменим настройки осей
  22.     axes.grid()
  23.     axes.set_xlim(0, 14)
  24.     axes.set_ylim(-2.0, 2.0)
  25.     axes.set_xlabel("t, нс")
  26.     axes.set_ylabel("U, В")
  27.  
  28.     title = axes.set_title("Периодический сигнал")
  29.     print(type(title))
  30.  
  31.     # Создадим легенду и получим экземпляр класса Legend
  32.     legend = axes.legend()
  33.     print(type(legend))
  34.  
  35.     # Изменим заголовок легенды
  36.     legend.set_title("Сигналы")
  37.  
  38.     # Показать окно с графиком
  39.     plt.show()

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

<class 'matplotlib.figure.Figure'>
<class 'matplotlib.axes._axes.Axes'>
[<matplotlib.lines.Line2D object at 0x7f8f8a9e6dd0>]
<class 'matplotlib.text.Text'>
<class 'matplotlib.legend.Legend'>
  • Функция plt.figure() возвращает экземпляр класса matplotlib.figure.Figure.
  • Метод Figure.add_subplot() возвращает экземпляр класса matplotlib.axes._axes.Axes.
  • Метод Axes.plot() возвращает список (состоящий из одного элемента в нашем примере) классов matplotlib.lines.Line2D.
  • Метод Axes.set_title() возвращает экземпляр класса matplotlib.text.Text.
  • Метод Axes.legend() возвращает экземпляр класса matplotlib.legend.Legend.

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

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

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3.  
  4.  
  5. if __name__ == "__main__":
  6.     x = np.arange(0.0, 4 * np.pi, 0.01)
  7.     y = np.sin(x) * np.cos(3 * x)
  8.  
  9.     # Получим экземпляр класса Figure
  10.     fig = plt.figure()
  11.     print(type(fig))
  12.  
  13.     # Получим экземпляр класса осей Axes
  14.     axes = fig.add_subplot(1, 1, 1)
  15.     print(type(axes))
  16.  
  17.     # Получим список новых кривых
  18.     curves = axes.plot(x, y)
  19.     print(curves)
  20.  
  21.     # !!! Изменим внешний вид кривой
  22.     curves[0].set_linestyle("-")
  23.     curves[0].set_color("k")
  24.     curves[0].set_label("y = f(x)")
  25.  
  26.     # Изменим настройки осей
  27.     axes.grid()
  28.     axes.set_xlim(0, 14)
  29.     axes.set_ylim(-2.0, 2.0)
  30.     axes.set_xlabel("t, нс")
  31.     axes.set_ylabel("U, В")
  32.  
  33.     title = axes.set_title("Периодический сигнал")
  34.     print(type(title))
  35.  
  36.     # Создадим легенду и получим экземпляр класса Legend
  37.     legend = axes.legend()
  38.     print(type(legend))
  39.  
  40.     # Изменим заголовок легенды
  41.     legend.set_title("Сигналы")
  42.  
  43.     # Показать окно с графиком
  44.     plt.show()

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

Таким образом при использовании библиотеки Matplotlib у нас есть выбор, при создании графиков использовать функции из модуля matpltolib.pyplot или использовать создаваемые объекты напрямую. Второй способ во многих ситуациях дает большую гибкость в настройке внешнего вида полученных графиков.

Похожие статьи

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

Рейтинг 5.0/5. Всего 5 голос(а, ов)




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