Питон для нормальных. Учебник Москва Базальт спо макс пресс 2018
Скачать 2.54 Mb.
|
если нет необходимости наблюдать несколько полотен одновременно, эффектив- нее один раз создавать полотно функцией figure, а потом на каждом шаге, например, цикла перерисовывать на нём новый рисунок, предварительно стирая предыдущий функцией clf(). 6.4 Гистограммы, диаграммы-столбцы Кроме обычных графиков, отражающих зависимость одной величины от дру- гой, бывает нужно построить графики другого типа, чаще всего это гистограм- мы. Гистограммы строят, чтобы следить за распределением некоторой величины. Если величина дискретна — каждому значению сопоставляют его частоту (число выпадений в данной реализации) или вероятность в процентах или долях едини- цы. Если величина изменяется непрерывно, её значения делят на диапазоны — бины, подсчитывая число попаданий в каждый диапазон. Для примера построим гистограммы равномерно на отрезке [0; 6] и нормально с параметрами µ = 0, σ = 3 распределённых случайных величин, сгенерировав по 10000 значений в каждом случае. Воспользуемся стандартным модулем random. 6.4. Гистограммы, диаграммы-столбцы 147 0 1 2 3 4 5 6 0 200 400 600 800 1000 1200 15 10 5 0 5 10 15 0 500 1000 1500 2000 2500 3000 0 1 2 3 4 5 6 0.00 0.05 0.10 0.15 0.20 0.25 15 10 5 0 5 10 15 0.00 0.02 0.04 0.06 0.08 0.10 0.12 0.14 (a) (b) Рис. 6.6. Пример построения гистограмм: (a) — использованы значения парамет- ров по умолчанию, в результате на обоих графиках наблюдаем по 10 бинов, а по вертикали отложено число попаданий в каждый из них; (b) — число бинов выставлено вручную и равно 100, по вертикали отложены значения плотности вероятности. f r o m random i m p o r t uniform , n o r m a l v a r i a t e f r o m m a t p l o t l i b . pyplot i m p o r t * v = [] f o r i i n r a n g e ( 1 0 0 0 0 ) : v . append ( uniform (0 , 6)) subplot (1 , 2 , 1) hist ( v ) w = [] f o r i i n r a n g e ( 1 0 0 0 0 ) : w . append ( n o r m a l v a r i a t e (0 , 3)) subplot (1 , 2 , 2) hist ( w ) show () Представленная программа делит весь диапазон от минимального до макси- мального значения на 10 бинов и рисует частоты — число попаданий в каждый бин (см. рис. 6.6(a)). Для 10000 значений 10 бинов — маловато, поэтому исполь- зуем необязательный параметр bins, принимающий целое число, равное желае- мому количеству бинов. А вместо частот нужно получить плотность вероятности (т. е. площадь под графиком должна равняться единице), для чего используем ещё один необязательный параметр normed, принимающий логическое значение. Изменим программу, указав дополнительные параметры: f r o m random i m p o r t uniform , n o r m a l v a r i a t e 148 Глава 6. Графики. Модуль matplotlib f r o m m a t p l o t l i b . pyplot i m p o r t * v = [] f o r i i n r a n g e ( 1 0 0 0 0 ) : v . append ( uniform (0 , 6)) subplot (1 , 2 , 1) hist (v , bins =100 , normed = True ) w = [] f o r i i n r a n g e ( 1 0 0 0 0 ) : w . append ( n o r m a l v a r i a t e (0 , 3)) subplot (1 , 2 , 2) hist (w , bins =100 , normed = True ) show () Теперь видим (см. рис. 6.6(b)), что по вертикали отложено уже знание плотно- сти вероятности, причём график стал более изрезанным, поскольку увеличилось число бинов, а число значеинй в каждом бине уменьшилось. Иногда полезными бывают диаграммы-столбцы. На таких диаграммах гори- зонтальный или вертикальный прямоугольник показывает своей длиной вклад, вносимый каждым участником. Главная его задача состоит в сравнении этих количественных показателей. Для визуализации используется функция bar(), принимающая две последо- вательности координат: x, определяющих левый край столбца, и y, определяю- щих высоту. Ширина прямоугольников по умолчанию равна 0.8. Но этот и другие параметры можно менять за счёт необязательных именованных параметров: f r o m numpy i m p o r t * f r o m random 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 * data1 = [] data2 = [] data3 = [] f o r i i n r a n g e (10): data1 . append ( n o r m a l v a r i a t e (5 , 0.5)) data2 . append ( n o r m a l v a r i a t e (5 , 0.5)) data3 . append ( n o r m a l v a r i a t e (5 , 0.5)) locs = arange (1 , l e n ( data1 )+1) width = 0.2 bar ( locs , data1 , width = width , color = ’ blue ’) bar ( locs + width , data2 , width = width , color = ’ red ’) bar ( locs +2* width , data3 , width = width , color = ’ green ’) xticks ( locs + width *1.5 , locs ) show () В данном примере width задает ширину прямоугольника, color задает цвет прямоугольника. Опционно можно дописать xerr, yerr, которые позволяют уста- навливать error bars. Далее генерируем последовательности трёх видов данных 6.5. Круговые и контурные диаграммы 149 (data) для пяти точек. Задаем переменную, которая будет определять толщину столбцов. Первый аргумент bar() имеет такой вид для того, чтобы три столбца стояли вместе, впритык друг к другу. Также здесь применяется фокус с функци- ей xticks, позволяющей изменять засечки на оси абсцисс, и мы смещаемся так, чтобы аргумент, породивший три своих столбца, стоял посередине — рис. 3(a). Часто используют и горизонтальное расположение. Оно описывается практиче- ски также, но вместо функции bar() используется barh(). Более того, такого рода диаграмм и возможностей существует великое множество, и вы сами може- те ознакомиться с ними по документации matplotlib. 6.5 Круговые и контурные диаграммы Достаточно распространённым способом графического изображения структу- ры статистических совокупностей является секторная диаграмма, так как идея целого очень наглядно выражается кругом, который представляет всю совокуп- ность. Относительная величина каждого значения изображается в виде сектора круга, площадь которого соответствует вкладу этого значения в сумму значений. Этот вид графиков удобно использовать, когда нужно показать долю каждой ве- личины в общем объёме. Секторы могут изображаться как в общем круге, так и отдельно, расположенными на небольшом удалении друг от друга. Круговая диаграмма сохраняет наглядность только в том случае, если ко- личество частей совокупности диаграммы небольшое. Если частей диаграммы слишком много, её применение неэффективно по причине несущественного раз- личия или малого размера сравниваемых структур. Недостаток круговых диа- грамм — малая информационная ёмкость, невозможность отразить более широ- кий объём полезной информации. Нарисуем круговую диаграмму средствами matplotlib’a — рис. 3(b): f r o m m a t p l o t l i b . pyplot i m p o r t * data = [18 , 15 , 11 , 9 , 8 , 6] labels = [ ’ Java ’ , ’C ’ , ’C ++ ’ , ’ PHP ’ , ’ Python ’ , ’ Ruby ’] explode = [0 , 0 , 0 , 0 , 0.2 , 0] axes ( aspect =1) pie ( data , labels = labels , explode = explode , autopct = ’ %1.1 f %% ’ , shadow = True ) show () Данная программа задаёт набор данных (data), добавляет на рисунок оси с соотношением сторон 1:1 (axes), строит график в виде круговой диаграммы (pie). Первым аргументом функция pie принимает последовательность дан- ных, затем code задаёт имена, по одному на каждый элемент data, далее за- даётся explode — маска, по которой «вырезается кусок пирога», autopct задаёт тип форматирования численных значений, shadow добавляет тень. Как обычно, цвет чередуется сам собою, порядок по умолчанию для matplotlib это ’blue’, ’green’ , ’red’, ’cyan’, ’magenta’, ’yellow’, ’black’. 150 Глава 6. Графики. Модуль matplotlib Ещё одним специализированным видом графиков являются контурные диа- граммы. Проще всего понять, что это такое, если вспомнить физическую кар- ту миры: там высоты и глубины обозначены цветом от тёмно-коричневого до тёмно-синего, а значения разделены на диапазоны, внутри которых все значения красятся единым цветом. Контурная диаграмма — способ представления трёх- мерной поверхности как бы «сверху». Чтобы построить контурную диаграмму с помощью matplotlib, нужно за- дать три двумерных массива одинаковой формы: массив значений координаты x для каждого узла сетки, массив координаты y и массив значений функции от них z = f (x, y). Если функция f нам известна, нужно определить пределы изме- нения x и y и задать шаг их изменения по каждой из осей, т. е. сетку. Это можно сделать с помощью функции arange. Далее из одномерных массивов, задающих сетку, нужно получить двумерные, содержащие координаты x и y в каждом узле сетки; это можно сделать командою meshgrid, как показано в примере далее. Сама контурная диаграмма строится с помощью команды contour, которой в качестве параметров передаются все три массива: x, y и z: 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 . mlab i m p o r t * x = arange ( -3 , 3 , 0.01) y = arange ( -2 , 2 , 0.01) X , Y = m e s h g r i d (x , y ) Z = X **2 -4* Y **2+ Y **4 contour (X , Y , Z ) show () Представленная программа строит контурную диаграмму функции (см. цвет- ную вкладку рис. 4(a)) с помощью линий уровней. Можно всё залить цветом, как на физической карте мира. Для этого необходимо использовать функцию contourf (см. цветную вкладку рис. 4(b)). Конечно, на практике значения массивов x, y и z будут, скорее всего, извест- ны и прибегать к таким ухищрениям не придётся. Тем не менее, предложенный пример — хорошая иллюстрация того, как построить график функции двух пе- ременных, не прибегая к изометрической проекции. 6.6 Трёхмерные графики В matplotlib кроме двумерных существует возможность построения трёх- мерных графиков. Для это используется модуль mplot3d. Для того, чтобы нарисовать трехмерный график, в первую очередь надо создать трехмерные оси. Они задаются как объект класса mpl_toolkits.mplot3d.Axes3D, кон- структор которого ожидает как минимум один параметр — экземпляр класса matplotlib.figure.Figure . У конструктора класса Axes3D есть ещё и другие 6.6. Трёхмерные графики 151 Рис. 6.7. 3D-оси. необязательные параметры, но пока мы их использовать не будем. Давайте на- рисуем пустые оси (рис. 6.7): 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 p l _ t o o l k i t s . mplot3d i m p o r t Axes3D fig = figure () Axes3D ( fig ) show () Полученные оси вы можете вращать мышкой в интерактивном режиме. А теперь нарисуем что-нибудь трёхмерное в полученных осях. Можно рисо- вать один каркас (wireframe, см. цветную вкладку рис. 5(a)), а можно — поверх- ность (surface, см. цветную вкладку рис. 5(b)): f r o m m a t p l o t l i b . pyplot i m p o r t * i m p o r t numpy as np f r o m m p l _ t o o l k i t s . mplot3d i m p o r t Axes3D fig = figure () ax = Axes3D ( fig ) u = np . l i n s p a c e (0 , 2 * np . pi , 100) v = np . l i n s p a c e (0 , np . pi , 100) x = 10 * np . outer ( np . cos ( u ) , np . sin ( v )) y = 10 * np . outer ( np . sin ( u ) , np . sin ( v )) z = 10 * np . outer ( np . ones ( np . size ( u )) , np . cos ( v )) ax . p l o t _ s u r f a c e (x , y , z , color = ’ grey ’) savefig ( ’3 D . png ’) show () 152 Глава 6. Графики. Модуль matplotlib Функция linspace как и функция arange создаёт массив значений, каждое следующее из которых больше предыдущего на одну и ту же величину. Напом- ним, что arange(start, stop, step) принимает три основных аргумента: нача- ло, конец, шаг; linspace(start, stop, num, endpoint=True) также принима- ет три обязательных аргумента: начало, конец и число значений, расположен- ных между ними, а кроме того у неё есть ещё необязательный четвёртый аргу- мент endpoint, который принимает логические значения. Если endpoint=True (это значение по умолчанию), то конечное значение stop будет включено в ге- нерируемый диапазон и расстояние между соседними значениями будет равно (stop-start)/(num-1) , иначе оно не будет включено и расстояние между ними будет равно (stop-start)/num. 6.7 Учёт ошибок В реальности эксперимент даже при максимальной точности измерений все- гда вносит свою погрешность. Например, при снятии вольт-амперной характе- ристики (ВАХ) диода в трёх экспериментах получаются немного разные значе- ния тока. С помощью errorbar можно построить среднее значение и отложить разброс (рис. 6.8). Для того, чтобы учесть это и указать возможный разброс во- круг значения, считаемого истинным, вводят планки погрешностей ( функция errorbar ), которые на кривой для полученных точек показывают своеобразный доверительный интервал: 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 ’] x = arange (0 , 2.2 , 0.2) y1 = [0 , 10 , 24 , 39 , 55 , 73 , 87 , 130 , 140 , 150 , 200] y2 = [0 , 11 , 25 , 41 , 58 , 66 , 94 , 135 , 140 , 160 , 170] y3 = [0 , 10 , 24 , 40 , 57 , 70 , 90 , 130 , 145 , 160 , 180] y = c o l u m n _ s t a c k ([ y1 , y2 , y3 ]) e r r o r b a r (x , mean (y , axis =1) , yerr =[ std (y , axis =1) , std (y , axis =1)] , marker = ’. ’ , color = ’ black ’) title ( ’Вольт-амперная характеристика’) xlabel ( ’Напряжение, В’ ); ylabel ( ’Ток, мкА’) show () В примере с помощью функции arange() был создан диапазон изменения напряжения от 0 В до 2 В с шагом 0.2 В. Далее результаты трёх серий изме- рений были представлены в виде трёх списков: y1, y2, y3. С помощью функции column_stack из нескольких одномерных массивов или списков одинаковой дли- ны можно сделать двумерный массив. Далее вызывается функция errorbar. В качестве первого аргумента передаём диапазон изменения напряжения. В каче- 6.8. Примеры построения графиков 153 0.0 0.5 1.0 1.5 2.0 , 0 50 100 150 200 , - Рис. 6.8. ВАХ диода, усреднённая по трём экспериментам с отложенными план- ками погрешностей. стве второго — среднее (mean) по трём измерениям значение тока. В качестве третьего (yerr) — разброс значений тока (std). Рассмотренные в данном примере планки погрешностей симметричны относи- тельно среднего значения, но существует возможность рисовать и несимметрич- ные отклонения. Их можно задать в той же функции с помощью списка из двух разных последовательностей: первой для отрицательных отклонений, второй — для положительных. 6.8 Примеры построения графиков Пример задачи 17 (Затухающая синусоида, вариант 1) Постройте гра- фик затухающей синусоиды e − x sin(2πx) на отрезке [0; 10], используя шаг по абсциссе, равный 0.1. Решение задачи 17 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 * x = arange (0 , 10 , 0.1) f = exp ( - x )* sin (2* pi * x ) plot (x , f ) show () 154 Глава 6. Графики. Модуль matplotlib 0 2 4 6 8 10 0.6 0.4 0.2 0.0 0.2 0.4 0.6 0.8 0 2 4 6 8 10 0.6 0.4 0.2 0.0 0.2 0.4 0.6 0.8 (a) (b) Рис. 6.9. Иллюстрация к задачам 17 — (a) и 18 — (b). Пример задачи 18 (Затухающая синусоида, вариант 2) Для построен- ного в предыдущем задании графика измените: цвет линии, тип линии и маркеров, шаг выборки данных, введите сетку и сохраните полученный график в файл. Решение задачи 18 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 * x = arange (0 , 10 , 0.01) f = exp ( - x )* sin (2* pi * x ) plot (x , f , ’ -o ’ , color = ’ black ’) grid ( True ) savefig ( ’ plot . png ’) show () Пример задачи 19 (Семейство затухающих синусоид) Постройте се- мейство функций e − x sin(2πx + φ 0 ) на одном графике различными цветами при φ 0 = 0, φ 0 = π/6 и φ 0 = π/3. Сделайте для графика легенду. Решение задачи 19 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 * x = arange (0 , 10 , 0.01) 6.8. Примеры построения графиков 155 f1 = exp ( - x )* sin (2* pi * x ) f2 = exp ( - x )* sin (2* pi * x + pi /6) f3 = exp ( - x )* sin (2* pi * x + pi /3) plot (x , f1 , label = r ’$ \ sin (2\ pi Ђ x ) $ ’) plot (x , f2 , label = r ’$ \ sin (2\ pi Ђ x Ђ + Ђ \ pi Ђ /6) $ ’) plot (x , f3 , label = r ’$ \ sin (2\ pi Ђ x Ђ + Ђ \ pi Ђ /3) $ ’) legend ( loc = ’ best ’) grid ( True ) show () Пример задачи 20 (Семейство графиков с затухающими синусоидами) Перестройте графики так, чтобы каждая кривая располагалась на одном графике с помощью команды subplot, легенду уберите, а её текст пере- местите в название соответствующего графика. Графики расположите на полотне в один столбец. Решение задачи 20 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 * x = arange (0 , 10 , 0.01) f1 = exp ( - x )* sin (2* pi * x ) f2 = exp ( - x )* sin (2* pi * x + pi /6) f3 = exp ( - x )* sin (2* pi * x + pi /3) subplot (3 , 1 , 1) plot (x , f1 ) title ( r ’$ \ sin (2\ pi Ђ x ) $ ’) grid ( True ) subplot (3 , 1 , 2) plot (x , f2 ) title ( r ’$ \ sin (2\ pi Ђ x Ђ + Ђ \ pi Ђ /6) $ ’) grid ( True ) subplot (3 , 1 , 3) plot (x , f3 ) title ( r ’$ \ sin (2\ pi Ђ x Ђ + Ђ \ pi Ђ /3) $ ’) grid ( True ) t i g h t _ l a y o u t () show () Пример задачи 21 Постройте закрашенную контурную диаграмму и трёхмерный график для функции двух переменных (6.1), определённой в прямоугольной области (x ∈ [−3; 3], y ∈ [−3; 3]): 156 Глава 6. Графики. Модуль matplotlib 0 2 4 6 8 10 0.6 0.4 0.2 0.0 0.2 0.4 0.6 0.8 1.0 sin(2πx) sin(2πx + π/6) sin(2πx + π/3) 0 2 4 6 8 10 0.6 0.4 0.2 0.0 0.2 0.4 0.6 0.8 sin(2πx) 0 2 4 6 8 10 0.6 0.4 0.2 0.0 0.2 0.4 0.6 0.8 1.0 sin(2πx + π/6) 0 2 4 6 8 10 0.6 0.4 0.2 0.0 0.2 0.4 0.6 0.8 1.0 sin(2πx + π/3) (a) (b) Рис. 6.10. Иллюстрация к задачам 19 — (a) и 20 — (b). |