вторник, 21 июня 2011 г.

matplotlib - чертим кодом

В гостях у нас новая модная фишка - библиотека питона для отображения 2D графиков и геометрических фигур. Я использовал ее для создания графиков в системе документирования проектов. Достаточно удобно, за исключением того факта, что отсутствуют какие-либо плагины для трака. Эх, как же было бы прекрасно писать в самой вики трака код, нажимать кнопку и получать готовую картинку. Как собственно я делал для графвиза. Но увы, на данный момент приходится сперва с помощью скрипта создавать изображение в каком-нибудь формате PNG, а уж затем впихивать эту картинку в трак. Может взять это за повод разработать плагин для трака?
Кстати раз уж упомянул, в чем же отличие Graphviz от matplotlib? Графвиз, как свидетельствует корень слова, специализируется на графиках. Это высокоуровневый движок предназначенный для отрисовки рафиков, описание которых не указывает форму отрисовки, лишь отношение между графами. Матплотлиб это более низкоуровневый движок, где отрисовка детально описывается кодом, и нарисовать можно все что угодно.

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

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

2. мучаем оси координат
По-умолчанию заботливый матплотлиб дарит нам отметки осей координат на всех четырех сторонах изображения. Что же можно с этим сделать...
a) убираем отметки (так называемые ticks) с верхней оси:

ax.xaxis.set_ticks_position('bottom')

где ax - объект типа matplotlib.axes.Axes , соответствующий метод для yaxis здесь.

б) убираем ось полностью

ax.yaxis.set_visible(False)

метод наследуется классом оси от класса matplotlib.artist.Artist

в) устанавливаем границы изображения по осям

plt.axis([0, 7, 0.5, 2.5])


г) указываем границы отметок-ticks и как их подписать

import pylab
...
pylab.xticks( pylab.arange(8), ('', 't1', '', 't2', '', 't1+d1','t2+d2') )

а что же это за модуль такой pylab? Это всего лишь процедурный интерфейс к другим различным модулям, в том числе к matplotlib и numpy. Достаточно посмотреть исходный код pylab чтобы увидеть все бесстыдство сплошных импортов и ни единого кусочка собственного кода. Однако это должно быть удобным. Так или иначе на моей убунточке матплотлиб установка включает в себя pylab, выбора тут нету.

д) указываем, где нужно разместить отметки-ticks (если дефолтные предположения матплотлиб рисуют ненужные тики или не рисуют нужные)

ax.xaxis.set_major_locator(matplotlib.ticker.IndexLocator(1,0))


3. меняем размеры изображения
Размеры картинки при работе с матплотлиб могут пониматься в двух смыслах. В векторном и в растровом. Изначально мы задаем размеры в векторном смысле. Что определяют эти размеры? Они определяют в основном относительное расположение элементом рисунка на координатной оси (при этом некоторые детали сохраняют свои размеры, например текст). Можно сказать что на этом этапе мы просто сжимаем/разжимаем координаты используя категории дюймов, сантиметров и тп. Второй и заключительный этап - преобразование вектора в растр, здесь мы просто указываем DPI (хотя наверное это правильнее было бы назвать pixels per inch) и все что мы наваяли в векторе преобразуется в растр. Вот кусок кода:

defaultSize = fig.get_size_inches() #получаем размер нашего изображения
pylab.savefig("plot01.png", bbox_inches="tight",dpi=75) #сохраняем как png с dpi 75

#уменьшаем изображение по вертикали, при этом текст например сохраняет свои размеры
fig.set_size_inches(defaultSize[0], defaultSize[1] * 0.4)
pylab.savefig("plot02.png", bbox_inches="tight",dpi=75) #вновь сохраняем с теми же dpi


Вот пока и всё. Читаем доки с сайта, смотрим питоновские help(...) и чертим с удовольствием!

Комментариев нет:

Отправить комментарий