Spec-Zone.ru › pandas 1

Визуализация диаграмм

Примечание

В примерах ниже предполагается, что вы используете 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();
../_images/series_plot_basic.png

Если индекс состоит из дат, он вызывает 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();
../_images/frame_plot_basic.png

Вы можете построить один столбец против другого, используя ключевые слова 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");
../_images/df_plot_xy.png

Примечание

Для получения дополнительных опций форматирования и стилей, см. форматирование ниже.

Другие графики

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

  • ‘bar’ или ‘barh’ для столбчатых графиков

  • ‘hist’ для гистограмм

  • ‘box’ для ящиковых диаграмм

  • ‘kde’ или ‘density’ для графиков плотности

  • ‘area’ для облачных графиков

  • ‘scatter’ для точечных графиков

  • ‘hexbin’ для графиков гексагональных ячеек

  • ‘pie’ для круговых диаграмм

Например, столбчатый график можно создать следующим образом:

In [13]: plt.figure();

In [14]: df.iloc[5].plot(kind="bar");
../_images/bar_plot_ex.png

Вы также можете создать эти другие графики, используя методы 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 в качестве аргумента. К ним относятся:

  • Матрица рассеяния

  • Кривые Эндрюса

  • Параллельные координаты

  • График запаздывания

  • График автокорреляции

  • График бутстрапа

  • RadViz

Графики также могут быть дополнены ошибочными линиями или таблицами.

Столбчатые графики

Для помеченных данных, не являющихся временными рядами, вы можете создать столбчатый график:

In [17]: plt.figure();

In [18]: df.iloc[5].plot.bar();

In [19]: plt.axhline(0, color="k");
../_images/bar_plot_ex.png

Вызов метода plot.bar() DataFrame создаёт график с несколькими столбцами:

In [20]: df2 = pd.DataFrame(np.random.rand(10, 4), columns=["a", "b", "c", "d"])

In [21]: df2.plot.bar();
../_images/bar_plot_multi_ex.png

Для создания графика с накопленными столбцами, передайте stacked=True. Размер интервала можно изменить, используя ключевое слово

In [22]: df2.plot.bar(stacked=True);
.

In [22]: df2.plot.bar(stacked=True);
../_images/bar_plot_stacked_ex.png

Для получения горизонтальных столбчатых диаграмм используйте метод barh:

In [23]: df2.plot.barh(stacked=True);
../_images/barh_plot_stacked_ex.png

Гистограммы

Гистограммы можно нарисовать, используя методы 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);
../_images/hist_new.png

Гистограмму можно сделать группированной, используя stacked=True. Размер интервала можно изменить, используя ключевое слово bins.

In [27]: plt.figure();

In [28]: df4.plot.hist(stacked=True, bins=20);
../_images/hist_new_stacked.png

Вы можете передать другие ключевые слова, поддерживаемые matplotlib hist. Например, горизонтальные и кумулятивные гистограммы можно нарисовать, используя orientation='horizontal' и cumulative=True.

In [29]: plt.figure();

In [30]: df4["a"].plot.hist(orientation="horizontal", cumulative=True);
../_images/hist_new_kwargs.png

См. метод hist и документацию matplotlib по гистограммам здесь для получения более подробной информации.

Существующий интерфейс DataFrame.hist для построения гистограмм всё ещё доступен.

In [31]: plt.figure();

In [32]: df["A"].diff().hist();
../_images/hist_plot_ex.png

DataFrame.hist() строит гистограммы столбцов на нескольких подграфиках:

In [33]: plt.figure();

In [34]: df.diff().hist(color="k", alpha=0.5, bins=50);
../_images/frame_hist_ex.png

Ключевое слово by можно указать для построения сгруппированных гистограмм:

In [35]: data = pd.Series(np.random.randn(1000))

In [36]: data.hist(by=np.random.randint(0, 4, 1000), figsize=(6, 4));
../_images/grouped_hist.png

Кроме того, ключевое слово 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));
../_images/grouped_hist_by.png

Диаграммы размаха

Диаграмму размаха можно построить, вызвав 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();
../_images/box_plot_new.png

Диаграмму размаха можно окрасить, передав 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+");
../_images/box_new_colorize.png

Также можно передать другие ключевые слова, поддерживаемые matplotlib boxplot. Например, горизонтальную и диаграмму размаха с настраиваемым расположением можно построить с помощью ключевых слов vert=False и positions.

In [43]: df.plot.box(vert=False, positions=[1, 4, 5, 6, 8]);
../_images/box_new_kwargs.png

См. метод boxplot и документацию по диаграммам размаха matplotlib для более подробной информации.

Существующий интерфейс DataFrame.boxplot для построения диаграммы размаха по-прежнему можно использовать.

In [44]: df = pd.DataFrame(np.random.rand(10, 5))

In [45]: plt.figure();

In [46]: bp = df.boxplot()
../_images/box_plot_ex.png

Вы можете создать стратифицированную диаграмму размаха, используя ключевой аргумент 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")
../_images/box_plot_ex2.png

Вы также можете передать подмножество столбцов для построения, а также группировать по нескольким столбцам:

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"])
../_images/box_plot_ex3.png

Вы также можете создавать группировки с помощью 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")
../_images/box_plot_ex4.png

В boxplot, тип возвращаемого значения может быть изменен с помощью ключевого слова return_type, допустимые значения — {"axes", "dict", "both", None}. Факеттинг, созданный с помощью DataFrame.boxplot с ключевым словом by, также повлияет на тип вывода:

return_type

Фрагментировано

Тип вывода

None

Нет

axes

None

Да

2-мерный массив осей

'axes'

Нет

axes

'axes'

Да

Список осей

'dict'

Нет

Словарь объектов

'dict'

Да

Список словарей объектов

'both'

Нет

namedtuple

'both'

Да

Список 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")
../_images/boxplot_groupby.png

Подграфики выше разделены по числовым столбцам в первую очередь, а затем по значению столбца g. Подграфики ниже в первую очередь разделены по значению столбца g, а затем по числовым столбцам.

In [65]: bp = df_box.groupby("g").boxplot()
../_images/groupby_boxplot_vis.png

График области

Вы можете создавать графики областей с помощью 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();
../_images/area_plot_stacked.png

Для создания нестопчатого графика передайте stacked=False. Значение альфа установлено в 0,5, если не указано иное:

In [68]: df.plot.area(stacked=False);
../_images/area_plot_unstacked.png

Точечный график

Точечный график можно построить с помощью метода 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");
../_images/scatter_plot.png

Чтобы построить несколько групп столбцов на одной оси, повторите метод 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);
../_images/scatter_plot_repeated.png

Ключевое слово c может быть указано как имя столбца для задания цвета каждой точки:

In [74]: df.plot.scatter(x="a", y="b", c="c", s=50);
../_images/scatter_plot_colored.png

Если в c передается категориальный столбец, то будет создана дискретная цветовая шкала:

Введено в версии 1.3.0.

In [75]: df.plot.scatter(x="a", y="b", c="species", cmap="viridis", s=50);
../_images/scatter_plot_categorical.png

Вы можете передать другие ключевые слова, поддерживаемые matplotlib scatter. Приведенный ниже пример показывает пузырьковую диаграмму, используя столбец DataFrame в качестве размера пузырьков.

In [76]: df.plot.scatter(x="a", y="b", s=df["c"] * 200);
../_images/scatter_plot_bubble.png

См. метод 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);
../_images/hexbin_plot.png

Полезный ключевой аргумент — 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);
../_images/hexbin_plot_agg.png

См. метод 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));
../_images/series_pie_plot.png

Для диаграмм круговой диаграммы лучше использовать квадратные фигуры, т. е. отношение сторон фигуры 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));
../_images/df_pie_plot.png

Вы можете использовать ключевые слова 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),
   ....: );
   ....: 
../_images/series_pie_plot_options.png

Если вы передадите значения, сумма которых меньше 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));
../_images/series_pie_plot_semi.png

Дополнительную информацию см. в документации по круговым диаграммам 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");
../_images/scatter_matrix_kde.png

Плотность распределения

Вы можете создать графики плотности распределения, используя методы Series.plot.kde() и DataFrame.plot.kde().

In [94]: ser = pd.Series(np.random.randn(1000))

In [95]: ser.plot.kde();
../_images/kde_plot.png

Кривые Эндрюса

Кривые Эндрюса позволяют отображать многомерные данные в виде большого числа кривых, которые создаются с использованием атрибутов выборок в качестве коэффициентов для рядов Фурье, см. статью Википедии для получения дополнительной информации. Различно окрашивая эти кривые для каждого класса, можно визуализировать кластеризацию данных. Кривые, принадлежащие выборкам одного класса, обычно будут располагаться ближе друг к другу и образовывать более крупные структуры.

Примечание: Набор данных «Ирис» доступен здесь.

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");
../_images/andrews_curves.png

Параллельные координаты

Параллельные координаты — это метод построения графиков многомерных данных, см. статью Википедии для введения. Параллельные координаты позволяют визуально увидеть кластеры в данных и оценить другие статистические данные. В параллельных координатах точки представлены соединенными отрезками прямых. Каждая вертикальная линия представляет один атрибут. Один набор соединенных отрезков прямых представляет одну точку данных. Точки, которые имеют тенденцию к кластеризации, будут казаться расположенными ближе друг к другу.

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");
../_images/parallel_coordinates.png

Диаграмма задержек

Диаграммы задержек используются для проверки того, является ли набор данных или временной ряд случайным. Случайные данные не должны иметь какой-либо структуры на диаграмме задержек. Неслучайная структура означает, что основополагающие данные не являются случайными. Аргумент 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);
../_images/lag_plot.png

График автокорреляции

Графики автокорреляции часто используются для проверки случайности временных рядов. Это делается путем вычисления автокорреляций значений данных при различных временных задержках. Если временной ряд случайный, такие автокорреляции должны быть близки к нулю для любых и всех временных задержек. Если временной ряд неслучайный, то одна или несколько автокорреляций будут значительно отличаться от нуля. Горизонтальные линии на графике соответствуют 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);
../_images/autocorrelation_plot.png

График бутстрапа

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

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");
../_images/bootstrap_plot.png

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");
../_images/radviz.png

Форматирование графиков

Установка стиля графика

Начиная с версии 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");
../_images/series_plot_basic2.png

Для каждого типа графика (например, 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);
../_images/frame_plot_basic_noleg.png

Управление метками

Введено в версии 1.1.0.

Вы можете установить аргументы xlabel и ylabel для присвоения графику пользовательских меток для осей X и Y. По умолчанию pandas использует имя индекса как метку оси X, а для метки оси Y оставляет пустое значение.

In [126]: df.plot();

In [127]: df.plot(xlabel="new x", ylabel="new y");
../_images/plot_xlabel_ylabel.png

Масштабы

Вы можете передать 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);
../_images/series_plot_logy.png

См. также ключевые аргументы logx и loglog.

Построение на дополнительной оси Y

Чтобы построить данные на дополнительной оси Y, используйте ключевое слово secondary_y.

In [131]: df["A"].plot();

In [132]: df["B"].plot(secondary_y=True, style="g");
../_images/series_plot_secondary_y.png

Чтобы построить некоторые столбцы в 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");
../_images/frame_plot_secondary_y.png

Обратите внимание, что столбцы, построенные на дополнительной оси Y, автоматически помечаются "(right)" в легенде. Чтобы отключить автоматическую маркировку, используйте ключевое слово mark_right=False:

In [137]: plt.figure();

In [138]: df.plot(secondary_y=["A", "B"], mark_right=False);
../_images/frame_plot_secondary_y_no_right.png

Настройка форматирования для временных рядов

Изменено в версии 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();
../_images/ser_plot_suppress.png

Используя параметр x_compat вы можете отключить это поведение:

In [141]: plt.figure();

In [142]: df["A"].plot(x_compat=True);
../_images/ser_plot_suppress_parm.png

Если у вас несколько графиков, которые нужно отключить, метод 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")
   .....: 
../_images/ser_plot_suppress_context.png

Автоматическая настройка делений дат

TimedeltaIndex теперь использует собственные методы локализации делений matplotlib, что полезно для вызова автоматической настройки делений дат из matplotlib для графиков, у которых метки делений перекрываются.

См. метод autofmt_xdate и документацию matplotlib для получения более подробной информации.

Подграфики

Каждый Series в DataFrame может быть построен на разных осях с помощью ключевого слова subplots:

In [145]: df.plot(subplots=True, figsize=(6, 6));
../_images/frame_plot_subplots.png

Использование макета и нацеливание на несколько осей

Макет подграфиков можно указать с помощью ключевого слова 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);
../_images/frame_plot_subplots_layout.png

Приведенный выше пример эквивалентен использованию:

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);
../_images/frame_plot_subplots_multi_ax.png

Другой вариант — передать аргумент 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");
../_images/series_plot_multi.png

Отображение с ошибками

Отображение с ошибками поддерживается в DataFrame.plot() и Series.plot().

Горизонтальные и вертикальные ошибки могут быть заданы в параметрах xerr и yerr для plot(). Значения ошибок могут быть заданы с использованием различных форматов:

  • В виде DataFrame или dict ошибок с именами столбцов, соответствующими атрибуту columns диаграммы DataFrame или атрибуту name Series.

  • В виде 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);
../_images/errorbar_example.png

Также поддерживаются асимметричные погрешности, однако в этом случае должны быть предоставлены исходные значения ошибок. Для 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);
../_images/errorbar_asymmetrical_example.png

Отображение таблиц

Отображение с помощью таблицы 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);
../_images/line_plot_table_true.png

Также можно передать другую 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);
../_images/line_plot_table_data.png

Также существует вспомогательная функция 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);
../_images/line_plot_table_describe.png

Примечание: Вы можете получить экземпляры таблиц на осях с помощью свойства 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");
../_images/cubehelix.png

В качестве альтернативы, мы можем передать саму цветовой карту:

In [193]: from matplotlib import cm

In [194]: plt.figure();

In [195]: df.plot(colormap=cm.cubehelix);
../_images/cubehelix_cm.png

Цветовые карты также могут использоваться в других типах графиков, таких как гистограммы:

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");
../_images/greens.png

Графики параллельных координат:

In [200]: plt.figure();

In [201]: parallel_coordinates(data, "Name", colormap="gist_rainbow");
../_images/parallel_gist_rainbow.png

Графики кривых Эндрюса:

In [202]: plt.figure();

In [203]: andrews_curves(data, "Name", colormap="winter");
../_images/andrews_curve_winter.png

Отображение напрямую с помощью 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);
../_images/bollinger.png

Отображение бэкэндов

Начиная с версии 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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API