Использование библиотеки Matplotlib. Как управлять положением меток на осях

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

Оглавление

Введение

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

Для начала нарисуем график с метками по умолчанию.

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import numpy

import pylab


if __name__ == "__main__":
    xvals = numpy.arange (-10.0, 10.1, 0.1)
    yvals = numpy.sinc (xvals)

    figure = pylab.figure()
    axes = figure.add_subplot (1, 1, 1)

    pylab.plot (xvals, yvals)

    axes.grid()
    pylab.show()

Результат выглядит следующим образом:

Для того, чтобы изменять шаг расположения меток, предназначены метод set_major_locator() класса matplotlib.axis.Axis для основных меток и метод set_minor_locator() для промежуточных. В качестве единственного параметра, эти методы принимают экземпляр класса, производного от базового класса matplotlib.ticker.Locator (дальше для краткости будем называть эти классы "локатор"). Модуль matplotlib.ticker содержит несколько таких локаторов, использующие различные алгоритмы расположения меток. В следующих разделах мы их рассмотрим подробнее. Во всех примерах мы будем изменять только метки по оси X.

Надо отметить, что нельзя применять один и тот же экземпляр локатора и к оси X, и к оси Y, надо обязательно делать для каждой оси свой экземпляр. Это связано с внутренней работой библиотеки Matplotlib.

А теперь давайте посмотрим, какие локаторы нам предлагает библиотека Matplotlib.

NullLocator

Самый простой локатор - это NullLocator, который используется для отключения всех меток. Применим его к оси X.

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import numpy

import pylab
import matplotlib.ticker


if __name__ == "__main__":
    xvals = numpy.arange (-10.0, 10.1, 0.1)
    yvals = numpy.sinc (xvals)

    figure = pylab.figure()
    axes = figure.add_subplot (1, 1, 1)

    pylab.plot (xvals, yvals)

    # Создаем экземпляр класса, который будет отвечать за расположение меток
    locator = matplotlib.ticker.NullLocator()

    # Установим локатор для главных меток
    axes.xaxis.set_major_locator (locator)

    axes.grid()
    pylab.show()

Метки по оси X исчезли:

LinearLocator

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

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import numpy

import pylab
import matplotlib.ticker


if __name__ == "__main__":
    xvals = numpy.arange (-10.0, 10.1, 0.1)
    yvals = numpy.sinc (xvals)

    figure = pylab.figure()
    axes = figure.add_subplot (1, 1, 1)

    pylab.plot (xvals, yvals)

    # Создаем экземпляр класса, который будет отвечать за расположение меток
    locator = matplotlib.ticker.LinearLocator (13)

    # Установим локатор для главных меток
    axes.xaxis.set_major_locator (locator)

    axes.grid()
    pylab.show()

MultipleLocator

Класс MultipleLocator используется, если надо расставить метки через равные интервалы, размер интервала задается через единственный параметр конструктора base.

Выражаясь математическим языком, метки будут расположены около значений base * i, где i = ±1, ±2, ...

Следующий пример демонстрирует работу MultipleLocator, расставляя метки с шагом 2.5.

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import numpy

import pylab
import matplotlib.ticker


if __name__ == "__main__":
    xvals = numpy.arange (-10.0, 10.1, 0.1)
    yvals = numpy.sinc (xvals)

    figure = pylab.figure()
    axes = figure.add_subplot (1, 1, 1)

    pylab.plot (xvals, yvals)

    # Создаем экземпляр класса, который будет отвечать за расположение меток
    locator = matplotlib.ticker.MultipleLocator (base=2.5)

    # Установим локатор для главных меток
    axes.xaxis.set_major_locator (locator)

    axes.grid()
    pylab.show()

IndexLocator

Класс IndexLocator напоминает MultipleLocator в том смысле, что этот локатор также позволяет расставлять метки с равным шагом. Но, в отличие от него, IndexLocator отсчитывает метки не от нулевого значения, а от наименьшего значения на графике.

Конструктор IndexLocator принимает два обязательных параметра:

  • base задает интервал между метками.
  • offset задает смещение относительно наименьшего значения на оси.

Проще всего это продемонстрировать на примерах. Первый пример расставляет метки с интервалом 1.5 и значением параметра offset = 0.

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import numpy

import pylab
import matplotlib.ticker


if __name__ == "__main__":
    xvals = numpy.arange (-10.0, 10.1, 0.1)
    yvals = numpy.sinc (xvals)

    figure = pylab.figure()
    axes = figure.add_subplot (1, 1, 1)

    pylab.plot (xvals, yvals)

    # Создаем экземпляр класса, который будет отвечать за расположение меток
    locator = matplotlib.ticker.IndexLocator (1.5, 0)

    # Установим локатор для главных меток
    axes.xaxis.set_major_locator (locator)

    axes.grid()
    pylab.show()

Обратите внимание, что в данном примере, в отличие от MultipleLocator, нет метки при нулевом значении.

Чтобы показать, что метки действительно отсчитываются от самого левого значения в данных, изменим этот пример, начав рисовать sinc не со значения -10, а со значения -10.3. В этом случае библиотека Matplotlib отмасштабирует ось X таким образом, чтобы она начиналась от значения -15. А мы увидим, где расположена первая метка.

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import numpy

import pylab
import matplotlib.ticker


if __name__ == "__main__":
    xvals = numpy.arange (-10.3, 10.1, 0.1)
    yvals = numpy.sinc (xvals)

    figure = pylab.figure()
    axes = figure.add_subplot (1, 1, 1)

    pylab.plot (xvals, yvals)

    # Создаем экземпляр класса, который будет отвечать за расположение меток
    locator = matplotlib.ticker.IndexLocator (1.5, 0)

    # Установим локатор для главных меток
    axes.xaxis.set_major_locator (locator)

    axes.grid()
    pylab.show()

Что и требовалось доказать. Метки отсчитываются от минимального значения в данных, а интервал между ними так и остался 1.5.

Теперь установим второй параметр конструктора (offset) значение 0.5.

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import numpy

import pylab
import matplotlib.ticker


if __name__ == "__main__":
    xvals = numpy.arange (-10.3, 10.1, 0.1)
    yvals = numpy.sinc (xvals)

    figure = pylab.figure()
    axes = figure.add_subplot (1, 1, 1)

    pylab.plot (xvals, yvals)

    # Создаем экземпляр класса, который будет отвечать за расположение меток
    locator = matplotlib.ticker.IndexLocator (1.5, 0.5)

    # Установим локатор для главных меток
    axes.xaxis.set_major_locator (locator)

    axes.grid()
    pylab.show()

Первая метка сместилась на значение 0.5.

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

FixedLocator

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

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import numpy

import pylab
import matplotlib.ticker


if __name__ == "__main__":
    xvals = numpy.arange (-10.0, 10.1, 0.1)
    yvals = numpy.sinc (xvals)

    figure = pylab.figure()
    axes = figure.add_subplot (1, 1, 1)

    pylab.plot (xvals, yvals)

    # Создаем экземпляр класса, который будет отвечать за расположение меток
    # Метки будут находиться только в тех значениях, которые перечислены в списке
    locator = matplotlib.ticker.FixedLocator ([-5, -4, -3, 0, 3, 4, 5])

    # Установим локатор для главных меток
    axes.xaxis.set_major_locator (locator)

    axes.grid()
    pylab.show()

В данном примере метки будут установлены только при значениях X = -5, -4, -3, 0, 3, 4, 5.

LogLocator

Если нужно расположить метки по логарифмическому закону (например, при значениях X = 1, 10, 100, 1000, ...), то нужно использовать локатор LogLocator. Конструктор класса LogLocator может принимать несколько значений. Самый важный из них - это первый параметр base, который задает величину, которая будет последовательно возводиться в степень 0, 1, 2, ..., и в этих местах будет ставиться метка. Если не использовать второй параметр, о котором будет написано ниже, то метки будут выставляться в значениях, рассчитанных по формуле basei, где i = 0, 1, 2, ... По умолчанию параметр base принимает значение 10.

Следующий пример показывает использование локатора с base = 2.

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import numpy

import pylab
import matplotlib.ticker


if __name__ == "__main__":
    xvals = numpy.arange (0.0, 65.1, 0.1)
    yvals = numpy.sinc (xvals)

    figure = pylab.figure()
    axes = figure.add_subplot (1, 1, 1)

    pylab.plot (xvals, yvals)

    # Создаем экземпляр класса, который будет отвечать за расположение меток
    locator = matplotlib.ticker.LogLocator (base=2)

    # Установим локатор для главных меток
    axes.xaxis.set_major_locator (locator)

    axes.grid()
    pylab.show()

Конструктору LogLocator можно передать дополнительный параметр subs, который представляет собой список множителей, на которые умножается, результат возведения в степень. То есть положения меток определяется по формуле basei * subs[j], где i = 0, 1, 2, ..., а j = 0, 1,... len (subs) - 1. По умолчанию параметр subs = [1.0].

Следующий пример демонстрирует использование параметра subs.

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import numpy

import pylab
import matplotlib.ticker


if __name__ == "__main__":
    xvals = numpy.arange (0.0, 65.1, 0.1)
    yvals = numpy.sinc (xvals)

    figure = pylab.figure()
    axes = figure.add_subplot (1, 1, 1)

    pylab.plot (xvals, yvals)

    # Создаем экземпляр класса, который будет отвечать за расположение меток
    locator = matplotlib.ticker.LogLocator (base=2, subs=[1, 5])

    # Установим локатор для главных меток
    axes.xaxis.set_major_locator (locator)

    axes.grid()
    pylab.show()

MaxNLocator

Класс MaxNLocator является одним из самых интеллектуальных локаторов, и в то же время мало предсказуемых. Суть его работы заключается в том, что с его помощью ось разбивается на некоторое количество интервалов, но не больше некоторого значения, которое задается в конструкторе с помощью именованного параметра nbins.

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

Посмотрим, как будет выглядеть график, если в конструктор MaxNLocator не будут переданы никакие параметры.

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import numpy

import pylab
import matplotlib.ticker


if __name__ == "__main__":
    xvals = numpy.arange (-20.0, 20.0, 0.1)
    yvals = numpy.sinc (xvals)

    figure = pylab.figure()
    axes = figure.add_subplot (1, 1, 1)

    pylab.plot (xvals, yvals)

    # Создаем экземпляр класса, который будет отвечать за расположение меток
    locator = matplotlib.ticker.MaxNLocator ()

    # Установим локатор для главных меток
    axes.xaxis.set_major_locator (locator)

    axes.grid()
    pylab.show()

Получилось довольно удачное разбиение с десятью интервалами.

Теперь укажем конструктору, что нам нужно не больше 5 интервалов.

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import numpy

import pylab
import matplotlib.ticker


if __name__ == "__main__":
    xvals = numpy.arange (-20.0, 20.0, 0.1)
    yvals = numpy.sinc (xvals)

    figure = pylab.figure()
    axes = figure.add_subplot (1, 1, 1)

    pylab.plot (xvals, yvals)

    # Создаем экземпляр класса, который будет отвечать за расположение меток
    locator = matplotlib.ticker.MaxNLocator (nbins=5)

    # Установим локатор для главных меток
    axes.xaxis.set_major_locator (locator)

    axes.grid()
    pylab.show()

Класс MaxNLocator решил, что 4 интервала будут смотреться лучше.

Конструктор класса MaxNLocator может принимать некоторое количество дополнительных параметров, о которых вы можете прочитать в документации. Рассмотрим один из них - параметр steps, который указывает локатору наши пожелания относительно того, какие числа мы бы хотели видеть около меток в пределах десятки. Этот параметр принимает список чисел в интервале от 1 до 10, включая концы.

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

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import numpy

import pylab
import matplotlib.ticker


if __name__ == "__main__":
    xvals = numpy.arange (-20.0, 20.0, 0.1)
    yvals = numpy.sinc (xvals)

    figure = pylab.figure()
    axes = figure.add_subplot (1, 1, 1)

    pylab.plot (xvals, yvals)

    # Создаем экземпляр класса, который будет отвечать за расположение меток
    locator = matplotlib.ticker.MaxNLocator (steps=[5])

    # Установим локатор для главных меток
    axes.xaxis.set_major_locator (locator)

    axes.grid()
    pylab.show()

В этом же примере мы укажем, что нас устроят числа 2 и 6.

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import numpy

import pylab
import matplotlib.ticker


if __name__ == "__main__":
    xvals = numpy.arange (-20.0, 20.0, 0.1)
    yvals = numpy.sinc (xvals)

    figure = pylab.figure()
    axes = figure.add_subplot (1, 1, 1)

    pylab.plot (xvals, yvals)

    # Создаем экземпляр класса, который будет отвечать за расположение меток
    locator = matplotlib.ticker.MaxNLocator (steps=[2, 6])

    # Установим локатор для главных меток
    axes.xaxis.set_major_locator (locator)

    axes.grid()
    pylab.show()

Алгоритм, заложенный в MaxNLocator решил, что только для данного графика лучше оставить только числа, кратные 6.

В библиотеке Matplotlib есть еще локатор AutoLocator, но он из себя представляет тот же MaxNLocator с установленными некоторыми параметрами по умолчанию.

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


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

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

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




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