Matplotlib: Научная графика в Python

Шабанов Павел написал замечательный электронный учебник «Научная графика в Python».
Учебник состоит из 13 глав, объединённых в 3 части.
Первая часть посвящена знакомству с библиотекой matplotlib. Здесь изложены основы по созданию графики в matplotlib с помощью модуля pyplot.
Вторая часть описывает логическую структуру рисунка в matplotlib и раскрывает особенности работы с элементами рисунка разных иерархических уровней: рисунком, областями рисования, координатными осями, делениями осей. Показаны основы работы с matplotlib в объектно-ориентированном стиле.
Третья часть посвящена специальным элементам рисунка: легенде, цветовой шкале, особым видам области рисования и координатных осей.
Каждая глава учебника содержит краткое введение, список полезных электронных ресурсов по теме главы, практическое руководство и несколько примеров.
Часть I Основы matplotlib
- Глава 1 Библиотека matplotlib. Pyplot
- Глава 2 Основные графические команды
- Глава 3 Работа с текстом и шрифтами
- Глава 4 Цвет и цветовая палитра
Часть II Структура рисунка в matplotlib
- Глава 5 Рисунок
- Глава 6 Область рисования
- Глава 7 Мультиоконные рисунки
- Глава 8 Координатные оси
- Глава 9 Деления координатных осей
Часть III Специальные элементы рисунка в matplotlib
- Глава 10 Особенности координатных осей
- Глава 11 Графики в полярной системе координат
- Глава 12 Легенда
- Глава 13 Цветовая шкала
Это пособие по matplotlib действительно стоит прочитать.
Для вставки кода на Python в комментарий заключайте его в теги
- Модуль csv - чтение и запись CSV файлов
- Создаём сайт на Django, используя хорошие практики. Часть 1: создаём проект
- Онлайн-обучение Python: сравнение популярных программ
- Книги о Python
- GUI (графический интерфейс пользователя)
- Курсы Python
- Модули
- Новости мира Python
- NumPy
- Обработка данных
- Основы программирования
- Примеры программ
- Типы данных в Python
- Видео
- Python для Web
- Работа для Python-программистов
- Сделай свой вклад в развитие сайта!
- Самоучитель Python
- Карта сайта
- Отзывы на книги по Python
- Реклама на сайте
Использование библиотеки Matplotlib. Как рисовать графики вида y = f(x)
Эта заметка первая в серии коротких шпаргалок про использование библиотеки Matplotlib, поэтому начнем с самых простых примеров.
Следующий пример строит график функции f(x) = sin(x) / x:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# . Импортируем один из пакетов Matplotlib
import matplotlib. pyplot as plt
import numpy as np
# Будем рисовать график этой функции
def func ( x ) :
"""
sinc(x)
"""
return math . sin ( x ) / x if x != 0 else 1.0
if __name__ == '__main__' :
# Интервал изменения переменной по оси X
xmin = - 20.0
xmax = 20.0
# Количество отсчетов на заданном интервале
count = 200
# . Создадим список координат по оси X на отрезке [-xmin; xmax], включая концы
xlist = np. linspace ( xmin , xmax , count )
# Вычислим значение функции в заданных точках
ylist = [ func ( x ) for x in xlist ]
# . Нарисуем одномерный график
plt. plot ( xlist , ylist )
# . Покажем окно с нарисованным графиком
plt. show ( )
Если в качестве отсчетов по оси X используется последовательность 0, 1, 2, . len(ylist) - 1, то первый параметр можно опустить. Следующий пример это демонстрирует
График выглядит точно также с той лишь разницей, что координаты X отсчитываются от 0, а расстояние между точками считается равным 1.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# . Импортируем один из пакетов Matplotlib
import matplotlib. pyplot as plt
import numpy as np
# Будем рисовать график этой функции
def func ( x ) :
"""
sinc(x)
"""
return math . sin ( x ) / x if x != 0 else 1.0
if __name__ == '__main__' :
# Интервал изменения переменной по оси X
xmin = - 20.0
xmax = 20.0
# Количество отсчетов на заданном интервале
count = 200
# . Создадим список координат по оси X на отрезке [-xmin; xmax], включая концы
xlist = np. linspace ( xmin , xmax , count )
# Вычислим значение функции в заданных точках
ylist = [ func ( x ) for x in xlist ]
# . Нарисуем одномерный график
plt. plot ( ylist )
# . Покажем окно с нарисованным графиком
plt. show ( )
Если вызывать функцию plot() несколько раз подряд, то на график будут добавляться новые кривые. Следующий пример рисует два гарфика на одних осях:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# . Импортируем один из пакетов Matplotlib
import matplotlib. pyplot as plt
import numpy as np
# Будем рисовать график этой функции
def func ( x ) :
"""
sinc(x)
"""
return math . sin ( x ) / x if x != 0 else 1.0
if __name__ == '__main__' :
# Интервал изменения переменной по оси X
xmin = - 20.0
xmax = 20.0
# Количество отсчетов на заданном интервале
count = 200
# . Создадим список координат по оси X на отрезке [-xmin; xmax], включая концы
xlist = np. linspace ( xmin , xmax , count )
# Вычислим значение функции в заданных точках
ylist1 = [ func ( x ) for x in xlist ]
ylist2 = [ func ( x * 0.2 ) for x in xlist ]
# . Нарисуем одномерные графики
plt. plot ( xlist , ylist1 )
plt. plot ( xlist , ylist2 )
# . Покажем окно с нарисованным графиком
plt. show ( )
Результат работы этого скрипта выглядит следующим образом:

Вы можете подписаться на новости сайта через RSS, Группу Вконтакте или Канал в Telegram.
Записки программиста
Бывает, что нужно по-быстрому визуализировать какие-то данные — построить графики для презентации или вроде того. Есть много способов сделать это. Например, можно открыть CSV-файл в LibreOffice или Google Docs и построить графики в нем. Но что, если диаграммы нужно строить регулярно, а значит предпочтительнее делать это автоматически? Вот тут-то на помощь и приходит Python с его потрясающей библиотекой Matplotlib.
Примечание: Для решения той же задачи в свое время мне доводилось использовать Scala Chart. Однако, как вы сами сейчас убедитесь, Matplotlib куда гибче, да и графики у него получаются намного красивее. Если вас интересует тема визуализации данных, вам стоит обратить внимание на мои стары посты, посвященные Graphviz, а также JavaScript-библиотекам Flot и Dracula.
Не будем ходить вокруг да около, лучше сразу перейдем к примерам. Пожалуй, простейший график, который можно построить в Matplotlib, это график синуса и косинуса:
#!/usr/bin/env python3
# vim: set ai et ts=4 sw=4:
import matplotlib as mpl
import matplotlib . pyplot as plt
import math
dpi = 80
fig = plt. figure ( dpi = dpi , figsize = ( 512 / dpi , 384 / dpi ) )
mpl. rcParams . update ( { 'font.size' : 10 } )
plt. axis ( [ 0 , 10 , - 1.5 , 1.5 ] )
plt. title ( 'Sine & Cosine' )
plt. xlabel ( 'x' )
plt. ylabel ( 'F(x)' )
xs = [ ]
sin_vals = [ ]
cos_vals = [ ]
x = 0.0
while x < 10.0 :
sin_vals + = [ math . sin ( x ) ]
cos_vals + = [ math . cos ( x ) ]
xs + = [ x ]
x + = 0.1
plt. plot ( xs , sin_vals , color = 'blue' , linestyle = 'solid' ,
label = 'sin(x)' )
plt. plot ( xs , cos_vals , color = 'red' , linestyle = 'dashed' ,
label = 'cos(x)' )
plt. legend ( loc = 'upper right' )
fig. savefig ( 'trigan.png' )
Я думаю, что код не нуждается в пояснениях. В крайнем случае, вы можете полистать официальную документацию или почитать вывод help() в REPL’е.

Однако на практике часто нужно построить график функции не от абстрактного вещественного числа, а от вполне конкретного времени. И в этом случае хочется, чтобы по оси OX были подписаны не абстрактные 1, 2, 3, а вполне конкретные временные метки. Для примера рассмотрим построение графика регистрации новых доменов в зоне RU за разное время с разбивкой по регистраторам:
#!/usr/bin/env python3
# vim: set ai et ts=4 sw=4:
import matplotlib as mpl
import matplotlib . pyplot as plt
import matplotlib . dates as mdates
import datetime as dt
import csv
with open ( 'ru-newreg.csv' , newline = '' ) as f:
for row in csv . reader ( f , delimiter = ',' , quotechar = '"' ) :
if dates == [ ] :
dates = [
dt. datetime . strptime (
"<>-01" . format ( d ) ,
'%Y-%m-%d'
) . date ( )
for d in row [ 1 : ]
]
continue
values [ row [ 0 ] ] = row [ 1 : ]
dpi = 80
fig = plt. figure ( dpi = dpi , figsize = ( 512 / dpi , 384 / dpi ) )
mpl. rcParams . update ( { 'font.size' : 10 } )
plt. title ( 'RU New Domain Names Registration' )
plt. xlabel ( 'Year' )
plt. ylabel ( 'Domains' )
ax = plt. axes ( )
ax. yaxis . grid ( True )
ax. xaxis . set_major_formatter ( mdates. DateFormatter ( '%Y' ) )
ax. xaxis . set_major_locator ( mdates. YearLocator ( ) )
for reg in values. keys ( ) :
plt. plot ( dates , values [ reg ] , linestyle = 'solid' , label = reg )
plt. legend ( loc = 'upper left' , frameon = False )
fig. savefig ( 'domains.png' )
Данные были получены с ныне уже закрытого сайта stat.nic.ru, который, впрочем, все еще доступен на web.archive.org. Результирующий график:

Что еще часто строят, это столбчатые диаграммы. В качестве примера возьмем данные из заметки Поиск по географическим данным при помощи PostGIS и построим диаграмму, отображающую сколько точек на карте к какому типу (заправка, кафе и так далее) относятся. Чтобы было чуть интереснее, сделаем вид, что в прошлом году точек каждого вида было на 10% меньше, и попытаемся отразить это изменение:
#!/usr/bin/env python3
# vim: set ai et ts=4 sw=4:
import matplotlib as mpl
import matplotlib . pyplot as plt
import matplotlib . dates as mdates
import datetime as dt
import csv
data_names = [ 'cafe' , 'pharmacy' , 'fuel' , 'bank' , 'waste_disposal' ,
'atm' , 'bench' , 'parking' , 'restaurant' ,
'place_of_worship' ]
data_values = [ 9124 , 8652 , 7592 , 7515 , 7041 , 6487 , 6374 , 6277 ,
5092 , 3629 ]
dpi = 80
fig = plt. figure ( dpi = dpi , figsize = ( 512 / dpi , 384 / dpi ) )
mpl. rcParams . update ( { 'font.size' : 10 } )
plt. title ( 'OpenStreetMap Point Types' )
ax = plt. axes ( )
ax. yaxis . grid ( True , zorder = 1 )
xs = range ( len ( data_names ) )
plt. bar ( [ x + 0.05 for x in xs ] , [ d * 0.9 for d in data_values ] ,
width = 0.2 , color = 'red' , alpha = 0.7 , label = '2016' ,
zorder = 2 )
plt. bar ( [ x + 0.3 for x in xs ] , data_values ,
width = 0.2 , color = 'blue' , alpha = 0.7 , label = '2017' ,
zorder = 2 )
plt. xticks ( xs , data_names )
fig. autofmt_xdate ( rotation = 25 )
plt. legend ( loc = 'upper right' )
fig. savefig ( 'bars.png' )

Те же данные можно отобразить, расположив столбики горизонтально:
#!/usr/bin/env python3
# vim: set ai et ts=4 sw=4:
import matplotlib as mpl
import matplotlib . pyplot as plt
import matplotlib . dates as mdates
import datetime as dt
import csv
data_names = [ 'cafe' , 'pharmacy' , 'fuel' , 'bank' , 'w.d.' , 'atm' ,
'bench' , 'parking' , 'restaurant' , 'p.o.w.' ]
data_values = [ 9124 , 8652 , 7592 , 7515 , 7041 , 6487 , 6374 , 6277 ,
5092 , 3629 ]
dpi = 80
fig = plt. figure ( dpi = dpi , figsize = ( 512 / dpi , 384 / dpi ) )
mpl. rcParams . update ( { 'font.size' : 9 } )
plt. title ( 'OpenStreetMap Point Types' )
ax = plt. axes ( )
ax. xaxis . grid ( True , zorder = 1 )
xs = range ( len ( data_names ) )
plt. barh ( [ x + 0.3 for x in xs ] , [ d * 0.9 for d in data_values ] ,
height = 0.2 , color = 'red' , alpha = 0.7 , label = '2016' ,
zorder = 2 )
plt. barh ( [ x + 0.05 for x in xs ] , data_values ,
height = 0.2 , color = 'blue' , alpha = 0.7 , label = '2017' ,
zorder = 2 )
plt. yticks ( xs , data_names , rotation = 10 )
plt. legend ( loc = 'upper right' )
fig. savefig ( 'barshoris.png' )

И последний на сегодня вид диаграмм — круговая диаграмма, или «пирог». Для примера попробуем визуализировать распределение кафе по различным городам России:
#!/usr/bin/env python3
# vim: set ai et ts=4 sw=4:
import matplotlib as mpl
import matplotlib . pyplot as plt
import matplotlib . dates as mdates
import datetime as dt
import csv
data_names = [ 'Москва' , 'Санкт-Петербург' , 'Сочи' , 'Архангельск' ,
'Владимир' , 'Краснодар' , 'Курск' , 'Воронеж' ,
'Ставрополь' , 'Мурманск' ]
data_values = [ 1076 , 979 , 222 , 189 , 137 , 134 , 124 , 124 , 91 , 79 ]
dpi = 80
fig = plt. figure ( dpi = dpi , figsize = ( 512 / dpi , 384 / dpi ) )
mpl. rcParams . update ( { 'font.size' : 9 } )
plt. title ( 'Распределение кафе по городам России (%)' )
xs = range ( len ( data_names ) )
plt. pie (
data_values , autopct = '%.1f' , radius = 1.1 ,
explode = [ 0.15 ] + [ 0 for _ in range ( len ( data_names ) - 1 ) ] )
plt. legend (
bbox_to_anchor = ( - 0.16 , 0.45 , 0.25 , 0.25 ) ,
loc = 'lower left' , labels = data_names )
fig. savefig ( 'pie.png' )
Полученная круговая диаграмма:

Выше была рассмотрена лишь малая часть возможностей Matplotlib. Чтобы получить более полное представление о всей мощи этой библиотеки, советую заглянуть в галерею построенных с ее помощью графиков на официальном сайте. Что же до исходников к этому посту, как обычно, вы найдете их на GitHub.
А чем вы строите диаграммы и, если не секрет, как они при этом выглядят?
Вы можете прислать свой комментарий мне на почту, или воспользоваться комментариями в Telegram-группе.
Построение графиков в Python при помощи Matplotlib

Картиной можно выразить тысячу слов. В случае с библиотекой Python matplotlib, к счастью, понадобится намного меньше слов в коде для создания качественных графиков.
Однако, matplotlib это еще и массивная библиотека, и создание графика, который будет выглядеть «просто, нормально» обычно проходит через путь проб и ошибок. Использование однострочных линий для создания базовых графиков в matplotlib – весьма просто, но умело пользоваться остальными 98% библиотеки может быть сложно.
Эта статья – руководство для пользователей Python на начальном-среднем уровне по matplotlib, с использованием как теории, так и практических примеров. Обучение по практическим примерам может быть очень продуктивным, и дает возможность получить представление даже на поверхностном уровне понимания внутренней работы и макета библиотеки.
Что мы рассмотрим?
- Pylab и pyplot: кто есть кто?
- Ключевые концепции дизайна matplotlib;
- Понимание plt.subplots();
- Визуализация массивов при помощи matplotlib;
- Построение графиков с комбинацией pandas и matplotlib.
Эта статья подразумевает, что пользователь имеет хотя-бы минимальное представление о NumPy. Мы в основном будем пользоваться модулем numpy.random для создания «игрушечных» данных, рисовать примеры из различных статистических источников.
Есть вопросы по Python?
На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!
Telegram Чат & Канал
Вступите в наш дружный чат по Python и начните общение с единомышленниками! Станьте частью большого сообщества!
Паблик VK
Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!
Если у вас еще не установлен matplotlib, рекомендуем ознакомиться с руководством по установке, перед тем как продолжить.
python - mpip install - U pip
python - mpip install - U matplotlib
Почему Matplotlib может быть сложным?
Изучение matplotlib временами может быть тяжелым процессом. Проблема не в нехватке документации (которая весьма обширная, между прочим). Сложности могут возникнуть со следующим:
- Размер библиотеки огромный сам по себе, около 70 000 строк кода;
- Matplotlib содержит несколько разных интерфейсов (способов построения фигуры) и может взаимодействовать с большим количеством бекендов. (Бекенды отвечают за то, как по факту будут отображаться диаграммы, не только за внутреннюю структуру);
- Несмотря на обширность, часть собственной документации matplotlib серьезно устарела. Библиотека все еще развивается, и множество старых примеров в сети могут включать на 70% меньше кода, чем в их современной версии;
Так что, перед тем как мы перейдем к сложным примерам, не помешает освоить корневые концепции дизайна matplotlib.
Pylab: что это и нужно ли мне это?
Немножко истории: Нейробиолог Джон Д. Хантер начал разрабатывать matplotlib в 2003 году, в основном вдохновляясь эмуляцией команд программного обеспечения Mathworks MATLAB. Джон отошел в мир иной трагически рано, в возрасте 44 лет в 2012 году, и matplotlib на сегодняшний день является целиком и полностью продуктом сообщества: развивается и поддерживается множеством людей. (Джон говорил об эволюции matplotlib на конференции SciPy в 2012, которую однозначно стоит посмотреть.)
Одной из важных особенностей MATLAB является его глобальный стиль. Концепция импорта Python не сильно используется в MATLAB, и большинство функций MATLAB легко доступны для пользователя на верхнем уровне.
Заказать свой собственный уникальный номер можно от Сим-Трейд.ру. Быстрая доставка в день заказа и красивые номера начиная от 300 руб. с выгодным тарифным планом. Свой уникальный номер это хороший признак для введения бизнеса с момента первого звонка.
Понимание того, что корни matplotlib растут из MATLAB, помогает объяснить существование pylab. pylab – это модуль внутри библиотеки matplotlib, который был встроен для подражания общего стиля MATLAB. Он существует только для внесения ряда функций классов из NumPy и matplotlib в пространство имен, что упрощает переход пользователей MATLAB, которые не сталкивались с необходимостью в операторах импорта. Бывшие пользователи MATLAB (которые очень хорошие люди, обещаем!) полюбили его функционал, потому что при помощи from pylab import * они могут просто вызывать plot() или array() напрямую также, как они это делали в MATLAB.
Проблема здесь может быть очевидной для некоторых пользователей Python: использование from pylab import * в сессии или скрипте – как правило, плохая идея. Matplotlib сегодня прямым текстом рекомендуют не делать этого в своих руководствах:
[pylab] все еще существует по историческим причинам, но его использование не рекомендуется. Он перегружает пространства имен функциями, которые оттеняют надстройки Python и может привести к скрытым багам. Для получения интеграции IPython без использования импортов, рекомендуется использовать %matplotlib.
В глубине своей, существует целая тонна потенциально конфликтных импортов, замаскированных в коротком источнике pylab. Фактически, использование ipython —pylab (из терминала или командной строки) или %pylab (из инструментов IPython/Jupyter) легко вызывает from pylab import *
Суть в том, что matplotlib забросили этот удобный модуль и рекомендуют не использовать pylab, подтверждая ключевое правило Python – явное лучше, чем неявное.
Без необходимости в использовании pylab, мы всегда можем обойтись всего одним каноничным импортом: