Введение в научный Python-1. Введение в научный Python
Скачать 6.2 Mb.
|
4 . Графические возможности 4.1 Двумерные графики matplotlib Основные графические возможности «научного» Python реализованы функциями, сосредоточенными в пакте matplotlib, являющегося аналогом графических инструментов MATLAB. Вначале определите версию вашего пакета matplotlib. import matplotlib as mpl print (' Текущая версия ', mpl.__version__) Текущая версия 1.5.1 Matplotlib состоит из множества модулей. Основной из них – высокоуровневый модуль matplotlib.pyplot. Наиболее распространенный метод его вызова состоит в выполнении следующей инструкции: import matplotlib.pyplot as plt Изображение в matplotlib создается путѐм последовательного вызова команд/функций этого модуля. Графические объекты (точки, линии, фигуры и т.д.) последовательно накладываются один на другой, если они занимают общие области на рисунке. Объектом самого высокого уровня при работе с matplotlib является рисунок (Figure). На нем располагаются одна или несколько областей рисования (Axes) и элементы оформления рисунка (заголовки, легенда и т.д.). Каждый объект Axes содержит две (или три) координатных оси Axis. Но основное назначение Axes состоит в том, что на него наносится графика: кривые, диаграммы, легенды и так далее. Создать рисунок figure позволяет инструкция: plt.figure() Чтобы результат рисования, то есть текущее состояние рисунка, отразилось на экране, можно воспользоваться командой plt.show(). После создания рисунка, т.е. экземпляра класса matplotlib.figure.Figure, результат выполнения всех графических команд будут отображаться именно в нѐм. Объект Figure может автоматически создаваться при первом выполнении какой – либо графической функции. Приступим к выполнению примеров. Наберите в Python Shell точно такие команды, и вы получите аналогичный рисунок. >>> import matplotlib.pyplot as plt >>> plt.plot([1, 3, 2, 4]) [ >>> plt.show() После ввода команды plt.show() и нажатия клавиши Enter , открывается окно Matplotlib с графиком. 108 В зависимости от используемого режима отображения, в его командном окне символ приглашения может появиться или не появиться. Если символ приглашения не появился, то вы сможете продолжать вводить команды только после закрытия графического окна. Функция plot. В приведенной, самой простой форме функции plot(), использован один вектор – список y– значений узлов ломаной, а в качестве x координат использованы целочисленные значения 0,1,2,.... В первой команде нашего примера мы импортировали модуль, используемый для построения графиков, и дали ему сокращенное имя plt. После этого мы использовали функцию plot() этого модуля, которая собственно и строит график. Затем вызвали функцию show(), которая его нам показывает. Зачастую, как мы говорили в п.1.2, вызов функции show()не требуется. В другой форме функция plot(...) использует два вектора – первый список значений независимой переменной, второй – список значений функции в этих точках. >>> import matplotlib.pyplot as plt >>> from math import sin >>> x=range(16) >>> y = [sin(t) for t in x] >>> plt.plot(list(x),y) [ >>> plt.show() Напомним, что в Python существует специальная синтаксическая конструкция, позволяющая создавать списки, называемая генератором списков. В предыдущем коде она записана строкой y=[sin(t) for t in x] Вся конструкция заключена в квадратные скобки, говорящие, что будет создан список. В начале внутри скобок стоит выражение, которое задает формулу для вычисления элементов списка. Потом идет цикл, в котором указывается имя 109 переменной цикла и диапазон, который эта переменная пробегает. В приведенном коде после создания списка y вызывается функция plot(). Чтобы для первого аргумента получить список, мы передали объект x в функцию list() , хотя в этом примере функцию list можно было бы не использовать. Когда точек много, ломаная неотличима от гладкой кривой >>> import numpy as np >>> X = np.linspace( -4, 4, 200) >>> C, S = np.cos(X), np.sin(X) >>> plt.plot(X, C) [ >>> plt.plot(X, S) [ >>> plt.show() Здесь в графическом окне сначала командой plt.plot(X,C) рисуется график косинусоиды, затем, командой plt.plot(X,S) – график синусоиды. Графики не видны, пока не выполнится команда plt.show() (в консоли Spyder графическое окно появляется сразу после выполнения функции plot()). В графическом окне имеется панель управления, которая состоит из нескольких кнопок. Поясним их назначение, перемещаясь слева направо. Первая кнопка, на которой изображен дом, возвращает просмотр графика к виду, который был создан при открытии окна. Вторая и третья кнопки со стрелками позволяют перемещаться между видами, которые могут иметь, например, разный масштаб, смещение и т.д. Четвертая кнопка (с крестом) имеет два возможных режима. Выбрав эту кнопку, а затем, зажав левую клавишу мыши, можно перемещать график в пределах окна. Нажав на эту кнопку, а затем, зажав правую клавишу мыши, можно менять масштаб изображения. Пятая кнопка позволяет увеличивать или уменьшать выбранную область графического окна. Нажатие шестой кнопки приводит к вызову панели настроек графического окна. Седьмая кнопка позволяет сохранить рисунок в графический файл. Когда графическое окно активно, то можно использовать горячие клавиши, заменяющие и дополняющие команды кнопок панели. Вот некоторые из них: h (home) первая кнопка (дом); c или ← вторая кнопка; v или → третья кнопка; удерживая x (или y) можно менять масштаб или перемещать изображение только по горизонтали (или вертикали); g – отображение сетки. 110 Управление внешним видом графика удобно, но не всегда нужно. Например, исполнительная система IPython позволяет отображать графики прямо в своем окне. Во многих случаях это удобнее, чем отображение в отдельнои окне. Прежде, чем продолжать, договоримся о среде выполнения графических примеров. Пусть это будет Spider. Откройте его. Если вы не меняли настроек, то слева у вас открыто окно редактора кода, а в правой нижней части расположены одна над другой панели двух консолей: Python и IPython. Команды можно выполнять в любой из них. Обычно консоль IPython настроена так, что графики будут отображаться прямо в ней. Захватите мышью заголовок окна IPython и перетащите его, расположив консоль IPython поверх редактора. Затем, если нужно, растяните границы окна консоли. Окно Spider примет следующий вид. Теперь продолжим обсуждение графических команд библиотеки matplotlib, имея в виду, что они вводятся и выполняются в интерпретаторе IPython Spyder. При этом при печати кодов примеров мы не будем использовать метки IPython, поскольку вы можете эти примеры выполнять и в других средах, имеющих другие метки, или не имеющие их вовсе. Кроме того, при отображении графиков мы не будем показывать рамки окна, поскольку окна может и не быть (для встраиваемой графики IPython). Отказ от встраиваемой (и статической) графики полезен в случае построения поверхностей. Трехмерные изображения в отдельном графическом окне можно «вращать» с помощью мыши, в то время как встроенные трехмерные изображения такой способностью пока не обладают. Напомним, что команда %matplotlib inline включает режим отображения графиков внутри окна IPython, а команда %matplotlib qt 111 включает режим отображения графиков в отдельном графическом окне. Выполните следующие команды. %matplotlib inline # включение режима встроенной графики в IPython import numpy as np import matplotlib.pyplot as plt # загружаем графический модуль Договоримся, что во всех последующих примерах, если не оговорено противное, действуют приведенные выше команды. Это значит, что к функциям модулей matplotlib.pyplot и numpy можно обращаться через их короткие имена plt и np. У функции plot имеется большое количество опций, предназначенных для оформления графиков. Можно задавать цвет, стиль линий и маркеры с помощью «форматной» строки следующим образом plot(x, y, 'цвет стиль маркер') (пробелы не обязательны). Цвета определяются символами (по первым буквам английских названий цветов): c , m , y , r , g , b, w, k (черный). Стиль линии определяются символами: „–„ (минус) сплошная линия, „—-‘ (два минуса) разрывная линия, „:’ (двоеточие) пунктирная линия, „–.’ (минус точка) штрих пунктирная. Наиболее часто встречаются маркеры: „s‟ – квадрат, „o‟ – круг, „p‟ – пятиугольник, „d‟ – ромб, „x‟ – крест, „*‟ – звезда, „+‟ – плюс, „h‟ – шестиугольник. x=np.linspace( -3,3,51) y=x**2*np.exp( -x**2) plt.plot(x, y, '-ko',linewidth=3, markersize=10) # следующий рисунок слева По следующей команде будет построен график, показанный на следующем рисунке в середине. plt.plot(x,y,' -wh',linewidth=3,markersize=20,markerfacecolor='b') Следующая команда построит рисунок, показанный на следующем рисунке справа. plt.plot(x, y, '--r',linewidth=3) # следующий рисунок справа Опции можно задавать, используя их название, которое позволяет легко понять их назначение. plt.plot(x, y, color= 'cyan', line,linewidth=4) # рис. слева Следующий рисунок справа построен командой plt.plot(x, y, color='red',linewidth=4, marker='o', markerfacecolor='blue',markersize =12) # следующий рисунок справа 112 Можно построить несколько кривых на одном графике. При этом для простой регулировки цветов и типов линий после пары x, y координат используется форматная строка. y2=x*np.exp(-x**2) plt.plot(x, y, '-k',x, y2, 'b--', linewidth=4) # следующий рисунок слева x=np.linspace( -1,1,100) plt.plot(x,x,x,x**2,x,x**3, linewidth=4) # предыдущий рисунок в центре Если задана опция line (апостроф+апостроф), то точки не соединяются линиями. Сами точки рисуются маркерами, типы которых должны быть указаны (иначе ничего не будет нарисовано). x=np.linspace( -1,1,41) plt.plot(x,x,'r-s',x,x**2,'b --p',x,x**3,'kd', linewidth=4, linestyle ='') # предыдущий рисунок справа Если в одной командной ячейке IPython используется несколько инструкций plot, то графики рисуются в общей области. Напомним, что в IPython Spyder, если вы желаете набрать несколько однострочных команд в одной ячейке, то после первой строки нужно нажать комбинацию клавиш Ctrl – Enter Последующие строки можно завершать клавишей Enter , а для завершения всей многострочной инструкции следует два раза нажать Enter (или один раз Shift – Enter ) x=np.linspace( -3,3,51) y1=x*np.exp( -x**2) y2=x**2*np.exp(-x**2) plt.plot(x,y1,'-ko',linewidth =3,markersize=10) #кривая 1 на след. рис. слева plt.plot(x,y2,'--b*',linewidth=5,markersize=14) #кривая 2 на след. рис. слева 113 Для других оформительских целей следует использовать функции модуля matplotlib.pyplot, которые должны следовать за функцией plot в той же ячейке, и которые влияют на активное графическое окно. x=np.linspace(0,2*np.pi,100) plt.plot(x, np.sin(x), ' -r', linewidth=5, label=r'$ \sin x$') plt.plot(x, np.cos(x), ' -b', linewidth=5, label=r'$ \cos x$') plt.legend(fontsize=12) # legend(loc='upper left') plt.title(r'$\sin x$, $\cos x$',fontsize=20) # предыдущий рисунок справа Здесь использована функция legend(), которая отображает легенды в графической области активного окна и, кроме того, задает размер шрифта легенд. Функция title() создает заголовок графика. Обратите внимание на строки, использованные для задания текста легенды и заголовка. Они могут содержать теги (команды) языка разметки текстов TeX, а символ „r‟, стоящий впереди, нужен для того, чтобы символы „\‟ (слэш) внутри строки не интерпретировались как спецсимволы. Если вы добавите к предыдущему коду инструкцию savefig("MyFirstGraph .png",dpi=200) то рисунок будет сохранен в соответствующий графический файл. Второй аргумент задает разрешение изображения. Теперь построим график функции x y 2 x=np.linspace(0,1,101) plt.plot(x,2*x) # следующий рисунок слева Физический наклон линии отличается от того, как мы себе это представляем из вида функции. Так получается потому, что по умолчанию задается разный масштаб в горизонтальном и вертикальном направлении. Изменить экранное соотношение высоты и ширины графической области можно с помощью команды set_aspect(число). Число определяет отношение длин осей графика (длина/высота). Вызов этой функции с единичным аргументом set_aspect(1) обеспечивает для нашего примера одинаковый масштаб по осям x и y. x=np.linspace(0,1,101) plt.plot(x,2*x) plt.axes().set_aspect(1) # предыдущий рисунок справа В методе set_aspect вместо числа допустимо использовать строки „auto‟ и „equal‟. Первое соответствует значению по умолчанию, второе – единице. Вот еще одна ситуация, когда полезно использовать функцию set_aspect(). На следующем графике слева синусоида выглядит густовато. x=np.linspace(0,40*np.pi,1000) plot(x,np.sin(x)) # следующий рисунок слева 114 График будет выглядеть лучше, если его растянуть (т.е. увеличить отношение ширина/высота) x=np.linspace(0,40*np.pi,1000) plot(x,np.sin(x)) axes().set_aspect(15) # предыдущий рисунок справа Прежде чем продолжить описание других графических возможностей, обсудим инструменты, которые предназначены для оформления графиков. Рассмотрим функции, которые выводят на графиках текст: в заголовках, на осях, печатают аннотации и т.д. Функция text(x,y,текст[,...]) выводит в области Axes текст. Положение текста определяется в координатах данных или, при задании опции transform=ax.transAxes , в относительных координатах 1 0 x , 1 0 y с началом (точка (0, 0)) в левом нижнем углу графической области. Здесь переменная ax является ссылкой на соответствующий объект Axes рисунка. Ее (ссылку) можно получить командой ax = fig.gca() (get current axes), где fig является ссылкой на объект рисунка. Опция fontsize=n функции text() задает размер шрифта, а опции horizontalalignment и verticalalignment определяют положение текста относительно точки привязки. Опция rotation задает угол поворота текста в градусах. Чтобы написать математическое выражение нужно окружить строку в формате TeX знаками доллара. Текст можно заключать в рамку с цветным фоном, передав аргумент bbox, который является словарем. Если вы не знаете TeX, не беда. Можно попросить Python написать TeX код для вашего выражения, используя функцию latex() модуля SymPy. >>> from sympy import latex,S # импортируем функции latex() и S() >>> latex(S('2*4+10',evaluate=False)) '2 \\cdot 4 + 10' >>> latex(S('exp(x*2)/2',evaluate=False)) '\\frac{e^{2 x}}{2}' Мы вводим строку, содержащую формулу, в обозначениях Python, а получаем строку, содержащую TeX код этой же формулы. Полученную строку вы можете затем использовать в функциях, отображающих текст в графическом окне. По умолчанию в matplotlib используются шрифты, которые не поддерживают кириллицу. Но это легко исправить. В Windows шрифты 'Arial', 'Times New Roman', 'Tahoma', 'Courier New' корректно отображают кириллицу. Чтобы их подключить, можно выполнить следующие команды: import matplotlib as mpl mpl.rcParams['font.family'] = ' fantasy' 115 mpl.rcParams['font. fantasy'] = 'Arial', 'Times New Roman', 'Tahoma' В результате создается набор шрифтов fantasy, который становится основным. Matplotlib будет стараться использовать первый шрифт Arial. Если его не окажется, то будет выбран второй по списку и так далее. Другим условием нормального отображения на рисунках кириллицы является использование UNICODE–строк. В Python 3 все строки являются юникодовыми, но можно также перед строкой поставить префикс u, обозначающий, что строка задана в кодировке UNICODE. str = u'Это юникод строка' # unicode-строка Не лишним будет в начале вашей программы вставить строку # -- coding: utf-8 – Функция matplotlib.pyplot.annotate(...) добавляет примечание, которое состоит из текста и стрелки, проведенной от текста в некоторую точку на рисунке. Она может иметь следующий формат вызова: annotate(текст, xy=(xa,ya), xytext=(xt, yt), shrink=0.05[,...]) Пара чисел (xa,ya) представляет координаты указываемой точки, а пара (xt,yt) – положение текстовой строки, опция shrink задает расстояние от конца стрелки до точки (xa,ya). Функции xlabel() и ylabel() задают подписи к осям. Они имеют одинаковый синтаксис, например, xlabel(„текст‟[,fontsize=‟small‟, verticalalignment=‟top‟, horizontalalignment=‟center‟,...]) Пример. Использование различных функций и их опций для оформления рисунка. # -*- coding: utf-8 -*- %matplotlib qt import numpy as np import matplotlib as mpl import matplotlib.pyplot as plt mpl.rcParams['font.family'] = 'fantasy' mpl.rcParams['font.fantasy'] = 'Arial','Times New Roman','Tahoma' str=r'$\frac{1}{\sigma\sqrt{2\pi}} \,e^{ -\frac{(x- \mu)^2}{2\sigma^2}}$' x=np.linspace(-3,5,40) sigma=1 mu=1 y=(1/(sigma*np.sqrt(2*np.pi)))*np.exp( -(x-mu)**2/(2*sigma**2)) fig = plt.figure(facecolor='white',num=' Пример оформления графика') plt.plot(x,y,' -bo',linewidth=3,markersize=10,label=str) plt.legend(fontsize=18, loc='upper left') ax = fig.gca() # получить ссылку на объект axes рисунка fig plt.title( r'$\mu=1,\ \sigma=1$') plt.text(0.58, .95,r' График функции $\varphi(x)$', horizontalalignment='left',verticalalignment='center', 116 transform=ax.transAxes, fontsize=16) # положение в относительных координатах окна ax.annotate(' Максимум', xy=(1, 0.4), xytext=(-2, 0.25), arrowprops=dict(facecolor='green', shrink=0.05)) plt.text( -0.9, 0.15, ' График кривой', rotation=70, horizontalalignment='center',verticalalignment='center') plt.text(2.5, 0.3, str, fontsize=24, bbox=dict(edgecolor='w', color='cyan'), color='black') # положение в координатах данных plt.xlabel(u'X- ось абсцисс',{'fontname':'Times New Roman'}) plt.ylabel(r'$\varphi(x)$ - ордината') plt.grid(true) # Метка 1 для вставки кода В примере была использована инструкция ax = fig.gca() ( |