Визуализация диаграмм
Примечание
В примерах ниже предполагается, что вы используете Jupyter.
Этот раздел демонстрирует визуализацию с помощью диаграмм. Для получения информации о визуализации табличных данных, пожалуйста, обратитесь к разделу Визуализация таблиц.
Мы используем стандартную конвенцию для ссылки на API matplotlib:
In [1]: import matplotlib.pyplot as plt
In [2]: plt.close("all")
Мы предоставляем основы в pandas для лёгкого создания привлекательных графиков. Обратитесь к разделу экосистемы для библиотек визуализации, которые выходят за рамки основ, описанных здесь.
Примечание
Все вызовы np.random имеют начальное значение 123456.
Базовая визуализация: plot
Мы продемонстрируем основы, см. кулинарную книгу для некоторых продвинутых стратегий.
Метод plot для Series и DataFrame — это просто простой обертка вокруг plt.plot():
In [3]: ts = pd.Series(np.random.randn(1000), index=pd.date_range("1/1/2000", periods=1000))
In [4]: ts = ts.cumsum()
In [5]: ts.plot();
Если индекс состоит из дат, он вызывает gcf().autofmt_xdate(), чтобы попытаться красиво отформатировать ось X, как описано выше.
Для DataFrame, plot() — это удобная функция для построения всех столбцов с метками:
In [6]: df = pd.DataFrame(np.random.randn(1000, 4), index=ts.index, columns=list("ABCD"))
In [7]: df = df.cumsum()
In [8]: plt.figure();
In [9]: df.plot();
Вы можете построить один столбец против другого, используя ключевые слова x и y в plot():
In [10]: df3 = pd.DataFrame(np.random.randn(1000, 2), columns=["B", "C"]).cumsum()
In [11]: df3["A"] = pd.Series(list(range(len(df))))
In [12]: df3.plot(x="A", y="B");
Примечание
Для получения дополнительных опций форматирования и стилей, см. форматирование ниже.
Другие графики
Методы построения графиков позволяют использовать несколько стилей графиков помимо стандартного линейного графика. Эти методы могут быть предоставлены в качестве ключевого аргумента kind к plot() и включают:
‘hist’ для гистограмм
‘box’ для ящиковых диаграмм
‘area’ для облачных графиков
‘scatter’ для точечных графиков
‘hexbin’ для графиков гексагональных ячеек
‘pie’ для круговых диаграмм
Например, столбчатый график можно создать следующим образом:
In [13]: plt.figure();
In [14]: df.iloc[5].plot(kind="bar");
Вы также можете создать эти другие графики, используя методы DataFrame.plot.<kind> вместо предоставления ключевого аргумента kind. Это упрощает поиск методов построения графиков и их специфических аргументов:
In [15]: df = pd.DataFrame()
In [16]: df.plot.<TAB> # noqa: E225, E999
df.plot.area df.plot.barh df.plot.density df.plot.hist df.plot.line df.plot.scatter
df.plot.bar df.plot.box df.plot.hexbin df.plot.kde df.plot.pie
Помимо этих kind, существуют методы DataFrame.hist() и DataFrame.boxplot(), которые используют отдельный интерфейс.
Наконец, есть несколько функций построения графиков в pandas.plotting, которые принимают Series или DataFrame в качестве аргумента. К ним относятся:
Графики также могут быть дополнены ошибочными линиями или таблицами.
Столбчатые графики
Для помеченных данных, не являющихся временными рядами, вы можете создать столбчатый график:
In [17]: plt.figure();
In [18]: df.iloc[5].plot.bar();
In [19]: plt.axhline(0, color="k");
Вызов метода plot.bar() DataFrame создаёт график с несколькими столбцами:
In [20]: df2 = pd.DataFrame(np.random.rand(10, 4), columns=["a", "b", "c", "d"])
In [21]: df2.plot.bar();
Для создания графика с накопленными столбцами, передайте stacked=True. Размер интервала можно изменить, используя ключевое слово
In [22]: df2.plot.bar(stacked=True);.
In [22]: df2.plot.bar(stacked=True);
Для получения горизонтальных столбчатых диаграмм используйте метод barh:
In [23]: df2.plot.barh(stacked=True);
Гистограммы
Гистограммы можно нарисовать, используя методы DataFrame.plot.hist() и Series.plot.hist().
In [24]: df4 = pd.DataFrame(
....: {
....: "a": np.random.randn(1000) + 1,
....: "b": np.random.randn(1000),
....: "c": np.random.randn(1000) - 1,
....: },
....: columns=["a", "b", "c"],
....: )
....:
In [25]: plt.figure();
In [26]: df4.plot.hist(alpha=0.5);
Гистограмму можно сделать группированной, используя stacked=True. Размер интервала можно изменить, используя ключевое слово bins.
In [27]: plt.figure();
In [28]: df4.plot.hist(stacked=True, bins=20);
Вы можете передать другие ключевые слова, поддерживаемые matplotlib hist. Например, горизонтальные и кумулятивные гистограммы можно нарисовать, используя orientation='horizontal' и cumulative=True.
In [29]: plt.figure();
In [30]: df4["a"].plot.hist(orientation="horizontal", cumulative=True);
См. метод hist и документацию matplotlib по гистограммам здесь для получения более подробной информации.
Существующий интерфейс DataFrame.hist для построения гистограмм всё ещё доступен.
In [31]: plt.figure();
In [32]: df["A"].diff().hist();
DataFrame.hist() строит гистограммы столбцов на нескольких подграфиках:
In [33]: plt.figure();
In [34]: df.diff().hist(color="k", alpha=0.5, bins=50);
Ключевое слово by можно указать для построения сгруппированных гистограмм:
In [35]: data = pd.Series(np.random.randn(1000))
In [36]: data.hist(by=np.random.randint(0, 4, 1000), figsize=(6, 4));
Кроме того, ключевое слово by также может быть указано в DataFrame.plot.hist().
Изменено в версии 1.4.0.
In [37]: data = pd.DataFrame(
....: {
....: "a": np.random.choice(["x", "y", "z"], 1000),
....: "b": np.random.choice(["e", "f", "g"], 1000),
....: "c": np.random.randn(1000),
....: "d": np.random.randn(1000) - 1,
....: },
....: )
....:
In [38]: data.plot.hist(by=["a", "b"], figsize=(10, 5));
Диаграммы размаха
Диаграмму размаха можно построить, вызвав Series.plot.box() и DataFrame.plot.box(), или DataFrame.boxplot(), чтобы визуализировать распределение значений в каждом столбце.
Например, вот диаграмма размаха, представляющая пять испытаний по 10 наблюдениям равномерной случайной переменной на [0,1).
In [39]: df = pd.DataFrame(np.random.rand(10, 5), columns=["A", "B", "C", "D", "E"])
In [40]: df.plot.box();
Диаграмму размаха можно окрасить, передав color ключевое слово. Вы можете передать dict, ключи которого — boxes, whiskers, medians и caps. Если некоторые ключи отсутствуют в dict, для соответствующих объектов используются значения по умолчанию. Кроме того, диаграмма размаха имеет ключевое слово sym для указания стиля выбросов.
При передаче других аргументов через ключевое слово color, оно будет напрямую передано в matplotlib для всех boxes, whiskers, medians и caps раскрашивания.
Цвета применяются ко всем графикам. Если вам нужна более сложная раскраска, вы можете получить каждый нарисованный объект, передав return_type.
In [41]: color = {
....: "boxes": "DarkGreen",
....: "whiskers": "DarkOrange",
....: "medians": "DarkBlue",
....: "caps": "Gray",
....: }
....:
In [42]: df.plot.box(color=color, sym="r+");
Также можно передать другие ключевые слова, поддерживаемые matplotlib boxplot. Например, горизонтальную и диаграмму размаха с настраиваемым расположением можно построить с помощью ключевых слов vert=False и positions.
In [43]: df.plot.box(vert=False, positions=[1, 4, 5, 6, 8]);
См. метод boxplot и документацию по диаграммам размаха matplotlib для более подробной информации.
Существующий интерфейс DataFrame.boxplot для построения диаграммы размаха по-прежнему можно использовать.
In [44]: df = pd.DataFrame(np.random.rand(10, 5))
In [45]: plt.figure();
In [46]: bp = df.boxplot()
Вы можете создать стратифицированную диаграмму размаха, используя ключевой аргумент by, чтобы создать группы. Например,
In [47]: df = pd.DataFrame(np.random.rand(10, 2), columns=["Col1", "Col2"])
In [48]: df["X"] = pd.Series(["A", "A", "A", "A", "A", "B", "B", "B", "B", "B"])
In [49]: plt.figure();
In [50]: bp = df.boxplot(by="X")
Вы также можете передать подмножество столбцов для построения, а также группировать по нескольким столбцам:
In [51]: df = pd.DataFrame(np.random.rand(10, 3), columns=["Col1", "Col2", "Col3"])
In [52]: df["X"] = pd.Series(["A", "A", "A", "A", "A", "B", "B", "B", "B", "B"])
In [53]: df["Y"] = pd.Series(["A", "B", "A", "B", "A", "B", "A", "B", "A", "B"])
In [54]: plt.figure();
In [55]: bp = df.boxplot(column=["Col1", "Col2"], by=["X", "Y"])
Вы также можете создавать группировки с помощью DataFrame.plot.box(), например:
Изменено в версии 1.4.0.
In [56]: df = pd.DataFrame(np.random.rand(10, 3), columns=["Col1", "Col2", "Col3"])
In [57]: df["X"] = pd.Series(["A", "A", "A", "A", "A", "B", "B", "B", "B", "B"])
In [58]: plt.figure();
In [59]: bp = df.plot.box(column=["Col1", "Col2"], by="X")
В boxplot, тип возвращаемого значения может быть изменен с помощью ключевого слова return_type, допустимые значения — {"axes", "dict", "both", None}. Факеттинг, созданный с помощью DataFrame.boxplot с ключевым словом by, также повлияет на тип вывода:
| Фрагментировано | Тип вывода |
|---|---|---|
| Нет | axes |
| Да | 2-мерный массив осей |
| Нет | axes |
| Да | Список осей |
| Нет | Словарь объектов |
| Да | Список словарей объектов |
| Нет | namedtuple |
| Да | Список namedtuple |
Groupby.boxplot всегда возвращает Series из return_type.
In [60]: np.random.seed(1234)
In [61]: df_box = pd.DataFrame(np.random.randn(50, 2))
In [62]: df_box["g"] = np.random.choice(["A", "B"], size=50)
In [63]: df_box.loc[df_box["g"] == "B", 1] += 3
In [64]: bp = df_box.boxplot(by="g")
Подграфики выше разделены по числовым столбцам в первую очередь, а затем по значению столбца g. Подграфики ниже в первую очередь разделены по значению столбца g, а затем по числовым столбцам.
In [65]: bp = df_box.groupby("g").boxplot()
График области
Вы можете создавать графики областей с помощью Series.plot.area() и DataFrame.plot.area(). Графики областей по умолчанию являются стопками. Для создания стопки областей каждый столбец должен содержать либо все положительные, либо все отрицательные значения.
Если входные данные содержат NaN, они автоматически заполняются нулями. Если вы хотите удалить или заполнить другими значениями, используйте dataframe.dropna() или dataframe.fillna() перед вызовом plot.
In [66]: df = pd.DataFrame(np.random.rand(10, 4), columns=["a", "b", "c", "d"])
In [67]: df.plot.area();
Для создания нестопчатого графика передайте stacked=False. Значение альфа установлено в 0,5, если не указано иное:
In [68]: df.plot.area(stacked=False);
Точечный график
Точечный график можно построить с помощью метода DataFrame.plot.scatter(). Точечный график требует числовых столбцов для осей x и y. Их можно указать с помощью ключевых слов x и y.
In [69]: df = pd.DataFrame(np.random.rand(50, 4), columns=["a", "b", "c", "d"])
In [70]: df["species"] = pd.Categorical(
....: ["setosa"] * 20 + ["versicolor"] * 20 + ["virginica"] * 10
....: )
....:
In [71]: df.plot.scatter(x="a", y="b");
Чтобы построить несколько групп столбцов на одной оси, повторите метод plot, указав целевые ax. Рекомендуется указать ключевые слова color и label для различения каждой группы.
In [72]: ax = df.plot.scatter(x="a", y="b", color="DarkBlue", label="Group 1")
In [73]: df.plot.scatter(x="c", y="d", color="DarkGreen", label="Group 2", ax=ax);
Ключевое слово c может быть указано как имя столбца для задания цвета каждой точки:
In [74]: df.plot.scatter(x="a", y="b", c="c", s=50);
Если в c передается категориальный столбец, то будет создана дискретная цветовая шкала:
Введено в версии 1.3.0.
In [75]: df.plot.scatter(x="a", y="b", c="species", cmap="viridis", s=50);
Вы можете передать другие ключевые слова, поддерживаемые matplotlib scatter. Приведенный ниже пример показывает пузырьковую диаграмму, используя столбец DataFrame в качестве размера пузырьков.
In [76]: df.plot.scatter(x="a", y="b", s=df["c"] * 200);
См. метод scatter и документацию по matplotlib scatter для получения дополнительной информации.
Гексагональный график
Вы можете создавать гексагональные графики с помощью DataFrame.plot.hexbin(). Гексагональные графики могут быть полезной альтернативой точечным графикам, если данные слишком плотные, чтобы графически отобразить каждую точку индивидуально.
In [77]: df = pd.DataFrame(np.random.randn(1000, 2), columns=["a", "b"])
In [78]: df["b"] = df["b"] + np.arange(1000)
In [79]: df.plot.hexbin(x="a", y="b", gridsize=25);
Полезный ключевой аргумент — gridsize; он управляет количеством шестиугольников в направлении x и по умолчанию равен 100. Большее значение gridsize означает больше и более мелких бинов.
По умолчанию вычисляется гистограмма подсчетов вокруг каждой точки (x, y). Вы можете указать альтернативные агрегации, передав значения аргументам C и reduce_C_function. C определяет значение в каждой точке (x, y), а reduce_C_function — функция одного аргумента, которая сводит все значения в бине к одному числу (например, mean, max, sum, std). В этом примере координаты задаются столбцами a и b, а значение — столбцом z. Бины агрегируются с помощью функции NumPy max.
In [80]: df = pd.DataFrame(np.random.randn(1000, 2), columns=["a", "b"])
In [81]: df["b"] = df["b"] + np.arange(1000)
In [82]: df["z"] = np.random.uniform(0, 3, 1000)
In [83]: df.plot.hexbin(x="a", y="b", C="z", reduce_C_function=np.max, gridsize=25);
См. метод hexbin и документацию matplotlib hexbin для получения дополнительной информации.
Диаграмма круговой диаграммы
Вы можете создать диаграмму круговой диаграммы с помощью DataFrame.plot.pie() или Series.plot.pie(). Если ваши данные содержат какие-либо NaN, они будут автоматически заполнены нулями. Будет поднято ValueError , если в ваших данных есть отрицательные значения.
In [84]: series = pd.Series(3 * np.random.rand(4), index=["a", "b", "c", "d"], name="series")
In [85]: series.plot.pie(figsize=(6, 6));
Для диаграмм круговой диаграммы лучше использовать квадратные фигуры, т. е. отношение сторон фигуры 1. Вы можете создать фигуру с одинаковой шириной и высотой или принудительно установить отношение сторон, равное после построения, вызвав ax.set_aspect('equal') на возвращенном axes объекте.
Обратите внимание, что диаграмма круговой диаграммы с DataFrame требует, чтобы вы либо указали целевой столбец с помощью аргумента y или subplots=True. Если указан y, будет построена диаграмма круговой диаграммы выбранного столбца. Если указан subplots=True, диаграммы круговой диаграммы для каждого столбца строятся как подграфики. По умолчанию в каждой диаграмме круговой диаграммы будет отображаться легенда; укажите legend=False , чтобы скрыть её.
In [86]: df = pd.DataFrame(
....: 3 * np.random.rand(4, 2), index=["a", "b", "c", "d"], columns=["x", "y"]
....: )
....:
In [87]: df.plot.pie(subplots=True, figsize=(8, 4));
Вы можете использовать ключевые слова labels и colors для указания меток и цветов каждого сегмента.
Предупреждение
Большинство диаграмм pandas используют аргументы label и color (обратите внимание на отсутствие «s» в этих обозначениях). Для согласованности с matplotlib.pyplot.pie() вы должны использовать labels и colors.
Если вы хотите скрыть метки сегментов, укажите labels=None. Если указан fontsize, это значение будет применено к меткам сегментов. Также можно использовать другие ключевые слова, поддерживаемые matplotlib.pyplot.pie().
In [88]: series.plot.pie(
....: labels=["AA", "BB", "CC", "DD"],
....: colors=["r", "g", "b", "c"],
....: autopct="%.2f",
....: fontsize=20,
....: figsize=(6, 6),
....: );
....:
Если вы передадите значения, сумма которых меньше 1,0, они будут масштабированы так, чтобы их сумма составляла 1.
In [89]: series = pd.Series([0.1] * 4, index=["a", "b", "c", "d"], name="series2")
In [90]: series.plot.pie(figsize=(6, 6));
Дополнительную информацию см. в документации по круговым диаграммам matplotlib.
Построение графиков с пропущенными данными
pandas пытается быть прагматичным при построении графиков DataFrames или Series , содержащих пропущенные данные. Пропущенные значения отбрасываются, пропускаются или заполняются в зависимости от типа графика.
Тип графика | Обработка NaN |
|---|---|
Линия | Оставить пробелы в NaN |
Линия (упакованная) | Заполнить 0 |
Столбчатая диаграмма | Заполнить 0 |
Точечная диаграмма | Отбросить NaN |
Гистограмма | Отбросить NaN (по столбцам) |
Ящик с усами | Отбросить NaN (по столбцам) |
Площадь | Заполнить 0 |
KDE | Отбросить NaN (по столбцам) |
Гексагональная | Отбросить NaN |
Круговая диаграмма | Заполнить 0 |
Если какие-либо из этих значений по умолчанию вам не подходят, или если вы хотите явно указать, как обрабатывать пропущенные значения, рассмотрите использование fillna() или dropna() перед построением графика.
Инструменты для построения графиков
Эти функции можно импортировать из pandas.plotting и принимать Series или DataFrame в качестве аргумента.
Матрица точечных диаграмм
Вы можете создать матрицу точечных диаграмм с помощью метода scatter_matrix в pandas.plotting:
In [91]: from pandas.plotting import scatter_matrix
In [92]: df = pd.DataFrame(np.random.randn(1000, 4), columns=["a", "b", "c", "d"])
In [93]: scatter_matrix(df, alpha=0.2, figsize=(6, 6), diagonal="kde");
Плотность распределения
Вы можете создать графики плотности распределения, используя методы Series.plot.kde() и DataFrame.plot.kde().
In [94]: ser = pd.Series(np.random.randn(1000))
In [95]: ser.plot.kde();
Кривые Эндрюса
Кривые Эндрюса позволяют отображать многомерные данные в виде большого числа кривых, которые создаются с использованием атрибутов выборок в качестве коэффициентов для рядов Фурье, см. статью Википедии для получения дополнительной информации. Различно окрашивая эти кривые для каждого класса, можно визуализировать кластеризацию данных. Кривые, принадлежащие выборкам одного класса, обычно будут располагаться ближе друг к другу и образовывать более крупные структуры.
Примечание: Набор данных «Ирис» доступен здесь.
In [96]: from pandas.plotting import andrews_curves
In [97]: data = pd.read_csv("data/iris.data")
In [98]: plt.figure();
In [99]: andrews_curves(data, "Name");
Параллельные координаты
Параллельные координаты — это метод построения графиков многомерных данных, см. статью Википедии для введения. Параллельные координаты позволяют визуально увидеть кластеры в данных и оценить другие статистические данные. В параллельных координатах точки представлены соединенными отрезками прямых. Каждая вертикальная линия представляет один атрибут. Один набор соединенных отрезков прямых представляет одну точку данных. Точки, которые имеют тенденцию к кластеризации, будут казаться расположенными ближе друг к другу.
In [100]: from pandas.plotting import parallel_coordinates
In [101]: data = pd.read_csv("data/iris.data")
In [102]: plt.figure();
In [103]: parallel_coordinates(data, "Name");
Диаграмма задержек
Диаграммы задержек используются для проверки того, является ли набор данных или временной ряд случайным. Случайные данные не должны иметь какой-либо структуры на диаграмме задержек. Неслучайная структура означает, что основополагающие данные не являются случайными. Аргумент lag может быть передан, и когда lag=1 , график по существу отображает data[:-1] по оси data[1:].
In [104]: from pandas.plotting import lag_plot
In [105]: plt.figure();
In [106]: spacing = np.linspace(-99 * np.pi, 99 * np.pi, num=1000)
In [107]: data = pd.Series(0.1 * np.random.rand(1000) + 0.9 * np.sin(spacing))
In [108]: lag_plot(data);
График автокорреляции
Графики автокорреляции часто используются для проверки случайности временных рядов. Это делается путем вычисления автокорреляций значений данных при различных временных задержках. Если временной ряд случайный, такие автокорреляции должны быть близки к нулю для любых и всех временных задержек. Если временной ряд неслучайный, то одна или несколько автокорреляций будут значительно отличаться от нуля. Горизонтальные линии на графике соответствуют 95% и 99% доверительным интервалам. Штриховая линия — это 99% доверительный интервал. См. статью Википедии для получения дополнительной информации о графиках автокорреляции.
In [109]: from pandas.plotting import autocorrelation_plot
In [110]: plt.figure();
In [111]: spacing = np.linspace(-9 * np.pi, 9 * np.pi, num=1000)
In [112]: data = pd.Series(0.7 * np.random.rand(1000) + 0.3 * np.sin(spacing))
In [113]: autocorrelation_plot(data);
График бутстрапа
Графики бутстрапа используются для визуальной оценки неопределенности статистики, такой как среднее значение, медиана, средний диапазон и т. д. Случайная подвыборка заданного размера выбирается из набора данных, вычисляется интересующая статистика для этой подвыборки, и этот процесс повторяется заданное количество раз. Полученные графики и гистограммы составляют график бутстрапа.
In [114]: from pandas.plotting import bootstrap_plot
In [115]: data = pd.Series(np.random.rand(1000))
In [116]: bootstrap_plot(data, size=50, samples=500, color="grey");
RadViz
RadViz — это способ визуализации многомерных данных. Он основан на простом алгоритме минимизации натяжения пружин. В основном вы создаете несколько точек на плоскости. В нашем случае они равномерно распределены по единичной окружности. Каждая точка представляет один атрибут. Затем вы притворяетесь, что каждая выборка в наборе данных прикреплена к каждой из этих точек пружиной, жесткость которой пропорциональна числовому значению этого атрибута (они нормализованы к единичному интервалу). Точка на плоскости, к которой устанавливается наша выборка (где силы, действующие на нашу выборку, находятся в равновесии), — это место, где будет нарисована точка, представляющая нашу выборку. В зависимости от того, к какому классу принадлежит эта выборка, она будет окрашиваться по-разному. См. пакет R Radviz для получения дополнительной информации.
Примечание: Набор данных «Ирис» доступен здесь.
In [117]: from pandas.plotting import radviz
In [118]: data = pd.read_csv("data/iris.data")
In [119]: plt.figure();
In [120]: radviz(data, "Name");
Форматирование графиков
Установка стиля графика
Начиная с версии 1.5 и выше, matplotlib предлагает ряд предварительно настроенных стилей для графиков. Установка стиля позволяет легко задать общий вид графиков. Установка стиля осуществляется вызовом matplotlib.style.use(my_plot_style) перед созданием графика. Например, вы можете написать matplotlib.style.use('ggplot') для графиков в стиле ggplot.
Вы можете посмотреть различные доступные имена стилей в matplotlib.style.available и очень легко их опробовать.
Общие аргументы стиля графика
Большинство методов построения графиков имеют набор ключевых аргументов, которые управляют макетом и форматированием возвращаемого графика:
In [121]: plt.figure();
In [122]: ts.plot(style="k--", label="Series");
Для каждого типа графика (например, line, bar, scatter) любые дополнительные ключевые аргументы передаются соответствующей функции matplotlib (ax.plot(), ax.bar(), ax.scatter()). Это может быть использовано для управления дополнительной стилизацией, помимо того, что предоставляет pandas.
Управление легендой
Вы можете установить аргумент legend в значение False для скрытия легенды, которая отображается по умолчанию.
In [123]: df = pd.DataFrame(np.random.randn(1000, 4), index=ts.index, columns=list("ABCD"))
In [124]: df = df.cumsum()
In [125]: df.plot(legend=False);
Управление метками
Введено в версии 1.1.0.
Вы можете установить аргументы xlabel и ylabel для присвоения графику пользовательских меток для осей X и Y. По умолчанию pandas использует имя индекса как метку оси X, а для метки оси Y оставляет пустое значение.
In [126]: df.plot();
In [127]: df.plot(xlabel="new x", ylabel="new y");
Масштабы
Вы можете передать logy для получения логарифмической шкалы оси Y.
In [128]: ts = pd.Series(np.random.randn(1000), index=pd.date_range("1/1/2000", periods=1000))
In [129]: ts = np.exp(ts.cumsum())
In [130]: ts.plot(logy=True);
См. также ключевые аргументы logx и loglog.
Построение на дополнительной оси Y
Чтобы построить данные на дополнительной оси Y, используйте ключевое слово secondary_y.
In [131]: df["A"].plot();
In [132]: df["B"].plot(secondary_y=True, style="g");
Чтобы построить некоторые столбцы в DataFrame, передайте имена столбцов в ключевое слово secondary_y:
In [133]: plt.figure();
In [134]: ax = df.plot(secondary_y=["A", "B"])
In [135]: ax.set_ylabel("CD scale");
In [136]: ax.right_ax.set_ylabel("AB scale");
Обратите внимание, что столбцы, построенные на дополнительной оси Y, автоматически помечаются "(right)" в легенде. Чтобы отключить автоматическую маркировку, используйте ключевое слово mark_right=False:
In [137]: plt.figure();
In [138]: df.plot(secondary_y=["A", "B"], mark_right=False);
Настройка форматирования для временных рядов
Изменено в версии 1.0.0.
pandas предоставляет настраиваемые форматировщики для временных рядов. Они изменяют форматирование меток осей для дат и времени. По умолчанию настраиваемые форматировщики применяются только к графикам, созданным с помощью pandas с помощью DataFrame.plot() или Series.plot(). Чтобы применить их ко всем графикам, включая те, которые созданы matplotlib, установите опцию pd.options.plotting.matplotlib.register_converters = True или используйте pandas.plotting.register_matplotlib_converters().
Отключение автоматической подстройки разрешения делений
pandas включает автоматическую подстройку разрешения делений для данных временных рядов с регулярной частотой. В ограниченных случаях, когда pandas не может определить информацию о частоте (например, в созданном внешне twinx), вы можете отключить это поведение для выравнивания.
Вот поведение по умолчанию, обратите внимание, как происходит маркировка делений оси X:
In [139]: plt.figure();
In [140]: df["A"].plot();
Используя параметр x_compat вы можете отключить это поведение:
In [141]: plt.figure();
In [142]: df["A"].plot(x_compat=True);
Если у вас несколько графиков, которые нужно отключить, метод use в pandas.plotting.plot_params может быть использован в with блоке:
In [143]: plt.figure();
In [144]: with pd.plotting.plot_params.use("x_compat", True):
.....: df["A"].plot(color="r")
.....: df["B"].plot(color="g")
.....: df["C"].plot(color="b")
.....:
Автоматическая настройка делений дат
TimedeltaIndex теперь использует собственные методы локализации делений matplotlib, что полезно для вызова автоматической настройки делений дат из matplotlib для графиков, у которых метки делений перекрываются.
См. метод autofmt_xdate и документацию matplotlib для получения более подробной информации.
Подграфики
Каждый Series в DataFrame может быть построен на разных осях с помощью ключевого слова subplots:
In [145]: df.plot(subplots=True, figsize=(6, 6));
Использование макета и нацеливание на несколько осей
Макет подграфиков можно указать с помощью ключевого слова layout . Оно может принимать (rows, columns). Ключевое слово layout также может использоваться в hist и boxplot . Если входные данные неверны, будет вызвано исключение ValueError.
Количество осей, которое может содержать строка x столбец, указанное layout, должно быть больше, чем количество необходимых подграфиков. Если макет может содержать больше осей, чем требуется, пустые оси не отрисовываются. Подобно методу NumPy array’s reshape, вы можете использовать -1 для одной размерности, чтобы автоматически вычислить количество строк или столбцов, исходя из другой.
In [146]: df.plot(subplots=True, layout=(2, 3), figsize=(6, 6), sharex=False);
Приведенный выше пример эквивалентен использованию:
In [147]: df.plot(subplots=True, layout=(2, -1), figsize=(6, 6), sharex=False);
Необходимое количество столбцов (3) определяется количеством рядов для построения и заданным количеством строк (2).
Вы можете передать созданные предварительно несколько осей в виде списка через ключевое слово ax . Это позволяет создавать более сложные макеты. Переданные оси должны соответствовать количеству строящихся подграфиков.
Когда несколько осей передаются через ключевое слово ax, ключевые слова layout, sharex и sharey не влияют на вывод. Вы должны явно передать sharex=False и sharey=False, в противном случае вы увидите предупреждение.
In [148]: fig, axes = plt.subplots(4, 4, figsize=(9, 9))
In [149]: plt.subplots_adjust(wspace=0.5, hspace=0.5)
In [150]: target1 = [axes[0][0], axes[1][1], axes[2][2], axes[3][3]]
In [151]: target2 = [axes[3][0], axes[2][1], axes[1][2], axes[0][3]]
In [152]: df.plot(subplots=True, ax=target1, legend=False, sharex=False, sharey=False);
In [153]: (-df).plot(subplots=True, ax=target2, legend=False, sharex=False, sharey=False);
Другой вариант — передать аргумент ax в Series.plot() для построения на конкретной оси:
In [154]: fig, axes = plt.subplots(nrows=2, ncols=2)
In [155]: plt.subplots_adjust(wspace=0.2, hspace=0.5)
In [156]: df["A"].plot(ax=axes[0, 0]);
In [157]: axes[0, 0].set_title("A");
In [158]: df["B"].plot(ax=axes[0, 1]);
In [159]: axes[0, 1].set_title("B");
In [160]: df["C"].plot(ax=axes[1, 0]);
In [161]: axes[1, 0].set_title("C");
In [162]: df["D"].plot(ax=axes[1, 1]);
In [163]: axes[1, 1].set_title("D");
Отображение с ошибками
Отображение с ошибками поддерживается в DataFrame.plot() и Series.plot().
Горизонтальные и вертикальные ошибки могут быть заданы в параметрах xerr и yerr для plot(). Значения ошибок могут быть заданы с использованием различных форматов:
В виде
DataFrameилиdictошибок с именами столбцов, соответствующими атрибутуcolumnsдиаграммыDataFrameили атрибутуnameSeries.В виде
str, указывающего, какие столбцы диаграммыDataFrameсодержат значения ошибок.В виде исходных значений (
list,tuple, илиnp.ndarray). Должны быть такой же длины, как и диаграммаDataFrame/Series.
Вот пример того, как легко построить графики средних значений групп со стандартными отклонениями из исходных данных.
# Generate the data
In [164]: ix3 = pd.MultiIndex.from_arrays(
.....: [
.....: ["a", "a", "a", "a", "a", "b", "b", "b", "b", "b"],
.....: ["foo", "foo", "foo", "bar", "bar", "foo", "foo", "bar", "bar", "bar"],
.....: ],
.....: names=["letter", "word"],
.....: )
.....:
In [165]: df3 = pd.DataFrame(
.....: {
.....: "data1": [9, 3, 2, 4, 3, 2, 4, 6, 3, 2],
.....: "data2": [9, 6, 5, 7, 5, 4, 5, 6, 5, 1],
.....: },
.....: index=ix3,
.....: )
.....:
# Group by index labels and take the means and standard deviations
# for each group
In [166]: gp3 = df3.groupby(level=("letter", "word"))
In [167]: means = gp3.mean()
In [168]: errors = gp3.std()
In [169]: means
Out[169]:
data1 data2
letter word
a bar 3.500000 6.000000
foo 4.666667 6.666667
b bar 3.666667 4.000000
foo 3.000000 4.500000
In [170]: errors
Out[170]:
data1 data2
letter word
a bar 0.707107 1.414214
foo 3.785939 2.081666
b bar 2.081666 2.645751
foo 1.414214 0.707107
# Plot
In [171]: fig, ax = plt.subplots()
In [172]: means.plot.bar(yerr=errors, ax=ax, capsize=4, rot=0);
Также поддерживаются асимметричные погрешности, однако в этом случае должны быть предоставлены исходные значения ошибок. Для Series длиной N, должен быть предоставлен массив 2xN, указывающий нижние и верхние (или левые и правые) погрешности. Для DataFrame длиной MxN, асимметричные погрешности должны быть представлены в массиве Mx2xN.
Вот пример построения графика диапазона мин/макс с использованием асимметричных погрешностей.
In [173]: mins = gp3.min()
In [174]: maxs = gp3.max()
# errors should be positive, and defined in the order of lower, upper
In [175]: errors = [[means[c] - mins[c], maxs[c] - means[c]] for c in df3.columns]
# Plot
In [176]: fig, ax = plt.subplots()
In [177]: means.plot.bar(yerr=errors, ax=ax, capsize=4, rot=0);
Отображение таблиц
Отображение с помощью таблицы matplotlib теперь поддерживается в DataFrame.plot() и Series.plot() с параметром table. Параметр table может принимать bool, DataFrame или Series. Простой способ нарисовать таблицу - указать table=True. Данные будут транспонированы для соответствия макету по умолчанию matplotlib.
In [178]: fig, ax = plt.subplots(1, 1, figsize=(7, 6.5))
In [179]: df = pd.DataFrame(np.random.rand(5, 3), columns=["a", "b", "c"])
In [180]: ax.xaxis.tick_top() # Display x-axis ticks on top.
In [181]: df.plot(table=True, ax=ax);
Также можно передать другую DataFrame или Series в параметр table. Данные будут нарисованы так, как отображаются в методе print (не транспонируются автоматически). При необходимости, они должны быть транспонированы вручную, как показано в примере ниже.
In [182]: fig, ax = plt.subplots(1, 1, figsize=(7, 6.75))
In [183]: ax.xaxis.tick_top() # Display x-axis ticks on top.
In [184]: df.plot(table=np.round(df.T, 2), ax=ax);
Также существует вспомогательная функция pandas.plotting.table, которая создает таблицу из DataFrame или Series и добавляет ее в экземпляр matplotlib.Axes. Эта функция может принимать параметры, которые имеет matplotlib table.
In [185]: from pandas.plotting import table
In [186]: fig, ax = plt.subplots(1, 1)
In [187]: table(ax, np.round(df.describe(), 2), loc="upper right", colWidths=[0.2, 0.2, 0.2]);
In [188]: df.plot(ax=ax, ylim=(0, 2), legend=None);
Примечание: Вы можете получить экземпляры таблиц на осях с помощью свойства axes.tables для дальнейших декораций. См. документацию matplotlib по таблицам для получения более подробной информации.
Цветовые карты
Возможная проблема при построении большого количества столбцов заключается в том, что некоторые ряды трудно отличить из-за повторения в стандартных цветах. Для исправления этого отображения DataFrame поддерживается использование аргумента colormap, который принимает либо цветовой карту matplotlib, либо строку, являющуюся именем цветовой карты, зарегистрированной в matplotlib. Визуализация стандартных цветовых карт matplotlib доступна здесь.
Поскольку matplotlib не поддерживает цветовые карты для линий напрямую, цвета выбираются на основе равномерного интервала, определяемого количеством столбцов в DataFrame. Не учитывается цвет фона, поэтому некоторые цветовые карты будут создавать линии, которые трудно различить.
Для использования цветовой карты cubehelix можно передать colormap='cubehelix'.
In [189]: df = pd.DataFrame(np.random.randn(1000, 10), index=ts.index)
In [190]: df = df.cumsum()
In [191]: plt.figure();
In [192]: df.plot(colormap="cubehelix");
В качестве альтернативы, мы можем передать саму цветовой карту:
In [193]: from matplotlib import cm
In [194]: plt.figure();
In [195]: df.plot(colormap=cm.cubehelix);
Цветовые карты также могут использоваться в других типах графиков, таких как гистограммы:
In [196]: dd = pd.DataFrame(np.random.randn(10, 10)).applymap(abs)
In [197]: dd = dd.cumsum()
In [198]: plt.figure();
In [199]: dd.plot.bar(colormap="Greens");
Графики параллельных координат:
In [200]: plt.figure();
In [201]: parallel_coordinates(data, "Name", colormap="gist_rainbow");
Графики кривых Эндрюса:
In [202]: plt.figure();
In [203]: andrews_curves(data, "Name", colormap="winter");
Отображение напрямую с помощью Matplotlib
В некоторых ситуациях может быть предпочтительнее или необходимо подготовить графики непосредственно с помощью matplotlib, например, когда определенный тип графика или настройка не поддерживается (еще) pandas. Series и DataFrame объекты ведут себя как массивы и поэтому могут быть переданы напрямую функциям matplotlib без явных преобразований.
pandas также автоматически регистрирует форматеры и локаторы, которые распознают индексы дат, тем самым расширяя поддержку дат и времени практически для всех типов графиков, доступных в matplotlib. Хотя эта форматирование не обеспечивает такой же уровень детализации, который вы получите при построении графиков с помощью pandas, оно может быть быстрее при построении большого числа точек.
In [204]: price = pd.Series(
.....: np.random.randn(150).cumsum(),
.....: index=pd.date_range("2000-1-1", periods=150, freq="B"),
.....: )
.....:
In [205]: ma = price.rolling(20).mean()
In [206]: mstd = price.rolling(20).std()
In [207]: plt.figure();
In [208]: plt.plot(price.index, price, "k");
In [209]: plt.plot(ma.index, ma, "b");
In [210]: plt.fill_between(mstd.index, ma - 2 * mstd, ma + 2 * mstd, color="b", alpha=0.2);
Отображение бэкэндов
Начиная с версии 0.25, pandas можно расширить с помощью сторонних бэкэндов отображения. Основная идея заключается в том, чтобы позволить пользователям выбрать бэкэнд отображения, отличных от предоставленного на основе Matplotlib.
Это можно сделать, передав ‘backend.module’ как аргумент backend в функцию plot. Например:
>>> Series([1, 2, 3]).plot(backend="backend.module")
В качестве альтернативы, вы также можете установить этот параметр глобально, не нужно указывать ключевое слово в каждом вызове plot. Например:
>>> pd.set_option("plotting.backend", "backend.module")
>>> pd.Series([1, 2, 3]).plot()
Или:
>>> pd.options.plotting.backend = "backend.module"
>>> pd.Series([1, 2, 3]).plot()
Это было бы более или менее эквивалентно:
>>> import backend.module
>>> backend.module.plot(pd.Series([1, 2, 3]))
Модуль бэкэнда может затем использовать другие инструменты визуализации (Bokeh, Altair, hvplot,…) для создания графиков. Некоторые библиотеки, реализующие бэкэнд для pandas, перечислены на странице экосистемы Визуализация.
Руководство для разработчиков можно найти по адресу https://pandas.pydata.org/docs/dev/development/extending.html#plotting-backends
© 2008–2022, AQR Capital Management, LLC, Lambda Foundry, Inc. and PyData Development Team
Licensed under the 3-clause BSD License.
https://pandas.pydata.org/pandas-docs/version/1.5.0/user_guide/visualization.html