Построение гистограмм в Python
В этой статье описывается построение графиков данных с помощью пакета Python pandas’.hist(). База данных SQL — это источник, используемый для визуализации интервалов данных гистограммы, имеющих последовательные, не перекрывающиеся значения.
Предварительные условия
- SQL Server для Windows или для Linux
- Управляемый экземпляр SQL Azure
- SQL Server Management Studio для восстановления образца базы данных в Управляемый экземпляр SQL Azure.
- Azure Data Studio. Сведения об установке см. в разделе Azure Data Studio.
- Восстановление образца базы данных DW для получения демонстрационных данных, используемых в этой статье.
Проверка восстановленной базы данных
Чтобы убедиться, что восстановленная база данных существует, выполните запрос к таблице Person.CountryRegion.
USE AdventureWorksDW; SELECT * FROM Person.CountryRegion;
Установка пакетов Python
Установите следующие пакеты Python.
- pyodbc
- pandas
- sqlalchemy
- matplotlib
Чтобы установить эти пакеты, выполните приведенные ниже действия.
- В записной книжке Azure Data Studio выберите Управление пакетами.
- В области Управление пакетами выберите вкладку Добавить новые.
- Для каждого из следующих пакетов введите имя пакета, нажмите Поиск, а затем — Установить.
Построение гистограммы
Распределенные данные, отображаемые в гистограмме, основаны на SQL-запросе. AdventureWorksDW2022 Гистограмма визуализирует данные и частоту значений данных.
Измените переменные строки подключения: «сервер», «база данных», «имя пользователя» и «пароль», чтобы подключиться к базе данных SQL Server.
Чтобы создать записную книжку:
- В Azure Data Studio выберите пункт Файл и Новая записная книжка.
- В записной книжке выберите ядро Python3 и нажмите + Код.
- Вставьте код в записную книжку и нажмите Запустить все.
import pyodbc import pandas as pd import matplotlib import sqlalchemy from sqlalchemy import create_engine matplotlib.use('TkAgg', force=True) from matplotlib import pyplot as plt # Some other example server values are # server = 'localhost\sqlexpress' # for a named instance # server = 'myserver,port' # to specify an alternate port server = 'servername' database = 'AdventureWorksDW2022' username = 'yourusername' password = 'databasename' url = 'mssql+pyodbc://:@:/?driver=SQL+Server'.format(user=username, passwd=password, host=server, port=port, db=database) engine = create_engine(url) sql = "SELECT DATEDIFF(year, c.BirthDate, GETDATE()) AS Age FROM [dbo].[FactInternetSales] s INNER JOIN dbo.DimCustomer c ON s.CustomerKey = c.CustomerKey" df = pd.read_sql(sql, engine) df.hist(bins=50) plt.show()
На экране отображается распределение возрастов клиентов в FactInternetSales таблице.
Рисуем гистограммы, столбчатые и круговые диаграммы
На этом занятии мы продолжим знакомство с разными типами двумерных графиков и увидим, как можно строить столбчатые и круговые диаграммы.
Гистограмма и столбчатые диаграммы
Иногда данные требуется сгруппировать по определенным диапазонам и подсчитать сколько значений попадает в тот или иной интервал. Для выполнения такой задачи хорошо подходят столбчатые диаграммы и довольно известный их вид – это гистограмма распределения случайной величины.
Давайте сгенерируем вектор из 500 случайных величин и выведем их в виде гистограммы, используя функцию hist():
import numpy as np import matplotlib.pyplot as plt fig = plt.figure(figsize=(6, 4)) ax = fig.add_subplot() y = np.random.normal(0, 2, 500) ax.hist(y) ax.grid() plt.show()
На выходе получим следующее изображение распределения нормальной СВ:
Фактически, мы здесь имеем набор столбиков, высота которых определяется числом СВ, попавших в тот или иной диапазон. Причем, по умолчанию функция hist() разбивает весь интервал на равных 10 диапазонов. Если требуется изменить это число, то мы можем его указать вторым параметром:
ax.hist(y, 50)

Прежний интервал теперь разбит на 50 диапазонов, столбиков стало больше и они выглядят тоньше.
Функции bar() и barh()
Похожий график можно сформировать и с помощью функции bar. Ей на вход, в самом простом варианте, нужно передать список отметок для столбцов x и значения высот каждого столбца y:
x = [f'H' for i in range(10)] y = np.random.randint(1, 5, len(x)) ax.bar(x, y)

Или, можно отобразить то же распределение нормальной СВ с помощью такой столбчатой диаграммы. Сначала сформируем сами величины и разобьем весь интервал на 10 равных диапазонов:
y = np.random.normal(0, 2, 500) x = np.linspace(np.min(y), np.max(y), 10)
Затем, подсчитаем, сколько величин попало в соответствующий диапазон и выведем список bars с помощью функции bar():
bars = [len(y[np.bitwise_and(y >= x[i], y x[i+1])]) for i in range(len(x)-1)] ax.bar(range(len(x)-1), bars)

Как видите, у нас получилось изображение аналогичное гистограмме. Только пришлось предварительно подготовить данные, что не очень удобно. Поэтому, когда нужно вывести распределение величин по диапазонам, то проще использовать функцию hist().
Если нам нужно отображать столбики относительно оси ординат, то для этого существует функция barh(), которая работает аналогично функции bar():
ax.barh(range(len(x)-1), bars)
В итоге, график будет выглядеть, следующим образом:
Использование библиотеки Matplotlib. Как рисовать гистограммы
Для построения гистограмм (диаграмм в виде набора столбиков) в Matplotlib используются функция bar() и barh(), которые строят вертикальные или горизонтальные гистограммы соответственно. Эти функции, как и другие функции рисования, импортируются из модуля matplotlib.pyplot или pyplot. Функции bar и barh имеют множество необязательных параметров с дополнительными настройками, мы в данной статье мы рассмотрим только наиболее часто используемые возможности для настройки внешнего вида гистограмм.
График без настройки внешнего вида
Для начала сначала рассмотрим простейший пример, где используются только обязательные параметры, их всего два.
- Список координат расположения столбиков по оси X для bar() или по оси Y для barh().
- Значения, задающие высоту (длину) столбиков.
Длины этих двух списков должны быть равны.
Наш первый пример будет выглядеть так:
import matplotlib. pyplot as plt
if __name__ == ‘__main__’ :
xdata = [ 0 , 1 , 2 , 4 , 5 , 8 ]
ydata = [ 0.1 , 0.2 , 0.4 , 0.8 , 0.6 , 0.1 ]
plt. bar ( xdata , ydata )
plt. show ( )
После запуска программы мы увидим график:

Или аналогично для функции barh():
import matplotlib. pyplot as plt
if __name__ == ‘__main__’ :
xdata = [ 0 , 1 , 2 , 4 , 5 , 8 ]
ydata = [ 0.1 , 0.2 , 0.4 , 0.8 , 0.6 , 0.1 ]
plt. barh ( xdata , ydata )
plt. show ( )

Выравнивание меток относительно столбцов
Как видно из примеров, по умолчанию метки на осях расположены по центру столбцов. Это поведение можно изменить с помощью именованного параметра align, который может принимать строковые значения ‘center’, что соответствует значению по умолчанию, или ‘edge’, в этом случае метки по осям будут расположены в начале столбиков. Добавим в нашем примере параметр align=’edge’ и посмотрим, что из этого получится:
import matplotlib. pyplot as plt
if __name__ == ‘__main__’ :
xdata = [ 0 , 1 , 2 , 4 , 5 , 8 ]
ydata = [ 0.1 , 0.2 , 0.4 , 0.8 , 0.6 , 0.1 ]
plt. bar ( xdata , ydata , align = ‘edge’ )
plt. show ( )

Аналогично себя ведет и функция barh:
import matplotlib. pyplot as plt
if __name__ == ‘__main__’ :
xdata = [ 0 , 1 , 2 , 4 , 5 , 8 ]
ydata = [ 0.1 , 0.2 , 0.4 , 0.8 , 0.6 , 0.1 ]
plt. barh ( xdata , ydata , align = ‘edge’ )
plt. show ( )
Результат выглядит следующим образом:

Изменение цвета столбцов
Чтобы изменить цвет столбиков, используется именованный параметр color, он может задавать единственное значение цвета в виде строки или быть списком, который задает цвет для каждого столбика отдельно. О том, как задаются цвета в Matplotlib, вы можете прочитать, например, .
Следующий пример показывает, как установить один цвет для всех столбиков:
import matplotlib. pyplot as plt
if __name__ == ‘__main__’ :
xdata = [ 0 , 1 , 2 , 3 , 4 , 5 ]
ydata = [ 0.1 , 0.2 , 0.4 , 0.8 , 0.6 , 0.1 ]
plt. bar ( xdata , ydata , color = ‘green’ )
plt. show ( )

Следующий пример устанавливает для каждого столбика свой цвет:
import matplotlib. pyplot as plt
if __name__ == ‘__main__’ :
xdata = [ 0 , 1 , 2 , 3 , 4 , 5 ]
ydata = [ 0.1 , 0.2 , 0.4 , 0.8 , 0.6 , 0.1 ]
colors = [ ‘red’ , ‘orange’ , ‘yellow’ , ‘green’ , ‘blue’ , ‘violet’ ]
plt. bar ( xdata , ydata , color = colors )
plt. show ( )

Если же в списке цветов окажется меньше элементов, чем количество столбцов, то цвета начнут повторяться заново с нулевого элемента. Это показано в следующем примере:
import matplotlib. pyplot as plt
if __name__ == ‘__main__’ :
xdata = [ 0 , 1 , 2 , 3 , 4 , 5 ]
ydata = [ 0.1 , 0.2 , 0.4 , 0.8 , 0.6 , 0.1 ]
colors = [ ‘green’ , ‘blue’ , ‘orange’ ]
plt. bar ( xdata , ydata , color = colors )
plt. show ( )
Результат будет выглядеть следующим образом:

Измерение обводки столбцов
С помощью именованных параметров linewidth и edgecolor функции bar() и barh() можно установить толщину линии обводки и ее цвет соответственно. В следующий пример добавляет к столбцам черную обводку толщиной 1.0 условная единица.
import matplotlib. pyplot as plt
if __name__ == ‘__main__’ :
xdata = [ 0 , 1 , 2 , 4 , 5 , 8 ]
ydata = [ 0.1 , 0.2 , 0.4 , 0.8 , 0.6 , 0.1 ]
plt. bar ( xdata , ydata , linewidth = 1.0 , edgecolor = ‘k’ )
plt. show ( )
Теперь график будет выглядеть следующим образом:

Также цвета рамки можно задавать индивидуально для каждого столбика. Для этого нужно в качестве значения параметра edgecolor передать не один цвет, а список цветов, как показано в следующем примере. Для более наглядного представления, с помощью параметра linewidth толщина рамки задана как 2.0 условные единицы.
import matplotlib. pyplot as plt
if __name__ == ‘__main__’ :
xdata = [ 0 , 1 , 2 , 3 , 4 , 5 ]
ydata = [ 0.1 , 0.2 , 0.4 , 0.8 , 0.6 , 0.1 ]
edgecolors = [ ‘orange’ , ‘red’ , ‘black’ , ‘yellow’ , ‘violet’ , ‘blue’ ]
plt. bar ( xdata , ydata , linewidth = 2.0 , edgecolor = edgecolors )
plt. show ( )

Если же список цветов будет более короткий, чем количество столбцов, то, как и в случае установки цветов заливки столбцов, цвета начнут повторяться с нулевого элемента списка. Такой случай показан в следующем примере.
import matplotlib. pyplot as plt
if __name__ == ‘__main__’ :
xdata = [ 0 , 1 , 2 , 3 , 4 , 5 ]
ydata = [ 0.1 , 0.2 , 0.4 , 0.8 , 0.6 , 0.1 ]
edgecolors = [ ‘orange’ , ‘red’ , ‘black’ ]
plt. bar ( xdata , ydata , linewidth = 2.0 , edgecolor = edgecolors )
plt. show ( )
В результате будет показано следующее окно:

Изменение ширины столбцов
По умолчанию ширины столбиков равны 0.8, поэтому, если шаг между отсчетами меньше этого значения, то столбики начнут пересекаться, и это вряд ли то, чего мы добивались:
import matplotlib. pyplot as plt
if __name__ == ‘__main__’ :
xdata = [ 0 , 0.1 , 0.2 , 0.4 , 0.5 , 0.8 ]
ydata = [ 0.1 , 0.2 , 0.4 , 0.8 , 0.6 , 0.1 ]
plt. bar ( xdata , ydata , linewidth = 1.0 , edgecolor = ‘k’ )
plt. show ( )

Ширину столбиков можно задавать с помощью параметра width, который может быть целым числом (в этом случае все столбики будут иметь одинаковую ширину) или списком (тогда для каждого столбика можно задать свою ширину). Давайте для начала сделаем так, чтобы столбики примыкали друг к другу, т.е. их ширина должна равняться расстоянию между ними:
import matplotlib. pyplot as plt
if __name__ == ‘__main__’ :
xdata = [ 0 , 0.1 , 0.2 , 0.4 , 0.5 , 0.8 ]
ydata = [ 0.1 , 0.2 , 0.4 , 0.8 , 0.6 , 0.1 ]
plt. bar ( xdata , ydata , linewidth = 1.0 , edgecolor = ‘k’ , width = 0.1 )
plt. show ( )

И посмотрим, как использовать параметр width, когда он задается в виде списка:
import matplotlib. pyplot as plt
if __name__ == ‘__main__’ :
xdata = [ 0 , 1 , 2 , 3 , 4 , 5 ]
ydata = [ 0.1 , 0.2 , 0.4 , 0.8 , 0.6 , 0.1 ]
width = [ 0.05 , 0.1 , 0.2 , 0.4 , 0.3 , 0.05 ]
plt. bar ( xdata , ydata , linewidth = 1.0 , edgecolor = ‘k’ , width = width )
plt. show ( )
В данном примере ширины заданы таким образом, чтобы они были пропорциональны отображаемому значению.

На этом пока все, мы рассмотрели основные возможности для построения гистограмм, за кадром остался вопрос отображения границ погрешностей данных, но это тема для отдельной статьи.
Вы можете подписаться на новости сайта через RSS, Группу Вконтакте или Канал в Telegram.
Рейтинг 4.6 / 5 . Всего 18 голос(а, ов)
True 04.07.2016 — 17:01
Очень удобная справка. СПАСИБО!
Способы создания гистограмм с помощью Python
За последний год я сталкивалась с необходимостью рисования гистограмм и столбчатых диаграмм достаточно часто для того, чтобы появилось желание и возможность об этом написать. Кроме того, мне самой довольно сильно не хватало подобной информации. В этой статье приведен обзор 3 методов создания таких графиков на языке Python.
Начнем с того, чего я сама по своей неопытности не знала очень долго: столбчатые диаграммы и гистограммы — разные вещи. Основное отличие состоит в том, что гистограмма показывает частотное распределение — мы задаем набор значений оси Ox, а по Oy всегда откладывается частота. В столбчатой диаграмме (которую в англоязычной литературе уместно было бы назвать barplot) мы задаем и значения оси абсцисс, и значения оси ординат.
Для демонстрации я буду использовать избитый набор данных библиотеки scikit learn Iris. Начнем c импортов:
import pandas as pd import numpy as np import matplotlib import matplotlib.pyplot as plt from sklearn import datasets iris = datasets.load_iris()
Преобразуем набор данных iris в dataframe — так нам удобнее будет с ним работать в будущем.
data = pd.DataFrame(data= np.c_[iris['data'], iris['target']], columns= iris['feature_names'] + ['target'])
Из интересующих нас параметров data содержит информацию о длине чашелистиков и лепестков и ширине чашелистиков и лепестков.
Используем Matplotlib
Построение гистограммы
Cтроим обычную гистограмму, показывающую частотное распределение длин лепестков и чашелистиков:
fig, axs = plt.subplots(1, 2) n_bins = len(data) axs[0].hist(data['sepal length (cm)'], bins=n_bins) axs[0].set_title('sepal length') axs[1].hist(data['petal length (cm)'], bins=n_bins) axs[1].set_title('petal length')

Построение столбчатой диаграммы
Используем методы matplotlib-а, чтобы сравнить ширину листьев и чашелистиков. Это кажется удобнее всего делать на одном графике:
x = np.arange(len(data[:50])) width = 0.35
Для примера и в целях упрощения картинки возьмем первые 50 строк dataframe.
fig, ax = plt.subplots(figsize=(40,5)) rects1 = ax.bar(x - width/2, data['sepal width (cm)'][:50], width, label='sepal width') rects2 = ax.bar(x + width/2, data['petal width (cm)'][:50], width, label='petal width') ax.set_ylabel('cm') ax.set_xticks(x) ax.legend()

Используем методы seaborn
На мой взгляд, многие задачи по построению гистограмм проще и эффективнее выполнять с помощью методов seaborn (кроме того, seaborn выигрывает еще и своими графическими возможностями, на мой взгляд).
Я приведу пример задач, решающихся в seaborn с помощью одной строчки кода. Особенно seaborn выигрышный, когда надо построить распределение. Скажем, нам надо построить распределение длин чашелистиков. Решение этой задачи таково:
sns_plot = sns.distplot(data['sepal width (cm)']) fig = sns_plot.get_figure()

Если же вам необходим только график распределения, сделать его можно так:
snsplot = sns.kdeplot(data['sepal width (cm)'], shade=True) fig = snsplot.get_figure()

Подробнее о построении распределений в seaborn можно почитать тут.
Pandas-гистограммы
Здесь все просто. На самом деле, это оболочка matplotlib.pyplot.hist(), но вызов функции через pd.hist() иногда удобнее менее поворотливых конструкций matplotlib-a. В документации библиотеки pandas можно прочитать больше.
Работает это так:
h = data['petal width (cm)'].hist() fig = h.get_figure()
Спасибо, что прочитали до конца! Буду рада отзывам и комментариям!
