Питон для нормальных. Учебник Москва Базальт спо макс пресс 2018
Скачать 2.54 Mb.
|
маркер вытянутый ромб ’D’ маркер квадрат, повёрнутый на 45 ◦ ’p’ маркер пятиугольник ’h’ маркер шестиугольник ’*’ маркер звёздочка ’+’ маркер плюс ’x’ маркер крестик, как знак умножения × ’ |’ маркер вертикальный отрезок ’_’ маркер горизонтальный отрезок В данном случае было использовано специальное именованное значение ’grey’ , соответствующее серому цвету. Существуют значения ’red’, ’black’, ’blue’ , ’yellow’, ’green’, ’magenta’, ’cyan’ и некоторые другие. Если желае- мый цвет не встречается среди именованных значений, можно воспользоваться кодировкою в стиле RGB — задать значения компонентов красного, зелёного и синего в долях от максимально возможного: 1 соответствует максимально воз- можной интенсивности каждого цвета, 0 — его нулевой интенсивности. Все три интенсивности ставятся в кортеж. Вот как получить темно-фиолетовый цвет: plot (x , ’: o ’ , color =(0.5 , 0 , 0.5)) show () Если вы хотите получить оттенок серого, вместо трёх чисел достаточно ука- зать только одно, поставленное в кавычки: plot (x , ’: o ’ , color = ’ 0.5 ’) show () 6.1. Простые графики 137 даст средне-серый цвет. Рассмотренный выше пример прост, но недостаточно полон: часто оказывает- ся необходимо отложить по оси абсцисс не номера точек, а какие-то осознанные значения. Это можно сделать, передав функции plot два списка. Рассмотрим этот случай на примере построения синусоиды: f r o m m a t p l o t l i b . pyplot i m p o r t plot , show f r o m math i m p o r t pi , sin t = [] x = [] f o r i i n r a n g e (400): t . append ( i *0.01) x . append ( sin (2* pi * t [ i ])) plot (t , x , color = ’ grey ’) show () Команда plot всегда пытается рассматривать первые аргументы как массивы со значениями до тех пор, пока не встретит именованный аргумент или строку. В приведённом примере (см. цветную вкладку рис. 1(a)) в качестве аргументов выступали 2 списка, первый интерпретируется как абсциссы точек, второй — как их ординаты. Можно построить несколько кривых на одном поле одною коман- дою, например, синус и косинус разом (для этого нужно указывать абсциссы и ординаты попеременно): f r o m m a t p l o t l i b . pyplot i m p o r t * f r o m math i m p o r t * t = [] x = [] y = [] f o r i i n r a n g e (400): t . append ( i *0.01) x . append ( sin (2* pi * t [ i ])) y . append ( cos (2* pi * t [ i ])) plot (t , x , t , y ) show () На полученных графиках (см. цветную вкладку рис. 1(b)) синусоида полу- чится синего цвета, а косинусоида — зелёного; это потому, что matplotlib само- стоятельно чередует цвета, если несколько кривых отображаются на одном гра- фике. Последние две строчки в программе можно было бы поменять следующим образом без изменения результата: plot (t , x ) plot (t , y ) show () 138 Глава 6. Графики. Модуль matplotlib Кроме просмотра графиков на экране современные графопостроители обяза- ны поддерживать вывод изображения в файл. В matplotlib это делается очень просто с помощью команды savefig, единственным обязательным аргументом которой является имя файла. Изменим последнюю строку предыдущей програм- мы так, чтобы она не только выводила график на экран, но и сохраняла его в файл ’sincos.png’ : plot (t , x ) plot (t , y ) savefig ( ’ sincos . png ’) show () При необходимости, вывод на экран можно убрать, вывод в файл от этого не пострадает. Важно только помнить, что функция show не только выводит изоб- ражение на экран, но и высвобождает буфер так, что он остаётся пуст. Поэтому перестановка местами функций savefig и show не скажется на выводе на экран, но в файл будет записано пустое полотно. Модуль matplotlib поддерживает несколько популярных форматов, в част- ности png для растровой графики, eps и pdf — для векторной. Можно сохранить график несколько раз, в том числе в файлы разных форматов: plot (t , x ) plot (t , y ) savefig ( ’ sincos . png ’) savefig ( ’ sincos . pdf ’) show () 6.2 Заголовок, подписи, сетка, легенда Если график строится просто для себя, и его не планируется вставлять, на- пример, в научную статью или диплом, представленных выше возможностей matplotlib может показаться достаточным. Но чтобы показать его другим лю- дям, да и самому не забыть, что нарисовано и что по какой оси отложено, полезно уметь ставить подписи. Простейшие подписи: заголовок и подписи к осям ставят- ся командами title, xlabel и ylabel, принимающими единственный аргумент — строку: f r o m numpy i m p o r t * f r o m m a t p l o t l i b . pyplot i m p o r t * t = arange (0 , 4 , 0.01) x = sin (2* pi * t ) y = cos (2* pi * t ) plot (t , x , t , y ) title ( ’ Voltage Ђ over Ђ time ’) xlabel ( ’ time , Ђ s ’) 6.2. Заголовок, подписи, сетка, легенда 139 ylabel ( ’ voltage , Ђ V ’) show () Заметим, что на практике всё же удобнее работать не со списками, а с массивами, что мы продемонстрировали здесь, заменив явный цикл операциями с массивами из модуля numpy. Команды plot, title, xlabel и др. формируют изображение, поэтому они должны предшествовать командам вывода типа savefig или show; порядок друг относительно друга — произвольный. Часто необходимо, чтобы в подписях на осях или легенде содержались верх- ние или нижние индексы, греческие буквы, различные значки и прочие матема- тические символы. Для этого matplotlib имеет режим совместимости с коман- дами L A TEX. Чтобы использовать его, нужно поставить перед строкою символ ’r’ , поскольку и в Python, и в L A TEXсимвол ’\’ является специальным и вво- дит команды. Строка, начинающаяся с ’r’, называется сырою. В такой строке все символы интепретируются как они есть, в том числе ’\t’ и ’\n’ не будут означать табуляцию и конец строки, а просто будут парами символов. Внутри сырой строки нужно поставить символ ’$’, с которого начинается и которым заканчивается формула L A TEX. Внутри пары из ’$’ можно использовать многие специальные обозначения: ’_’ для нижнего индекса (см. рис. 6.2(b)), ’ˆ’ — для верхнего. Если в индекс входит несколько символов, следует заключить их в фи- гурные скобки, служащие в L A TEXспециальными символами наряду с ’\’; причём сами фигурные скобки не отображаются. Кроме того, можно использовать почти все стандартные команды L A TEX, например, ’$\dot{x}$’ нарисует ’x’ с точкою наверху (будет выглядеть ˙x — так обозначают производную), а ’$\to$’ нарисует красивую стрелку слева направо (→, см. рис. 6.2(а)): xlabel ( r ’ $t$ , Ђс’ , f o n t s i z e =18) ylabel ( r ’ $E_ { cm }$ , ЂВ, $i_ { c }$ , мкА’ , f o n t s i z e =18) Если на графике несколько кривых, возникает желание как-то подписать их. Такая подпись, помещённая на график, как правило называется «легендой». Чтобы сделать легенду средствами matplotlib нужно, во-первых, указать при построении каждой кривой требуемую подпись с помощью параметра с клю- чевым словом label, во-вторых, вызвать специальную функцию legend, рису- ющую легенду. Для того, чтобы можно было использовать в подписях нела- тинские буквы, нужно установить шрифт, их поддерживающий. По умолча- нию matplotlib использует шрифты без засечек (в типографии такие шриф- ты принято обозначать по-французски «Sans Serif»), список которых содер- жится в переменной rcParams[’font.sans-serif’], где rcParams — словарь, а ’font.sans-serif’ — ключ. Если в вашей системе нужные шрифты не уста- новлены, либо не имеют необходимых символов, вместо букв получатся «кряко- зябры» или просто квадратики. В таком случае нужно переопределить перемен- ную rcParams[’font.sans-serif’], записав туда список шрифтов, в которых нужные символы имеются. Например, в Windows можно использовать шрифт ’Arial’ , как это показано ниже. 140 Глава 6. Графики. Модуль matplotlib 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 time, s 1.0 0.5 0.0 0.5 1.0 voltage, V Voltage over time 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 t , 1.0 0.5 0.0 0.5 1.0 E cm , , i c , Voltage over time (a) (b) Рис. 6.2. Графики с подписями и названием. f r o m numpy i m p o r t * f r o m m a t p l o t l i b . pyplot i m p o r t * f r o m m a t p l o t l i b i m p o r t r c P a r a m s r c P a r a m s [ ’ font . sans - serif ’ ]=[ ’ Arial ’] t = arange ( -1 , 1 , 0.01) x = t **2 y = t **3 z = t **4 plot (t , x , label = r ’ $x ^2 $ ’) plot (t , y , ’ -- ’ , label = r ’ $x ^3 $ ’) plot (t , z , ’: ’ , label = r ’ $x ^4 $ ’) legend () title ( ’Степенные одночлены’) show () Получившаяся программа строит легенду, но пока качество её нас не устраи- вает: во-первых, она налезает на графики, во-вторых, подписи выглядят не очень красиво — см. рис. 6.3(a). Чтобы исправить первый недостаток, нужно использо- вать параметр функции legend с названием loc, отвечающий за расположение. Параметр loc может принимать числовые значения с нуля по 10, либо соответ- ствующие им строковые значения типа ’upper right’ — верхний правый угол, или ’lower center’ — посредине внизу. Значение 0 соответствует строке ’best’ — Python сам пытается выбрать такое положение легенды, чтобы она не засло- няла график (см. рис. 6.3(b)). Ещё один часто встречающийся элемент графиков — сетка. Сетка используется для того, чтобы лучше видеть относительное распо- ложение далеко разнесённых значений. Для получения сетки нужно всего лишь 6.3. Несколько графиков на одном полотне 141 1.0 0.5 0.0 0.5 1.0 1.0 0.5 0.0 0.5 1.0 x 2 x 3 x 4 1.0 0.5 0.0 0.5 1.0 1.0 0.5 0.0 0.5 1.0 x 2 x 3 x 4 (a) (b) Рис. 6.3. Пример использования легенды: (a) — расположение по умолчанию, (b) — оптимальное расположение с дополнительно наложенною сеткою. добавить (как обычно, до savefig и show) в программу функцию grid. В итоге добавим в нашу программу ещё две строчки: legend ( loc = ’ best ’) grid ( True ) У функции grid единственный логический аргумент. Если его значение правда — сетка будет, если ложь — нет. 6.3 Несколько графиков на одном полотне Модуль matplotlib позволяет построить несколько графиков на одном по- лотне. Для этого существует команда subplot, определяющая, в какой части полотна расположен выводимый в настоящий момент график, и осуществляю- щая его масштабирование (по умолчанию, если subplot ни разу не использован, вывод осуществляется на всё полотно). Команда subplot имеет три обязатель- ных аргумента — целых числа. Первое означает, на сколько частей будет разде- лено полотно по вертикали, второе — по горизонтали (получается своеобразная сетка), третье — номер элемента в этой сетке, нумерация идёт сначала по гори- зонтали слева направо, потом по вертикали сверху вниз. Чтобы лучше понять работу subplot, создадим программу, рисующую графики различных одночле- нов на разных графиках. f r o m numpy i m p o r t * f r o m m a t p l o t l i b . pyplot i m p o r t * t = arange (0 , 2 , 0.01) x = sqrt ( t ) 142 Глава 6. Графики. Модуль matplotlib y = t z = sqrt ( t **3) u = t **2 v = sqrt ( t **5) w = t **3 subplot (3 , 2 , 1) plot (t , x , label = ’x **(1/2) ’) title ( r ’$ \ sqrt { x } $ ’) ylim ([0 , 5]) subplot (3 , 2 , 2) plot (t , y , label = ’x ’ , color = ’ red ’) title ( r ’ $x$ ’) ylim ([0 , 5]) subplot (3 , 2 , 3) plot (t , z , label = ’x **(3/2) ’) title ( r ’$ \ sqrt { x ^3} $ ’) ylim ([0 , 5]) subplot (3 , 2 , 4) plot (t , u , ’: ’ , label = ’x **2 ’) title ( r ’ $x ^2 $ ’) ylim ([0 , 5]) subplot (3 , 2 , 5) plot (t , v , label = ’x **(5/2) ’) title ( r ’$ \ sqrt { x ^5} $ ’) ylim ([0 , 5]) subplot (3 , 2 , 6) plot (t , w , label = r ’ $x ^3 $ ’) title ( r ’ $x ^3 $ ’) legend ( loc =0) grid ( True ) t i g h t _ l a y o u t () show () Из приведённого примера видно следующее. Во-первых, все команды постро- ения такие, как plot, xlabel, title и др., включая рисование сетки grid и ле- генды legend, относятся только к текущему графику. Во-вторых, для каждого графика стиль и цвет линий выставляется независимо (см. цветную вкладку рис. 2), поэтому, изменив цвет второго и стиль линий четвёртого, мы получили 6.3. Несколько графиков на одном полотне 143 цвет и стиль линий по умолчания для всех остальных, идущих как до, так и после. С помощью команды ylim([0, 5]) у всех графиков кроме последнего, задали фиксированные пределы по оси ординат. Функция tight_layout() обес- печивает расположение графиков на одном полотне без залезания друг на друга автоматически. Можно сделать так, чтобы графики на полотне занимали разный размер, например, сверху два, снизу — один. Дело в том, что функция subplot про- сто определяет положение графика на полотне, она не задаёт никакой реальной сетки. Поэтому могут одновременно встречаться графики, для которых сетка задана по-разному. Приведём пример из радиофизики. На выходах микрофона, передающей те- лекамеры и различных датчиков создаются низкочастотные сигналы с малой амплитудой. Таким сигналам свойственно большое затухание в пространстве и, следовательно, они не могут передавать информацию по каналам связи. Для эффективной передачи сигналов в произвольной среде необходимо перенести спектр данных сигналов из низкочастотной области в область высоких частот. Такой процесс называется модуляцией. Модуляция — процесс изменения одного или нескольких параметров высо- кочастотного несущего колебания по закону низкочастотного информационного сигнала (сообщения). Будем использовать амплитудную модуляцию — вид мо- дуляции, при которой изменяемым параметром несущего сигнала является его амплитуда. Передаваемая информация заложена в управляющем (модулирую- щем) сигнале (в данном примере x = cos(2πt)), а роль переносчика информа- ции выполняет высокочастотное колебание (y = cos(20 · 2πt)), называемое несу- щим. Модуляция, таким образом, представляет собой процесс «посадки» инфор- мационного колебания на заведомо известную несущую. Формула амплитудно- модулированного колебания выглядит следующим образом: z = (1 + M · x) · y, где M — глубина модуляции. Вот пример генерации и отображения такого модулированного сигнала на компьютере: f r o m numpy i m p o r t * f r o m m a t p l o t l i b . pyplot i m p o r t * r c P a r a m s [ ’ font . sans - serif ’ ]=[ ’ Arial ’] t = arange (0 , 10 , 0.001) x = cos (2* pi * t ) y = cos (20*2* pi * t ) z = (1+0.7* x )* y subplot (2 , 2 , 1) plot ( t [:2000] , x [:2000] , color = ’ black ’) title ( ’Модулирующий сигнал’) xlabel ( ’ Time , Ђ s ’) ylabel ( ’ Voltage , Ђ V ’) subplot (2 , 2 , 2) 144 Глава 6. Графики. Модуль matplotlib plot ( t [:2000] , y [:2000] , color = ’ black ’) title ( ’Несущий сигнал’) xlabel ( ’ Time , Ђ s ’) ylabel ( ’ Voltage , Ђ V ’) subplot (2 , 1 , 2) plot (t , z , color = ’ black ’) title ( ’AM -сигнал’) xlabel ( ’ Time , Ђ s ’) ylabel ( ’ Voltage , Ђ V ’) t i g h t _ l a y o u t () show () Здесь видно (см. рис. 6.4), что мы как бы «обманываем» matplotlib: для графиков y и z мы говорим, что будем размещать графики по схеме 2 × 2, а для графика x — по схеме 2 × 1. В результате третий график занимает всю нижнюю половину, как будто он второй из двух, а первые — каждый по четверти в верхней половине, как первый и второй из четырёх. Часто бывает так, что требуется построить не несколько графиков в одном окне, а несколько окон с графиками; такая возможность в matplotlib предусмот- рена. Например, вам нужно построить несколько разных рисунков и сохранить каждый в отдельный файл. Для этого нужно воспользоваться функцией figure. Вызов figure подобен вызову subplot в том смысле, что рисование начинается заново, а все ранее нарисованные объекты: сами графики, подписи к ним, сет- ка, легенда и проч. остаются на предыдущем полотне (или полотнах). Разница в том, что subplot размещает новый график в пределах всё того же полотна, а figure просто создаёт новое. Вот что будет, если переписать предыдущий пример с помощью figure: f r o m numpy i m p o r t * f r o m m a t p l o t l i b . pyplot i m p o r t * t = arange (0 , 1 , 0.001) x = sin (10* pi * t ) y = t z = sqrt ( t **3) figure (1) plot (t , y ) figure (2) plot (t , z ) figure (3) plot (t , x ) show () В использованном примере у функции figure только один аргумент — номер создаваемого полотна. Номер этот полезен тем, что в любой момент вы можете вернуться к уже начатому графику и что-то там дорисовать; для этого просто 6.3. Несколько графиков на одном полотне 145 0.0 0.5 1.0 1.5 2.0 Time, s 1.0 0.5 0.0 0.5 1.0 Voltage, V 0.0 0.5 1.0 1.5 2.0 Time, s 1.0 0.5 0.0 0.5 1.0 Voltage, V 0 2 4 6 8 10 Time, s 2.0 1.5 1.0 0.5 0.0 0.5 1.0 1.5 2.0 Voltage, V - Рис. 6.4. Пример нескольких графиков различного размера на одном полотне. необходимо сменить «фигуру» на ту, где вы уже рисовали. Так же полотну можно задать нужные размеры. Это делается с помощью именного аргумента figsize функции figure. Этот аргумент задаётся в виде кортежа из двух чисел — ширина и высота полотна. Вот пример: i m p o r t numpy as np i m p o r t m a t p l o t l i b . pyplot as plt t = np . arange ( -1.0 , 1.0 , 0.001) x = np . sin (2* np . pi * t ) y = np . cos (5* np . pi * t ) plt . figure (1 , figsize = (8 ,3)) plt . plot (t , x ) plt . figure (2) plt . plot (t , y ) plt . ylabel ( ’ cos ( t ) ’) plt . figure (1) plt . ylabel ( ’ sin ( t ) ’) 146 Глава 6. Графики. Модуль matplotlib Рис. 6.5. Пример вызова нескольких полотен (figure). plt . grid ( True ) plt . show () Здесь мы сначала нарисовали первую синусоиду в первом окне, потом вторую во втором, а затем вернулись к первому окну и доделали подписи к осям и сетку (рис. 6.5). Создание каждого нового полотна потребляет оперативную память. Поэтому, |