За последний год я сталкивалась с необходимостью рисования гистограмм и столбчатых диаграмм достаточно часто для того, чтобы появилось желание и возможность об этом написать. Кроме того, мне самой довольно сильно не хватало подобной информации. В этой статье приведен обзор 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')

image

Построение столбчатой диаграммы

Используем методы 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()

image

Используем методы seaborn

На мой взгляд, многие задачи по построению гистограмм проще и эффективнее выполнять с помощью методов seaborn (кроме того, seaborn выигрывает еще и своими графическими возможностями, на мой взгляд).

Я приведу пример задач, решающихся в seaborn с помощью одной строчки кода. Особенно seaborn выигрышный, когда надо построить распределение. Скажем, нам надо построить распределение длин чашелистиков. Решение этой задачи таково:

sns_plot = sns.distplot(data['sepal width (cm)'])
fig = sns_plot.get_figure()

image

Если же вам необходим только график распределения, сделать его можно так:

snsplot = sns.kdeplot(data['sepal width (cm)'], shade=True)
fig = snsplot.get_figure()

image

Подробнее о построении распределений в seaborn можно почитать тут.

Pandas-гистограммы

Здесь все просто. На самом деле, это оболочка matplotlib.pyplot.hist(), но вызов функции через pd.hist() иногда удобнее менее поворотливых конструкций matplotlib-a. В документации библиотеки pandas можно прочитать больше.

Работает это так:

h = data['petal width (cm)'].hist()
fig = h.get_figure()

image

Спасибо, что прочитали до конца! Буду рада отзывам и комментариям!

Комментарии (4)


  1. WhiteBlackGoose
    07.10.2019 21:16
    +1

    И еще кто-то говорит, что мои очерки короткие 0_о. Ну да ладно. Тут чуть побольше инфы https://habr.com/ru/post/468295/


  1. milssky
    07.10.2019 21:33

    а plotly не рассматривался?


    1. Alex_ME
      07.10.2019 23:18

      Немного смотрел, понравился интерактив, особенно возможность включения и отключения графиков. А есть ли возможность использования без браузера? Отдельным окном, как matplotlib.


      1. milssky
        10.10.2019 20:11

        offline режим есть. На хабре мануал был habr.com/ru/post/308162