Настраиваем формат отображения меток у координатных осей

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

set_xticklabels(), set_yticklabels()

с помощью которых часто делают сокрытие текстовых меток для тиков графика:

import numpy as np
import matplotlib.pyplot as plt
 
fig = plt.figure(figsize=(7, 4))
ax = fig.add_subplot()
x = np.arange(-np.pi/2, np.pi, 0.1)
ax.plot(x, np.sin(x))
ax.set_xticklabels([])
ax.set_yticklabels([])
ax.grid()
plt.show()

Если же требуется более тонкая настройка формата тиков, то для этого в matplotlib используется функция set_major_formatter(), которая применяет тот или иной форматер для форматирования текстовой информации у соответствующих координатных осей.

Само форматирование осуществляется с помощью различных классов, расположенных в ветке:

matplotlib.ticker

И на этом занятии мы рассмотрим основные из них.

NullFormatter

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

from matplotlib.ticker import NullFormatter

А, затем, применить к оси абсцисс или ординат:

ax.xaxis.set_major_formatter(NullFormatter())

Мы здесь сначала обращаемся к объекту xaxis, отвечающий за ось Ox, и вызываем функцию set_major_formatter(), передавая ей экземпляр класса NullFormatter. В результате, подписи у этой оси исчезают и мы видим следующий результат:

По аналогии, можно работать и с осью ординат, только для этого следует использовать объект yaxis:

ax.yaxis.set_major_formatter(NullFormatter())

Увидим похожий результат, но уже для оси Oy.

FormatStrFormatter

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

ax.yaxis.set_major_formatter(FormatStrFormatter('%d'))

будет округлять все числа до целых и по оси Oy мы увидим следующее:

Если же указать спецификатор в виде:

ax.yaxis.set_major_formatter(FormatStrFormatter('%f'))

то получим вещественные числа с шестью знаками после запятой. Для управления точностью вещественных чисел используется запись вида:

ax.yaxis.set_major_formatter(FormatStrFormatter('%.2f'))

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

Интересно, что здесь можно формировать любую строку заданного формата, например, добавлять надписи:

ax.yaxis.set_major_formatter(FormatStrFormatter('y = %.2f'))

В итоге, перед каждым числом будет записано «y = ».

FuncFormatter

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

Для этого воспользуемся классом FuncFormatter и передадим ему ссылку на функцию formatOy:

ax.yaxis.set_major_formatter(FuncFormatter(formatOy))

Сама же функция будет выглядеть так:

def formatOy(x, pos):
    return f"[{x}]" if x < 0 else f"({x})"

Здесь x – это текущее значение риски; pos – текущая позиция (номер) риски от 0 до N, где N+1 – общее число рисок.

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

ScalarFormatter

Этот форматер используется пакетом matplotlib по умолчанию. Он отображает числовые данные так, как они есть с небольшими манипуляциями. Если число оказывается очень большим (больше 10^10), то его множитель выносится:

То же самое происходит и с очень маленькими числами (меньше 10^-10). Но мы можем изменить это поведение и настроить свой диапазон больших и малых значений. Например, если вывести график в диапазоне степени 10^5:

fig = plt.figure(figsize=(7, 4))
ax = fig.add_subplot()
x = np.arange(-2*np.pi, 2*np.pi, 0.1)
ax.plot(x, np.sinc(x) * 1e5)
ax.grid()
plt.show()

То числа будут отображены целиком без сокращений. Но, если сформировать ScalarFormatter и указать максимальную и минимальную степень 4:

sf = ScalarFormatter()
sf.set_powerlimits((-4, 4))
ax.yaxis.set_major_formatter(sf)

то результат будет следующий:

Как видите, степень 10^5 была вынесена за скобки.

Если мы хотим настроить такое поведение глобально для всех графиков, то можно воспользоваться словарем rcParams и переопределить ключ axes.formatter.limits:

matplotlib.rcParams["axes.formatter.limits"] = (-4, 4)

FixedFormatter

Если каждой риске оси нужно присвоить строго определенное значение, то для этого хорошо подходит класс FixedFormatter. Работает он очень просто. Его конструктору передается список значений, которые, затем, будут подставлены соответствующим рискам. Например:

ax.xaxis.set_major_locator(FixedLocator([-3, -2, -1, 0, 1, 2, 3]))
ax.xaxis.set_major_formatter(FixedFormatter(['a', 'b', 'c', 'd', 'e', 'f', 'g']))

Даст результат:

Причем, обратите внимание, мы использовали класс FixedFormatter совместно с классом FixedLocator, так как желательно, чтобы списки по длинам в этих классах совпадали.

Мы с вами рассмотрели лишь некоторые популярные классы форматеров, полный их список можно найти на странице официальной документации:

https://matplotlib.org/stable/api/ticker_api.html