Показаны сообщения с ярлыком pylab. Показать все сообщения
Показаны сообщения с ярлыком pylab. Показать все сообщения

20090403

Русские буквы в matplotlib/pylab

Усилиями некого Алексея сегодня мы все наконец узнали как в Matplotlib/Pylab делать подписи по-русски. Вот работающий пример:
#!/usr/bin/env pytnon
# vim: set fileencoding=utf-8 ts=4 sw=4 expandtab:

# Cyrillic letters in Matplotlib,
# thanks to Alexey for solution, see http://koldunov.net/?p=290#comments
from matplotlib import rc
rc('font',**{'family':'serif'})
rc('text', usetex=True)
rc('text.latex',unicode=True)
rc('text.latex',preamble='\usepackage[utf8]{inputenc}')
rc('text.latex',preamble='\usepackage[russian]{babel}')

from pylab import *

def figsize(wcm,hcm): figure(figsize=(wcm/2.54,hcm/2.54))
figsize(13,9)

x = linspace(0,2*pi,100)
y = sin(x)
plot(x,y,'-')
xlabel(u"ось абсцисс")
ylabel(u"ось ординат")
title(u"Две беды в России — синусы и косинусы!")
savefig('rus-mpl.pdf')
И вот результат:



По теме:
Matplotlib. Простые вещи — 1
Matplotlib. Простые вещи — 2
Как построить график с изолиниями в gnuplot, gri и pylab
Короткие «рецепты» по применению Python в околонаучных целях

PS. Как, кстати, лучше PDF в растр конвертировать? Я делаю так:
$ pdftoppm -r 300 image.pdf | convert ppm:- image.png
Дополнение: ещё лучше вариант предложил Дмитрий Душкин:
from matplotlib import rc
font = {'family': 'Droid Sans',
        'weight': 'normal',
        'size': 14}
И всё отлично работает.

20081111

Python на службе науки (черновик)

Не знаю, соберусь ли это дело систематизировать, пока буду просто добавлять в этот пост короткие «рецепты» по применению Python в околонаучных целях (создание отчётов, построение графиков и тому подобное). Поживём-увидим.

Преобразование числа из экспоненциальной формы (например, –1.2e+003) в формулу LaTeX (например, -1.2 10³). Регулярное выражение:
>>> import re
>>> re.sub('([\d.+-]+)[Ee]\+?([-]?)0*([\d]+)', '\\1 \\cdot 10^{\\2\\3} ','-1.2e+003')
'-1.2 \\cdot 10^{3} '


Прозрачные/полупрозрачные легенды (подписи) в графиках pylab:
l=legend()
l.get_frame().set_alpha(0.2)


Формулы LaTeX в подписях и надписях в pylab: просто заключить нужный фрагмент надписи в $…$, например '$\rho$'.

Открытый вопрос — как делать русские подписи в pylab? Дополнение: вопрос решился сам. См. заметку Русские буквы в matplotlib/pylab.

Произвольная надпись, выровненная по центру — (xlim()[0]+xlim()[1])*0.5, ha="center" — нижнего края — lim()[0], va="bottom") — графика в pylab:
text((xlim()[0]+xlim()[1])*0.5,ylim()[0],"your message",ha="center",va="bottom",fontsize=10)


Дана пара массивов (списков) t и x с временем измерения и измеренной величиной, отобрать только те пары время-значение, которые попадают в заданный временной интервал [t0, t1] (или какому другому условию):
xt=[ pair for pair in zip(x,t) if t0 <= pair[0] <= t1 ]


Из полученных пар выделить опять отдельные массивы t и x:
t=[pair[0] for pair in tx]
x=[pair[1] for pair in tx]
или с использованием array из scipy:
t,x=array(tx)[:,0],array(tx)[:,1]


Кусочно-линейная интерполяция зависимости t→x на другом наборе точек t2 (тоже список, как и t):
from scipy import interp
interp(t2,t,x)


Транспонирование двумерного массива — проще всего array([[1,2,],[3,4]]).transpose().

Линейная регрессия (аналогично — фиттирование более сложных функций, модифицировать количество параметров и вычисление ошибки в residual()). Как и прежде, предполагаю, что точки для фиттирования заданы в массивах t и x:
from scipy import array
from scipy.optimize import leastsq
def residual(params,t,x):
a,b=params
x_ab=array([a*x=t_i+b for t_i in t])
return x_ab-x
[a,b],ier=leastsq(residual,(1,1),args=(t,x))


Интегрирование системы обыкновенных дифференциальных уравнений (ОДУ):
from scipy import linspace, array
from scipy.integrate import odeint

def dotu(u,t0):
"расчёт производных в момент времени t0"
x,y,z=u # вектор переменных
sigma,rho,beta=10,28,8.0/3 # параметры модели
dotx=sigma*(y-x)
doty=x*(rho-z)-y
dotz=x*y-beta*z
return [dotx,doty,dotz]

t=linspace(0,50,1e4) # точки интегрирования
u0=[-5,-5,1] # начальное условие
u=odeint(dotu,u0,t) # решение


Чтобы построить график полученного решения (2D), транспонируем u и строим как обычно:
from pylab import plot, show
u=array(u).transpose()
plot(u[1],u[2]) # строим фазовый портрет y-z
show()

20080215

Как построить график с изолиниями в gnuplot, gri и pylab

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

Я покажу как это делается на примере сразу трёх свободных инструментов: gnuplot, gri и matplotlib (он же pylab). Именно этими тремя программами я пользуюсь чаще всего. В тексте буду давать ссылки на полный скрипт, используемый для построения графика, пояснять же буду самое основное. Все графики я буду строить в чёрнобелом варианте, сохраняя в формате EPS. Иллюстрации к этой статье получены последующей конвертацией EPS в PNG.

Итак, дано: файл с данными sampledata.txt, значения x, y, z в три колонки, массив 80×80 точек, каждый следующий «столбец» сетки (следующее значение x) отделён от предыдущего пустой строкой. Файлы такого формата использует gnuplot (для gri и для pylab потребуется преобразовать формат). Задача: построить график с изолиниями постоянного значения z.

Итак, способ первый,

строим график с изолиниями в gnuplot

Здесь всё просто. Отключаем построение поверхности, включаем построение изолиний, включаем «вид сверху», велим выбирать уровни автоматически:
unset surface
set contour
set view map
set cntrparam levels auto 10
Можно задать уровни изолиний и вручную:
set cntrparam levels discrete уровень1, уровень2, уровень3, …
Теперь команда
splot 'sampledata.txt' w l
будет строить график с изолиниями. И вот какой результат получается по-умолчанию в gnuplot:
график с изолиниями, построенный в gnuplot
(Запускал gnuplot так: $ gnuplot plotiso_gnulot.txt)


Способ второй,

строим график с изолиниями в gri

Честно говоря, я считаю, что gri справляется с изолиниями лучше, чем gnuplot. Во всяком случае, здесь, в отличие от gnuplot, значения можно надписать прямо на изолиниях, и есть реальная возможность управлять цветами изолиний при сохранении EPS (пользователей gnuplot в этом месте ждёт сюрприз). При этом gri остаётся инструментом достаточно простым для понимания.

Небольшое препятствие состоит лишь в том, что необходимо преобразовать формат данных. Gri хочет, чтобы каждая строка данных отделялась была отдельной строкой в файле, а точки были разделены пробелами. Здесь я использую такую возможность gri, как чтение данных из юниксового «пайпа», и делаю все нужные преобразования на лету с помощью awk:
open "awk ' /[^s]/ { printf($3 \" \"); } /^\s*$/ { print ; }' sampledata.txt |"
read grid data 80 80 bycolumns
close
Построение же собственно изолиний уже совсем просто:
draw contour
Вот что получает в gri:
график с изолиниями, построенный в gri
(gri я запускал так: $ gri -b -output iso_gri.eps < plotiso_gri.txt)


Способ третий,

строим изолинии в matplotlib/pylab

matplotlib — это библиотека для python. Её можно использовать как интерактивно, запуская ipython -pylab, так и внутри обычного скрипта; синтаксис команд построения графиков приближен к синтаксису matlab, но при этом можно использовать на полную возможности Python. А возможности у matplotlib весьма приличные.

Изолинии строятся одной командой:
cset=contour(X,Y,Z)
Здесь X, Y, Z — должны быть двумерными массивами одной и той же размерности. Кроме того, в скрипте я отключил раскраску изолиний по умолчанию, чтобы нарисовать все изолинии чёрным цветом (параметр colors='black'). Другие варианты использования contour можно прочитать в help contour, если запустить ipython -pylab.
Ещё одна команда добавляет к изолиниям подписи:
clabel(cset,fmt="%1.1f",fontsize=9)
Сохранить результат в файл нужного формата тоже просто:
savefig('pylab.eps')
Остальные строчки в скрипте — это преобразование формата данных средствами Python.
Дополнение: в новых версиях SciPy этот скрипт можно значительно упростить, если воспользоваться функцией loadtxt(), загружающей данные из текстового файла. То, что нам надо.
Вот что получается в итоге:
график с изолиниями, построенный в matplotlib/pylab
(скрипт я запускал так: $ python plotiso_pylab.txt)

☙ ☙ ☙

Конечно, выбор конкретного инструмента — вопрос удобства (имеющегося формата данных, требований к тонкостям настройки графики, имеющегося времени, опыта использования). Я хотел показать, что выбирать есть из чего, и построить на графике изолинии с любой из трёх рассмотренных программ — дело двух–трёх строчек. Совершенствовать же результат и настраивать тонкости отображения можно долго. На мой взгляд, в случае построения изолиний, gri и matplotlib предоставляют больше возможностей.

Хочу также заметить, что этими тремя программами список инструментов пригодных для построения графиков с изолиниями не исчерпывается. Надо отметить ещё Tioga, plotmtv, GMT, Asymptote. Есть и пакеты, ориентированные на 3D-данные, но которые можно использовать и для 2D: OpenDX, VTK, MayaVi. Вроде бы можно построить изолинии и в R (приличных примеров я не видел). Судя по документации, есть такая возможность и в scilab (но примеров того, что получается — я тоже не видел). Octave, как я понимаю, предоставляет лишь альтернативный интерфейс для gnuplot. Возможно, эту статью я в будущем дополню ещё какими-то примерами. Если кто-то активно строит графики с изолиниями в чём-то другом — предлагаю поделиться ссылкой на подобные инструкции. Ссылки буду добавлять ниже.

См. также:

Сравнение 9 программ для построения графиков
Цветные поверхности в gnuplot в режиме pm3d