Станьте Леонардо да Матплотлиб

Хорошие вещи приходят к тем, кто читает документацию Matplotlib.

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

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

Итак, вот они.

1️⃣. rcParams

Начнем с понятий самого высокого уровня.

Первым в нашем списке является словарь rcParams. Он содержит все настройки Matplotlib, которые используются для создания стилей фигур по умолчанию. Вы импортируете его непосредственно из пространства имен matplotlib:

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

Если вы когда-нибудь что-то испортите или захотите вернуться к значениям по умолчанию, вы можете вызвать функцию rcdefaults PyPlot, которая сбрасывает все.

>>> plt.rcdefaults()

2️⃣. функции get_*

Под капотом Matplotlib полностью объектно-ориентирован.

Каждый отдельный компонент, который вы видите на диаграмме выше, реализован как отдельный класс. Все они наследуются от базового класса Matplotlib Artist. Вот почему вы часто будете читать это слово в документации по MPL.

Наличие отдельного класса для каждого отдельного аспекта сюжета вводит определенный уровень сложности, но также дает вам большую гибкость.

Ключ к отличному сюжету — настройка. Не просто изменения сюжета, а кастомизация на самых глубоких уровнях. Вы должны иметь возможность настроить каждый отдельный компонент ваших визуальных эффектов так, чтобы он соответствовал вашему вкусу, теме и профессионализму.

Для этого вы должны знать, как извлекать компоненты, которые вы хотите настроить. К счастью, в Matplotlib есть много функций, которые начинаются с префикса get_, что позволяет извлекать разные классы из созданной фигуры или осей. Вот пример:

Допустим, вы хотите настроить xticks этого графика:

Это легко, просто вызовите get_xticklabels для объекта осей, и вы получите список экземпляров Matplotlib Text:

Вы также можете настроить линии делений с помощью get_xticklines или расположение делений с помощью get_xticks.

Вам может быть интересно, как мы на самом деле настраиваем эти объекты? Мы ответим на этот вопрос в следующем разделе.

3️⃣. получить/установить

Когда у вас есть компонент, который вы хотите настроить, вы должны знать, какие свойства или параметры они принимают. Здесь вы используете два швейцарских армейских ножа Matplotlib.

Во-первых, вызовите функцию plt.getp для вашего объекта, чтобы увидеть, какие параметры у него есть в данный момент. Например, предположим, что мы хотим стилизовать l2 графика ниже:

Как видите, я сохранил каждый линейный график в отдельную переменную для последующего использования. Теперь мы вызываем plt.getp во второй строке l2:

Как и ожидалось, функция распечатала значения по умолчанию l2. Для изменения свойства воспользуемся другой функцией — plt.setp. Вызов этого для объекта без каких-либо параметров выводит возможные значения, которые объект принимает для своих свойств:

Чтобы напечатать возможные значения только для одного свойства, вы можете указать имя свойства в виде строки setp:

Теперь давайте, наконец, внесем несколько изменений во вторую строку:

Чтобы увидеть текущую фигуру после изменений, просто вызовите get_figure для объекта фигуры:

>>> fig.get_figure()

Как видите, вторая строка полностью отличается от остальных.

В двух словах, если вы хотите стилизовать определенный компонент вашего сюжета, вот шаги, которые вы должны выполнить:

  1. Определите имя элемента интуитивно или по документации MPL.
  2. Извлеките его, используя соответствующую функцию get_*.
  3. Посмотреть его текущие свойства можно с помощью plt.getp
  4. Узнайте, какие возможные значения принимает каждое свойство с помощью plt.setp
  5. Измените нужные параметры с помощью той же функции.

4️⃣. Легенды

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

К счастью, вы можете управлять легендами любого графика, используя только функцию legend с plt.legend внутри PyPlot API или ax.legend в OOP API. Вызов функции без параметров создает легенду со значениями по умолчанию:

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

Поэтому предлагаю прочитать документацию Matplotlib функции legend (ссылка). Тем не менее, я бы сказал, что наиболее важными параметрами легенды являются:

  • loc - расположение легенды
  • bbox_to_anchor — еще один параметр местоположения, относящийся к окну округления легенды (подробности см. в документации).
  • Свойства шрифта — размер, цвет, стиль
  • ncol - количество столбцов внутри легенды, когда элементов много

Вы также можете изменить эти параметры после создания легенды. Просто извлеките его с помощью get_legend и используйте функции getp, setp.

5️⃣. велосипедист

Вы когда-нибудь задумывались, как Matplotlib меняет свои цвета или циклически через разные стили сам по себе?

Причина в том, что под капотом Matplotlib использует встроенные объекты Python, называемые Cyclers:

Функция cycle очень универсальна. Он принимает любой параметр ключ-значение и создает список словарей:

Кроме того, вы можете комбинировать несколько циклов с помощью операторов «плюс» и «умножить», чтобы получить индекс к индексу или исчерпывающую комбинацию параметров:

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

Вы можете передать этот пользовательский цикл на график, используя функцию set_prop_cycle объекта осей:

Как видите, линии синусоиды совершенно другие.

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

Вы также можете добавить свои пользовательские циклеры в словарь rcParams. Вот значения по умолчанию:

>>> rcParams["axes.prop_cycle"]

6️⃣. tick_params

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

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

Первая пара параметров, которые вы всегда должны указывать, это axis и which. В зависимости от них установленные вами параметры будут применяться к делениям оси X или Y, а также к второстепенным или основным делениям.

Кстати, в большинстве случаев мелкие галочки не будут видны в Matplotlib. Чтобы быстро включить их, используйте функцию minorticks_on на объекте осей:

Вот отличный ресурс, который показывает больше о функции tick_params.

7️⃣. Тикеры

Иногда вы не хотите утруждать себя заданием настраиваемых параметров тика. В этом случае вы можете использовать множество встроенных в Matplotlib коллекций «тем» параметров тиков, называемых тикеры.

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

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

Используйте свойства xaxis или yaxis объекта осей и вызовите функции set_major(minor)_formatter(locator), передав имя класса. Выше мы форматируем деления оси X, используя нотацию Engineering.

8️⃣. Добавление пользовательских сеток

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

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

В Matplotlib вы можете создавать и настраивать сетки, используя функцию grid объекта осей. Вот уродливая вертикальная сетка в качестве примера:

Я предлагаю вам прочитать документы для деталей.

9️⃣. plt.bar_label()

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

Вы можете сделать это вручную, используя некоторые арифметические вычисления, чтобы разместить текстовую аннотацию над каждой полосой, но есть способ получше. Функция bar_label принимает объект BarContainer в качестве параметра и автоматически аннотирует каждый бар с его высотой.

Вот простой график с Seaborn:

Объект BarContainer добавляется на график каждый раз, когда вы создаете гистограмму с помощью Seaborn или таких функций, как ax.bar. Затем вы можете получить этот объект контейнера, используя атрибут containers объекта осей:

>>> ax.containers
[<BarContainer object of 5 artists>]

Как видите, в приведенном выше списке есть объект BarContainer с 5 барами. Теперь мы просто передаем этот объект bar_label после создания графика:

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

1️⃣0️⃣. зордер

Наконец, у нас есть еще один тонкий аспект графиков — порядок отображения. Это важная концепция, когда вы накладываете разные графики. Вы должны убедиться, что каждый сюжет рисуется на холсте в правильном порядке. Для этого вам нужен параметр zorder.

Ниже мы создаем три строки (взятые из документов) с разными zorders:

Эффект хорошо виден. Если вы обратите внимание, zorder легенды задается с помощью функции set_zorder, что тоже допустимо. Кроме того, вы можете изменить zorder любого объекта, используя предыдущую функцию plt.setp.

Краткое содержание

Библиотеки приходят и уходят, но такой титан, как Matplotlib, всегда выдерживает испытание временем. Несмотря на то, что многих людей привлекают блестящие инструменты, такие как Plotly, Matplotlib по-прежнему остается самой популярной библиотекой для визуализации данных.

Согласно статистике PyPI, в июне 2023 года Matplotlib было скачано более 30 миллионов раз, что почти в 4 раза больше, чем у его крупнейшего конкурента — Plotly.

Это просто доказывает, насколько важно изучить некоторые менее известные расширенные функции библиотеки и вывести свои графики на новый уровень.

Спасибо за чтение!

Мне понравилась эта статья и, скажем прямо, ее причудливый стиль написания. Представьте себе, что у вас есть доступ к десяткам таких же, написанных блестящим, обаятельным, остроумным автором (кстати, это я :).

Всего за 4,99 $ членства вы получите доступ не только к моим историям, но и к сокровищнице знаний от лучших и самых ярких умов на Medium. А если вы воспользуетесь моей реферальной ссылкой, то получите мою сверхновую благодарность и виртуальную пятерку за поддержку моей работы.