Pandas и Matplotlib: эффективная визуализация табличных данных
Совместное использование Pandas и Matplotlib
Наиболее распространённый способ визуализации данных из DataFrame - использование встроенного метода plot(), который вызывает функции Matplotlib. Пример:
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame({'x': [1,2,3,4], 'y': [10,20,15,25]})
df.plot(x='x', y='y', kind='line')
plt.show()Python pandas matplotlib (pandas и matplotlib в python)
Этот подход подходит для быстрого построения базовых графиков. При необходимости дальнейшей настройки используется интерфейс plt после вызова plot(). Например, добавление заголовка и меток осей:
df.plot(x='x', y='y')
plt.title('Зависимость y от x')
plt.xlabel('Значения x')
plt.ylabel('Значения y')
plt.grid(True)
plt.show()
Возможные проблемы:
- График не отображается в Jupyter - требуется %matplotlib inline или вызов plt.show().
- Ошибка при использовании колонок с пропущенными значениями - pandas автоматически исключает NaN, но стоит явно обработать данные через dropna().
Варианты визуализации
Как построить столбчатую диаграмму на основе группировки данных?
df = pd.DataFrame({'Категория': ['A','B','C','A','B','C'],
'Значение': [5,7,3,8,2,9]})
df.groupby('Категория')['Значение'].sum().plot(kind='bar')
plt.title('Суммарные значения по категориям')
plt.show()
Метод groupby() агрегирует данные, а plot(kind='bar') создаёт столбцы. Для горизонтального расположения используется kind='barh'.
Если индексы после groupby не отсортированы, столбцы могут отображаться в произвольном порядке. Решение - добавить sort_index() перед plot().
Как построить гистограмму распределения числовых данных?
df['Возраст'] = [22,25,27,30,35,40,42,45,50,55]
df['Возраст'].hist(bins=5, edgecolor='black')
plt.xlabel('Возраст')
plt.ylabel('Частота')
plt.show()
Метод hist() из pandas вызывает plt.hist(). Параметр bins задаёт количество интервалов.
При большом количестве данных возможна высокая загрузка памяти. Рекомендуется использовать bins в разумных пределах (15–30).
Как разместить несколько графиков на одной фигуре?
fig, axes = plt.subplots(2, 2, figsize=(10,6))
df['Продажи'].plot(ax=axes[0,0], title='Линейный')
df['Продажи'].hist(ax=axes[0,1], title='Гистограмма')
df['Продажи'].plot(ax=axes[1,0], kind='box', title='Ящик с усами')
df['Продажи'].cumsum().plot(ax=axes[1,1], title='Накопленная сумма')
plt.tight_layout()
plt.show()
Передача конкретной оси ax позволяет управлять расположением. tight_layout() предотвращает наложение.
Если оси не синхронизированы по масштабу, данные могут искажаться. Используйте sharex=True или sharey=True при создании subplots.
Как применить стиль оформления из Matplotlib?
plt.style.use('seaborn-v0_8-darkgrid')
df.plot(x='x', y='y')
plt.show()
Доступные стили: 'ggplot', 'fivethirtyeight', 'default' и другие. Список можно получить через plt.style.available.
Некоторые стили могут переопределять параметры шрифтов, что иногда приводит к некорректному отображению кириллицы. Решение - явно задать шрифт после применения стиля.
Как сохранить графику в файл с высоким разрешением?
df.plot(x='x', y='y')
plt.savefig('graph.png', dpi=300, bbox_inches='tight')
plt.show() # не обязательно после savefig
savefig() сохраняет текущую фигуру. Параметр bbox_inches='tight' обрезает лишние поля.
Если сохранённый файл пустой, вероятно, plt.show() вызывается до savefig() и очищает фигуру. Следует сохранять до показа.
Расширенные примеры совместного использования
Ниже приведены более сложные сценарии, демонстрирующие гибкость связки Pandas и Matplotlib.
Многопанельный график с разными типами данных
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
# Создание данных
dates = pd.date_range('2023-01-01', periods=50, freq='D')
df = pd.DataFrame({'Дата': dates,
'Температура': np.random.normal(20, 5, 50),
'Осадки': np.random.exponential(2, 50)})
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10,8), sharex=True)
# Линейный график температуры
ax1.plot(df['Дата'], df['Температура'], color='red', marker='o', linestyle='-', linewidth=0.8)
ax1.set_ylabel('Температура (°C)')
ax1.set_title('Метеоданные: температура и осадки')
ax1.grid(True, alpha=0.3)
# Столбчатая диаграмма осадков
ax2.bar(df['Дата'], df['Осадки'], width=0.8, color='skyblue', edgecolor='navy')
ax2.set_ylabel('Осадки (мм)')
ax2.set_xlabel('Дата')
ax2.grid(axis='y', alpha=0.3)
fig.autofmt_xdate() # наклон подписей дат
plt.tight_layout()
plt.show()
Результат: фигура с двумя панелями, на верхней - красный линейный график, на нижней - синие столбцы. Оси X синхронизированы по датам.
Построение нескольких кривых на одном графике с легендой
df = pd.DataFrame({
'Месяц': ['Янв','Фев','Мар','Апр','Май'],
'Отдел A': [100,120,90,140,130],
'Отдел B': [80,95,110,105,120],
'Отдел C': [110,115,100,125,135]
})
df.plot(x='Месяц', y=['Отдел A','Отдел B','Отдел C'], marker='s')
plt.title('Динамика продаж по отделам')
plt.ylabel('Продажи (тыс. руб.)')
plt.legend(loc='upper left')
plt.grid(axis='y', linestyle=':')
plt.show()
График с тремя линиями разных цветов и маркерами-квадратами. Легенда расположена в левом верхнем углу.
Кастомизация с использованием циклов и колонок
# Данные о нескольких продуктах
products = ['Товар A','Товар B','Товар C']
data = {p: np.cumsum(np.random.randn(20)*10 + 50) for p in products}
df = pd.DataFrame(data, index=range(1,21))
colors = ['#e74c3c','#3498db','#2ecc71']
for i, col in enumerate(df.columns):
df[col].plot(label=col, color=colors[i], linewidth=1.5)
plt.legend()
plt.xlabel('Временной период')
plt.ylabel('Накопленный объём')
plt.title('Сравнение динамики продуктов')
plt.show()
Каждый продукт отображается отдельной линией с уникальным цветом. Цикл позволяет гибко управлять параметрами.
Работа с пропущенными данными и аномалиями
df = pd.DataFrame({
'Дата': pd.date_range('2024-01-01', periods=10),
'Цена': [100, 105, np.nan, 110, 115, 112, 108, np.nan, 120, 125]
})
# Интерполяция пропусков
df['Цена_инт'] = df['Цена'].interpolate()
plt.figure(figsize=(8,4))
plt.plot(df['Дата'], df['Цена_инт'], 'b-', label='Интерполированная цена')
plt.scatter(df['Дата'], df['Цена'], color='red', zorder=5, label='Исходные точки')
plt.legend()
plt.title('Цена с пропущенными значениями и интерполяция')
plt.xticks(rotation=45)
plt.grid(True, alpha=0.3)
plt.show()
На графике видны исходные точки (красные) и непрерывная линия, полученная интерполяцией. Пропуски не отображаются.
Создание тепловой карты корреляции
# Матрица корреляции из DataFrame
df = pd.DataFrame(np.random.randn(100, 5), columns=['A','B','C','D','E'])
corr = df.corr()
fig, ax = plt.subplots(figsize=(6,5))
im = ax.imshow(corr, cmap='coolwarm', aspect='auto', vmin=-1, vmax=1)
ax.set_xticks(range(len(corr.columns)))
ax.set_yticks(range(len(corr.columns)))
ax.set_xticklabels(corr.columns)
ax.set_yticklabels(corr.columns)
plt.colorbar(im, ax=ax, shrink=0.8)
for i in range(len(corr.columns)):
for j in range(len(corr.columns)):
ax.text(j, i, f'{corr.iloc[i,j]:.2f}', ha='center', va='center', color='white' if abs(corr.iloc[i,j])>0.5 else 'black')
plt.title('Тепловая карта корреляции')
plt.show()
Цветная матрица с подписанными коэффициентами корреляции. Используется imshow и ручное добавление текста.
Использование pandas.plotting для специальных диаграмм
from pandas.plotting import scatter_matrix
df = pd.DataFrame(np.random.randn(100, 4), columns=['Признак1','Признак2','Признак3','Признак4'])
scatter_matrix(df, alpha=0.5, figsize=(10,10), diagonal='hist')
plt.suptitle('Матрица точечных диаграмм и гистограмм', y=1.02)
plt.show()
Матрица 4x4, где на диагонали - гистограммы, на остальных - точечные графики с корреляцией.