Matplotlib (pylab) простые вещи 2
Задача: продолжить получать графику высокого качества не выходя из питона :)
Инструмент: Matplotlib
Это продолжение . Сегодня мы рассмотрим, как отобразить два графика в одном окне, как это сделать в разных окнах, как добавить математические выражения в подписи к осям и в любое место графика, а также, как подписать какую-нибудь деталь на графике, которая вам особенно нравится.
Работа с несколькими окнами и осями в Matplotlib
И матлаб, и pyplot используют концепцию активного окна и активных осей. Все команды отрисовки чего бы то ни было применяются к именно к активным осям. Функция gca() возвращает активные оси (экземпляр класса matplotlib.axes.Axes), а gcf() возвращает активное окно (figure) (экземпляр класса matplotlib.figure.Figure). Ниже представлен скрипт для создания двух графиков на одном изображении:
import matplotlib.pyplot as plt
def f(t):
return np.exp(-t) * np.cos(2*np.pi*t)
t1 = np.arange(0.0, 5.0, 0.1)
t2 = np.arange(0.0, 5.0, 0.02)
plt.figure(1)
plt.subplot(211)
plt.plot(t1, f(t1), 'bo', t2, f(t2), 'k')
plt.subplot(212)
plt.plot(t2, np.cos(2*np.pi*t2), 'r--')
plt.show()

Команда figure() здесь не обязательна, поскольку figure(1) будет создано по умолчанию, также как и подокно (да, такое вот прекрасное слово :) ) subplot(111) будет создано по умолчанию, если вы вручную не определили оси. Команда subplot() определяет на какое количество подокон будет разбито ваше окно, и в какое из них будет происходить ваш вывод. При этом в качестве аргументов она принимает количество строк (numrows), количество колонок (numcols) и номер подокна(fignum), который изменяется от 1 до numrows*numcols (subplot(numrows,numcols,fignum)). Если numrows*numcols < 10 то запятые ставить не обязательно, то есть subplot(211) и subplot(2,1,1) идентичны друг другу. Вы можете создать сколько угодно подокон и осей. Если вы хотите расположить оси (подокна) вручную, например не на прямоугольной сетке, а как-нибудь ёлочкой, используйте команду axes(), которая позволяет определить положение осей как axes([left, bottom, width, height]), где все значения изменяются от 0 до 1. Выглядеть это может так:
import matplotlib.pyplot as plt
def f(t):
return np.exp(-t) * np.cos(2*np.pi*t)
t1 = np.arange(0.0, 5.0, 0.1)
t2 = np.arange(0.0, 5.0, 0.02)
plt.figure(1)
plt.axes([0.55, 0.55, 0.4, 0.4])
plt.plot(t1, f(t1), 'bo', t2, f(t2), 'k')
plt.axes([0.3, 0.3, 0.4, 0.4])
plt.plot(t2, np.cos(2*np.pi*t2), 'r--')
plt.axes([0.05, 0.05, 0.4, 0.4])
plt.plot(t1, f(t1), 'bo', t2, f(t2), 'k')
plt.show()

Вы можете создать несколько окон, вызывая figure() с увеличивающимся номером окна. Конечно, каждое окно может содержать столько осей и подокон сколько вашей душе угодно.
plt.figure(1) # the first figure
plt.subplot(211) # the first subplot in the first figure
plt.plot([1,2,3])
plt.subplot(212) # the second subplot in the first figure
plt.plot([4,5,6])
plt.figure(2) # a second figure
plt.plot([4,5,6]) # creates a subplot(111) by default
plt.figure(1) # figure 1 current; subplot(212) still current
plt.subplot(211) # make subplot(211) in figure1 current
plt.title('Easy as 1,2,3') # subplot 211 title
plt.show()
Создаст два окна:


Вы можете очистить активное окно при помощи clf() , а активные оси при помощи cla().
Работа с текстом в matplotlib
Команду text() можно использовать для добавления текста в произвольном месте (по умолчанию координаты задаются в координатах активных осей), а команы xlabel(), ylabel() и title() служат соответственно для подписи оси абсцисс, оси ординат и всего графика. Для более полной информации смотрите раздел на офсайте.
import matplotlib.pyplot as plt
mu, sigma = 100, 15
x = mu + sigma * np.random.randn(10000)
# the histogram of the data
n, bins, patches = plt.hist(x, 50, normed=1, facecolor='g', alpha=0.75)
plt.xlabel('Smarts')
plt.ylabel('Probability')
plt.title('Histogram of IQ')
plt.text(60, .025, r'$\mu=100,\ \sigma=15$')
plt.axis([40, 160, 0, 0.03])
plt.grid(True)
plt.show()

Все команды text() возвращают экземпляр matplotlib.text.Text. Точно также, как с линиями вы можете изменять свойства текста, передавая ключевые слова в текстовые функции или используя setp().
Так, чтобы сделать подпись к оси x красной и 14м размером шрифта, нужно написать:
Более подробно это описано в
Использование математических выражений в тексте
Matplotlib понимает формулы написанные в синтаксисе TeX и может вставлять их в любой текст. Например, для того, чтобы написать математическое выражение в заголовке, нужно окружить строку в формате TeX знаками доллара:
Символ r перед строкой важен, он означает, что последующее это чистая строка и не нужно обрабатывать обратный слеш и escape символы (подробнее об этом .
Если мы добавим эти пару строчек в предыдущий пример с гистограммой:
plt.text(50, .033, r'$\varphi_{\mu,\sigma^2}(x) = \frac{1}{\sigma\sqrt{2\pi}} \,e^{ -\frac{(x- \mu)^2}{2\sigma^2}} = \frac{1}{\sigma} \varphi\left(\frac{x - \mu}{\sigma}\right),\quad x\in\mathbb{R}$', fontsize=20, color='red')
то получим такую вот красоту:

Текстовые подписи
Использование команды text(), рассмотренной выше, помещает текст в произвольном месте графика. Часто текст используется для того, чтобы подписать какую-нибудь деталь на графике, и метод annotate() предоставляет вспомогательную функциональность для того, чтобы сделать подобное подписывание легче. Две основных вещи, которые вы должны предоставить этому методу - позицию той точки, которую вы будете подписывать (координаты x y) и позицию текста подписи. Чудесным образом между этими позициями будет проведена стрелочка, свойства которой вы тоже можете контролировать.
import matplotlib.pyplot as plt
ax = plt.subplot(111)
t = np.arange(0.0, 5.0, 0.01)
s = np.cos(2*np.pi*t)
line, = plt.plot(t, s, lw=2)
plt.annotate('local max', xy=(2, 1), xytext=(3, 1.5),
arrowprops=dict(facecolor='black', shrink=0.05),
)
plt.ylim(-2,2)
plt.show()

В этом простом примере позиции и xy (то куда направлена стрелка), и xytext (собственно подпись) задаются в координатах данных (активных осей). Можно выбрать и другие координатные системы, подробности в
Про TeX не знал, спасибо за инфу. Кстати, TeX-овские формулы в pylab смотрятся симпатичнее, чем в mimeTex.
2Jenyay
Ну видишь, пишут что у них свои шрифты, наверное вкус у тебя и у создателей matplotlib в смысле матшрифтов совпадает )
Выковырять бы их рендер TeX-а и использовать вместо mimeTex :)
2Jenyay
Исходники на сайте ))
Я пока к такому подвигу не готов морально :))
2Jenyay
Да, конечно mimeTex шрифты выглядят по сравнению с matplotlib страшненько…
Насколько я понял с matplotlib идёт три шрифта
плюс есть возможность подключать свои.
Может у mimeTex тоже такое есть?
Не, в mimeTex шрифты меяять так просто нельзя, они там, кажется, прошиты в исходнике.
Да, спасибо огромнейшее!!!
Передо мной стоял выбор: pyQwt или mathplotlib.
Благодаря статье однозначно выбираю последнее!
Вот только прочитал это же на оф сайте, а теперь нашел перевод :)
Есть одна проблема… Matplotlib не хочет отрисовывать русский текст. Очень хотелось бы найти способ её решения. В принципе, куда копать, понятно.
Чтобы питоновский скрипт не ругался на не ascii-символы, второй строкой после #!/usr/bin/python нужно указать кодировку, например, так:
# coding=utf-8
После этого matplotlib ругается на отсутствие в используемом шрифте нужных глифов. Значит, нужно как-то заставить его сменить шрифт. Задача решается редактированием файла matplotlibrc.
Здесь есть два варианта: сменить шрифт или возложить задачу отрисовки текста на LaTeX, причем последнему можно прописать преамбулу документа (например, \usepackage[english,russian]{babel}).
Так что понятно куда копать, ясно, но пока ничего не удается :(
У меня та же проблема, что и у Романа,
есть два варианта и оба не работают :(
Может кто решил? Роман?
Завелось, следующим образом:
from matplotlib import rc
rc(’font’,**{’family’:’sans-serif’,’sans-serif’:[’Monospace’]})
rc(’text’, usetex=True)
rc(’text.latex’,unicode=True)
rc(’text.latex’,preamble=’\usepackage[utf8]{inputenc}’)
rc(’text.latex’,preamble=’\usepackage[russian]{babel}’)
Также поставил пакет texlive-latex-extra
Удачи!
2Alexey
Спасибо вам за решение, мировая общественность уже взяла его на вооружение тут
Камрад! Дорогой мой человек!Дайте больше статей по matplotlib на русском языке! Массу интереснейшей информации почерпал из Ваших статей! Было бы неплохо объективно дать оценку пакету python(x,y) и в особенности его работе под Win.(Корректно запустился у меня только почему то на Win7).
Paul, что вы имеете в виду под python(x,y)?
Да и вообще оценку работе matplotlib уже давно поставило сообщество: “работает не хуже конкурентов”.
А у microsoft семерка это первая ОС, которую можно назвать ОС ;), use ubuntu!
вот рабочий вариант под виндой
# -*- coding: utf-8 -*-
from matplotlib import rc
rc(’font’,**{’family’:'verdana’})
rc(’text.latex’,unicode=True)
rc(’text.latex’,preamble=’\usepackage[utf8]{inputenc}’)
rc(’text.latex’,preamble=’\usepackage[russian]{babel}’)
import matplotlib.pyplot as plt
from matplotlib import pyplot
def f(k=0.9):
plt.plot([t for t in range(0,7)],[round(100*k**t) for t in range(0,7)],label=u’коеффициент=%s’%k)
plt.plot([t for t in range(0,7)],[round(100*k**t) for t in range(0,7)],”o”)
f(0.9)
f(0.89)
f(0.88)
f(0.87)
pyplot.axis([-1, 7, 0, 110])
pyplot.xlabel(u”кол. препятствий”)
pyplot.ylabel(u”P, вероятность, %”)
pyplot.title(u”Вероятность попадания от количества препятствий!”)
plt.legend()
plt.grid()
plt.show()
По-моему, лучший вариант решения проблемы с отображением кириллических символов - это редактирование файла matplotlibrc, как, например, подробно описано здесь
lunariusis, если я правильно понимаю, то в вашем случае latex отрисовывать не будет (не выставлен text.usetex = True), в результате чего все настройки латеха бессмыслены, но самое неприятное то, что кириллица то будет, а вот формулы - нет.
Не подскажите, как построить 3д поверхность plot_surface по данным из текстового файла? Формулы Z = f(X,Y) нет. Все данные в текстовом файле.
Вот тема на форуме с подробным описанием
Не знаю, актуально ли еще.
Вывод русского текста в matplotlib работает без проблем, если:
1. Указана кодировка
# -*- coding: utf-8 -*-
2. Перед текстом стоит символ Юникода:
plt.title(u’Траектория цели “‘ conf[8] ‘” => “‘ conf[7] ‘”‘) # некий живой пример