Как нарисовать график из pandas DataFrame

Задача. У вас есть jupyter notebook, в нем есть данные, которые загружены в DataFrame. Вам необходимо из этих данных нарисовать график.

Вот пример:

import pandas as pd

df = pd.DataFrame({'day_number': ['1', '3', '4'], 'orders': [8, 7, 11]})

df

Это данные про заказы в интернет магазине

График

Чтобы нарисовать график нужно добавить всего две строчки:

import matplotlib.pyplot as plt

plt.plot(df['day_number'], df['orders'])

Первая строчка — это подключение библиотеки, вторая — это вызов "plot", которому переданы значения по X и по Y.

Получился график:

Но тут есть несколько проблем, давайте их исправим.

Текст "matplotlib.lines.Line2D at "

В выводе ячейки jupyter есть не только график, но еще и какой-то текст

[<matplotlib.lines.Line2D at 0x7f62a8d9abe0>]

Это специфика jupyter. Он выводит в ячейку результат последнего выражения. "plt.plot(df['day_number'], df['orders'])" возвращает список из одного элемента "matplotlib.lines.Line2D" — это и отображается в ячейке.

Для того чтобы это убрать, нужно чтобы последнее выражение возвращало None. Чаще всего для этого используется выражение "plt.show()". Если это записать в последнюю строку, то текст пропадет и будет только график:

Неправильные значения по оси X

Если внимательно посмотреть на график, то станет понятно что на нем нарисовано не то что нужно. В DataFrame есть данные про день 1, 3 и 4. Данных про день два нет. Но на графике расстояние от точки 1 до точки 3 точно такое же как от точки 3 до точки 4.

Так происходит из-за того что в day_number находятся строки, а не числа. Эти строки используются только как подписи на оси графика. Вот еще пример где используются строки состоящие не из цифры, он работает точно так же:

Для того чтобы график использовал значения X как цифры нужно преобразовать их в цифры. Можно либо поправить это в создании df (убрать кавычки), либо преобразовать уже готовый столбец в DataFrame:

df['day_number'] = pd.to_numeric(df['day_number'])

Вот правильный график:

График начинается не от нуля

Следующая вещь, которую хочется поправить в графике — это сделать чтобы минимальное значение по оси Y было 0.

Есть несколько способов как это можно сделать, самый простой — добавить в ячейку строчку кода plt.ylim(bottom=0)

Легенда

Удобно когда на графике отображается информация про линии. Чтобы это сделать, нужно поправить две строчки.

Указать label внутри plot:

plt.plot(df['day_number'], df['orders'],label="Number of orders by day")

И сказать:

plt.legend()

Этот вызов постарается отобразить легенду в лучшем месте на графике (чтобы он не закрывал линию). Но можно и руками указать место где расположить легенду:

plt.legend(loc="lower right")

Если указать неправильное значение для loc, то система выдаст отличнейшую ошибку, в которой перечислены все валидные варианты для этого значения:

/usr/local/lib/python3.7/site-packages/ipykernel_launcher.py:9: MatplotlibDeprecationWarning: Unrecognized location 'asdf'. Falling back on 'best'; valid locations are
    best
    upper right
    upper left
    lower left
    lower right
    right
    center left
    center right
    lower center
    upper center
    center
This will raise an exception in 3.3.
  if __name__ == '__main__':

Другие типы графиков

Кроме линии можно отобразить данные другим способом.

Например, bar chart:

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame({'day_number': ['1', '3', '4'], 'orders': [8, 7, 11]})
df['day_number'] = pd.to_numeric(df['day_number'])

plt.bar(df['day_number'], df['orders'])
plt.show()

Или точки:

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame({'day_number': ['1', '3', '4'], 'orders': [8, 7, 11]})
df['day_number'] = pd.to_numeric(df['day_number'])

plt.scatter(df['day_number'], df['orders'])
plt.show()

Иван Бессарабов
ivan@bessarabov.ru

5 апреля 2020