Spec-Zone.ru › pandas 2

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

Примечание

В приведенных ниже примерах предполагается, что вы используете 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]: np.random.seed(123456)

In [4]: ts = pd.Series(np.random.randn(1000), index=pd.date_range("1/1/2000", periods=1000))

In [5]: ts = ts.cumsum()

In [6]: ts.plot();
../_images/series_plot_basic.png

Если индекс состоит из дат, он вызывает gcf().autofmt_xdate(), чтобы красиво отформатировать ось x, как показано выше.

Для DataFrame, plot() — это удобный способ построить все столбцы с метками:

In [7]: df = pd.DataFrame(np.random.randn(1000, 4), index=ts.index, columns=list("ABCD"))

In [8]: df = df.cumsum()

In [9]: plt.figure();

In [10]: df.plot();
../_images/frame_plot_basic.png

Вы можете построить один столбец против другого, используя ключевые слова x и y в plot():

In [11]: df3 = pd.DataFrame(np.random.randn(1000, 2), columns=["B", "C"]).cumsum()

In [12]: df3["A"] = pd.Series(list(range(len(df))))

In [13]: df3.plot(x="A", y="B");
../_images/df_plot_xy.png

Примечание

Дополнительные параметры форматирования и стилей см. ниже в разделе форматирование.

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

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

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

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

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

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

  • ‘area’ для диаграмм областей

  • ‘scatter’ для диаграмм рассеяния

  • ‘hexbin’ для диаграмм гексагонального разбиения

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

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

In [14]: plt.figure();

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

Вы также можете создать эти другие графики, используя методы DataFrame.plot.<kind> вместо указания ключевого аргумента kind. Это упрощает поиск методов построения графиков и используемых ими аргументов:

In [16]: df = pd.DataFrame()

In [17]: 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 [18]: plt.figure();

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

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

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

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

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

Для создания графика столбцов с накоплением передайте stacked=True:

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

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

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

Гистограммы

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

In [25]: 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 [26]: plt.figure();

In [27]: df4.plot.hist(alpha=0.5);
../_images/hist_new.png

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

In [28]: plt.figure();

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

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

In [30]: plt.figure();

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

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

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

In [32]: plt.figure();

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

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

In [34]: plt.figure();

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

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

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

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

Кроме того, ключевое слово by также можно указать в DataFrame.plot.hist().

Изменено в версии 1.4.0.

In [38]: 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 [39]: 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 [40]: df = pd.DataFrame(np.random.rand(10, 5), columns=["A", "B", "C", "D", "E"])

In [41]: 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 [42]: color = {
   ....:     "boxes": "DarkGreen",
   ....:     "whiskers": "DarkOrange",
   ....:     "medians": "DarkBlue",
   ....:     "caps": "Gray",
   ....: }
   ....: 

In [43]: df.plot.box(color=color, sym="r+");
../_images/box_new_colorize.png

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

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

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

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

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

In [46]: plt.figure();

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

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

In [48]: df = pd.DataFrame(np.random.rand(10, 2), columns=["Col1", "Col2"])

In [49]: df["X"] = pd.Series(["A", "A", "A", "A", "A", "B", "B", "B", "B", "B"])

In [50]: plt.figure();

In [51]: bp = df.boxplot(by="X")
../_images/box_plot_ex2.png

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

In [52]: df = pd.DataFrame(np.random.rand(10, 3), columns=["Col1", "Col2", "Col3"])

In [53]: df["X"] = pd.Series(["A", "A", "A", "A", "A", "B", "B", "B", "B", "B"])

In [54]: df["Y"] = pd.Series(["A", "B", "A", "B", "A", "B", "A", "B", "A", "B"])

In [55]: plt.figure();

In [56]: bp = df.boxplot(column=["Col1", "Col2"], by=["X", "Y"])
../_images/box_plot_ex3.png

Вы также можете создать группы с помощью DataFrame.plot.box(), например:

Изменено в версии 1.4.0.

In [57]: df = pd.DataFrame(np.random.rand(10, 3), columns=["Col1", "Col2", "Col3"])

In [58]: df["X"] = pd.Series(["A", "A", "A", "A", "A", "B", "B", "B", "B", "B"])

In [59]: plt.figure();

In [60]: 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

Нет

ось

None

Да

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

'axes'

Нет

ось

'axes'

Да

Последовательность осей

'dict'

Нет

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

'dict'

Да

Последовательность словарей объектов

'both'

Нет

namedtuple

'both'

Да

Последовательность namedtuple

Groupby.boxplot всегда возвращает Series из return_type.

In [61]: np.random.seed(1234)

In [62]: df_box = pd.DataFrame(np.random.randn(50, 2))

In [63]: df_box["g"] = np.random.choice(["A", "B"], size=50)

In [64]: df_box.loc[df_box["g"] == "B", 1] += 3

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

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

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

График площади

Вы можете создать графики площади с помощью Series.plot.area() и DataFrame.plot.area(). Графики площади по умолчанию являются стопкой. Для создания стопки графиков площади каждый столбец должен содержать либо только положительные, либо только отрицательные значения.

При входных данных, содержащих NaN, они автоматически заполняются 0. Если вы хотите удалить или заполнить другие значения, используйте dataframe.dropna() или dataframe.fillna() перед вызовом plot.

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

In [68]: df.plot.area();
../_images/area_plot_stacked.png

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

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

Диаграмма рассеяния

Диаграмму рассеяния можно построить с помощью метода DataFrame.plot.scatter(). Диаграмма рассеяния требует числовых столбцов для осей x и y. Их можно указать с помощью ключевых слов x и y.

In [70]: df = pd.DataFrame(np.random.rand(50, 4), columns=["a", "b", "c", "d"])

In [71]: df["species"] = pd.Categorical(
   ....:     ["setosa"] * 20 + ["versicolor"] * 20 + ["virginica"] * 10
   ....: )
   ....: 

In [72]: df.plot.scatter(x="a", y="b");
../_images/scatter_plot.png

Чтобы построить несколько групп столбцов на одной оси, повторите метод plot, указав целевую ax. Рекомендуется указать color и label ключевые слова, чтобы различать группы.

In [73]: ax = df.plot.scatter(x="a", y="b", color="DarkBlue", label="Group 1")

In [74]: df.plot.scatter(x="c", y="d", color="DarkGreen", label="Group 2", ax=ax);
../_images/scatter_plot_repeated.png

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

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

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

Добавлено в версии 1.3.0.

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

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

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

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

Диаграмма шестиугольных ячеек

Вы можете создать диаграммы шестиугольных ячеек с помощью DataFrame.plot.hexbin(). Диаграммы шестиугольных ячеек могут быть полезной альтернативой диаграммам рассеяния, если ваши данные слишком плотные, чтобы наносить каждую точку индивидуально.

In [78]: df = pd.DataFrame(np.random.randn(1000, 2), columns=["a", "b"])

In [79]: df["b"] = df["b"] + np.arange(1000)

In [80]: 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 [81]: df = pd.DataFrame(np.random.randn(1000, 2), columns=["a", "b"])

In [82]: df["b"] = df["b"] + np.arange(1000)

In [83]: df["z"] = np.random.uniform(0, 3, 1000)

In [84]: df.plot.hexbin(x="a", y="b", C="z", reduce_C_function=np.max, gridsize=25);
../_images/hexbin_plot_agg.png

См. метод hexbin и документацию matplotlib по диаграммам шестиугольных ячеек для получения дополнительной информации.

Диаграмма круговой диаграммы

Вы можете создать диаграмму круговой диаграммы с помощью DataFrame.plot.pie() или Series.plot.pie(). Если ваши данные содержат какие-либо NaN, они будут автоматически заполнены нулями. Будет поднята ошибка ValueError, если в ваших данных имеются отрицательные значения.

In [85]: series = pd.Series(3 * np.random.rand(4), index=["a", "b", "c", "d"], name="series")

In [86]: 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 [87]: df = pd.DataFrame(
   ....:     3 * np.random.rand(4, 2), index=["a", "b", "c", "d"], columns=["x", "y"]
   ....: )
   ....: 

In [88]: 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 [89]: 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 [90]: series = pd.Series([0.1] * 4, index=["a", "b", "c", "d"], name="series2")

In [91]: 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 [92]: from pandas.plotting import scatter_matrix

In [93]: df = pd.DataFrame(np.random.randn(1000, 4), columns=["a", "b", "c", "d"])

In [94]: scatter_matrix(df, alpha=0.2, figsize=(6, 6), diagonal="kde");
../_images/scatter_matrix_kde.png

Диаграмма плотности

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

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

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

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

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

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

In [97]: from pandas.plotting import andrews_curves

In [98]: data = pd.read_csv("data/iris.data")

In [99]: plt.figure();

In [100]: andrews_curves(data, "Name");
../_images/andrews_curves.png

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

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

In [101]: from pandas.plotting import parallel_coordinates

In [102]: data = pd.read_csv("data/iris.data")

In [103]: plt.figure();

In [104]: parallel_coordinates(data, "Name");
../_images/parallel_coordinates.png

Диаграмма с запаздыванием

Диаграммы с запаздыванием используются для проверки того, является ли набор данных или временной ряд случайным. Случайные данные не должны демонстрировать никакой структуры на диаграмме с запаздыванием. Структура, не являющаяся случайной, подразумевает, что исходные данные не случайны. Аргумент lag может быть передан, и когда lag=1 график по сути является data[:-1] по отношению к data[1:].

In [105]: from pandas.plotting import lag_plot

In [106]: plt.figure();

In [107]: spacing = np.linspace(-99 * np.pi, 99 * np.pi, num=1000)

In [108]: data = pd.Series(0.1 * np.random.rand(1000) + 0.9 * np.sin(spacing))

In [109]: lag_plot(data);
../_images/lag_plot.png

Диаграмма автокорреляции

Диаграммы автокорреляции часто используются для проверки случайности во временных рядах. Это делается путем вычисления автокорреляций для значений данных при различных временных лагах. Если временной ряд случайный, такие автокорреляции должны быть близки к нулю для любых и всех временных лагов. Если временной ряд не случайный, то одна или несколько автокорреляций будут существенно отличны от нуля. Горизонтальные линии на графике соответствуют 95% и 99% доверительным интервалам. Штриховая линия - 99% доверительный интервал. Смотрите статью Википедии здесь для получения дополнительной информации об автокорреляционных графиках.

In [110]: from pandas.plotting import autocorrelation_plot

In [111]: plt.figure();

In [112]: spacing = np.linspace(-9 * np.pi, 9 * np.pi, num=1000)

In [113]: data = pd.Series(0.7 * np.random.rand(1000) + 0.3 * np.sin(spacing))

In [114]: autocorrelation_plot(data);
../_images/autocorrelation_plot.png

Bootstrap-график

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

In [115]: from pandas.plotting import bootstrap_plot

In [116]: data = pd.Series(np.random.rand(1000))

In [117]: bootstrap_plot(data, size=50, samples=500, color="grey");
../_images/bootstrap_plot.png

RadViz

RadViz — это способ визуализации многомерных данных. Он основан на простом алгоритме минимизации натяжения пружины. В основном вы назначаете множество точек на плоскости. В нашем случае они равномерно распределены по единичной окружности. Каждая точка представляет отдельный атрибут. Затем вы представляете, что каждый образец в наборе данных подключен к каждой из этих точек пружиной, жесткость которой пропорциональна численному значению этого атрибута (они нормированы к единичному интервалу). Точка на плоскости, к которой наш образец стабилизируется (где силы, действующие на наш образец, находятся в равновесии), — это то место, где будет нарисована точка, представляющая наш образец. В зависимости от класса, к которому принадлежит образец, он будет окрашен по-разному. Смотрите пакет R Radviz для получения дополнительной информации.

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

In [118]: from pandas.plotting import radviz

In [119]: data = pd.read_csv("data/iris.data")

In [120]: plt.figure();

In [121]: radviz(data, "Name");
../_images/radviz.png

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

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

Начиная с версии 1.5, matplotlib предлагает ряд предварительно сконфигурированных стилей графиков. Установка стиля позволяет легко задать общий вид графиков. Установка стиля осуществляется простым вызовом matplotlib.style.use(my_plot_style) перед созданием графика. Например, вы можете написать matplotlib.style.use('ggplot') для графиков в стиле ggplot.

Вы можете ознакомиться с различными именами доступных стилей в matplotlib.style.available и очень легко их опробовать.

Общие аргументы стиля графика

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

In [122]: plt.figure();

In [123]: 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 [124]: df = pd.DataFrame(np.random.randn(1000, 4), index=ts.index, columns=list("ABCD"))

In [125]: df = df.cumsum()

In [126]: df.plot(legend=False);
../_images/frame_plot_basic_noleg.png

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

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

In [127]: df.plot();

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

Масштабы

Вы можете передать logy для получения логарифмического масштаба оси Y.

In [129]: ts = pd.Series(np.random.randn(1000), index=pd.date_range("1/1/2000", periods=1000))

In [130]: ts = np.exp(ts.cumsum())

In [131]: ts.plot(logy=True);
../_images/series_plot_logy.png

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

Построение на вторичной оси Y

Для построения данных на вторичной оси Y используйте ключевой аргумент secondary_y.

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

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

Для построения некоторых столбцов в DataFrame, передайте имена столбцов в ключевой аргумент secondary_y:

In [134]: plt.figure();

In [135]: ax = df.plot(secondary_y=["A", "B"])

In [136]: ax.set_ylabel("CD scale");

In [137]: ax.right_ax.set_ylabel("AB scale");
../_images/frame_plot_secondary_y.png

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

In [138]: plt.figure();

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

Пользовательские форматеры для временных рядов

pandas предоставляет пользовательские форматеры для графиков временных рядов. Они изменяют форматирование меток осей для дат и времени. По умолчанию пользовательские форматеры применяются только к графикам, созданным pandas с помощью DataFrame.plot() или Series.plot(). Чтобы применить их ко всем графикам, включая те, что созданы matplotlib, установите опцию pd.options.plotting.matplotlib.register_converters = True или используйте pandas.plotting.register_matplotlib_converters().

Отключение автоматической корректировки разрешения делений шкалы

pandas включает автоматическую корректировку разрешения делений шкалы для данных временных рядов с регулярной частотой. В ограниченных случаях, когда pandas не может определить информацию о частоте (например, в созданном внешним образом twinx), вы можете выбрать подавление этого поведения для выравнивания целей.

Вот поведение по умолчанию, обратите внимание, как выполняется маркировка делений оси X:

In [140]: plt.figure();

In [141]: df["A"].plot();
../_images/ser_plot_suppress.png

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

In [142]: plt.figure();

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

Если у вас есть более одного графика, который нужно подавить, метод use в pandas.plotting.plot_params может быть использован в инструкции with:

In [144]: plt.figure();

In [145]: 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 [146]: df.plot(subplots=True, figsize=(6, 6));
../_images/frame_plot_subplots.png

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

Макет подграфиков может быть задан ключевым аргументом layout . Он может принимать значение (rows, columns) . Ключевые аргументы layout можно использовать в hist и boxplot тоже. Если входной параметр некорректен, произойдет исключение ValueError.

Число осей, которое может содержать строка x столбцы, заданные layout, должно быть больше, чем количество требуемых подграфиков. Если макет может содержать больше осей, чем требуется, пустые оси не рисуются. Аналогично методу reshape массива NumPy, вы можете использовать -1 для одной размерности, чтобы автоматически вычислить необходимое количество строк или столбцов, зная другое.

In [147]: df.plot(subplots=True, layout=(2, 3), figsize=(6, 6), sharex=False);
../_images/frame_plot_subplots_layout.png

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

In [148]: df.plot(subplots=True, layout=(2, -1), figsize=(6, 6), sharex=False);

Требуемое количество столбцов (3) выводится из числа рядов для построения и заданного количества строк (2).

Вы можете передать несколько предварительно созданных осей как список через ключевой аргумент ax . Это позволяет создавать более сложные макеты. Передаваемые оси должны быть такими же, как количество подграфиков, которые строятся.

Когда несколько осей передаются через ключевой аргумент ax, ключевые аргументы layout, sharex и sharey не влияют на вывод. Вы должны явно передать sharex=False и sharey=False, в противном случае вы увидите предупреждение.

In [149]: fig, axes = plt.subplots(4, 4, figsize=(9, 9))

In [150]: plt.subplots_adjust(wspace=0.5, hspace=0.5)

In [151]: target1 = [axes[0][0], axes[1][1], axes[2][2], axes[3][3]]

In [152]: target2 = [axes[3][0], axes[2][1], axes[1][2], axes[0][3]]

In [153]: df.plot(subplots=True, ax=target1, legend=False, sharex=False, sharey=False);

In [154]: (-df).plot(subplots=True, ax=target2, legend=False, sharex=False, sharey=False);
../_images/frame_plot_subplots_multi_ax.png

Другой вариант - передать аргумент ax в Series.plot() для построения на конкретной оси:

In [155]: np.random.seed(123456)

In [156]: ts = pd.Series(np.random.randn(1000), index=pd.date_range("1/1/2000", periods=1000))

In [157]: ts = ts.cumsum()

In [158]: df = pd.DataFrame(np.random.randn(1000, 4), index=ts.index, columns=list("ABCD"))

In [159]: df = df.cumsum()
In [160]: fig, axes = plt.subplots(nrows=2, ncols=2)

In [161]: plt.subplots_adjust(wspace=0.2, hspace=0.5)

In [162]: df["A"].plot(ax=axes[0, 0]);

In [163]: axes[0, 0].set_title("A");

In [164]: df["B"].plot(ax=axes[0, 1]);

In [165]: axes[0, 1].set_title("B");

In [166]: df["C"].plot(ax=axes[1, 0]);

In [167]: axes[1, 0].set_title("C");

In [168]: df["D"].plot(ax=axes[1, 1]);

In [169]: 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 [170]: 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 [171]: 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 [172]: gp3 = df3.groupby(level=("letter", "word"))

In [173]: means = gp3.mean()

In [174]: errors = gp3.std()

In [175]: means
Out[175]: 
                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 [176]: errors
Out[176]: 
                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 [177]: fig, ax = plt.subplots()

In [178]: means.plot.bar(yerr=errors, ax=ax, capsize=4, rot=0);
../_images/errorbar_example.png

Также поддерживаются асимметричные погрешности, однако в этом случае должны быть предоставлены исходные значения погрешностей. Для Series длиной N, должен быть предоставлен массив 2xN, указывающий нижние и верхние (или левые и правые) погрешности. Для DataFrame длиной MxN, асимметричные погрешности должны быть в массиве Mx2xN.

Вот пример построения графика диапазона мин/макс с помощью асимметричных погрешностей.

In [179]: mins = gp3.min()

In [180]: maxs = gp3.max()

# errors should be positive, and defined in the order of lower, upper
In [181]: errors = [[means[c] - mins[c], maxs[c] - means[c]] for c in df3.columns]

# Plot
In [182]: fig, ax = plt.subplots()

In [183]: 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 [184]: np.random.seed(123456)

In [185]: fig, ax = plt.subplots(1, 1, figsize=(7, 6.5))

In [186]: df = pd.DataFrame(np.random.rand(5, 3), columns=["a", "b", "c"])

In [187]: ax.xaxis.tick_top()  # Display x-axis ticks on top.

In [188]: df.plot(table=True, ax=ax);
../_images/line_plot_table_true.png

Также вы можете передать другую DataFrame или Series аргументу table. Данные будут отображены так, как они отображаются в методе print (без автоматической транспонирования). При необходимости они должны быть транспонированы вручную, как показано в примере ниже.

In [189]: fig, ax = plt.subplots(1, 1, figsize=(7, 6.75))

In [190]: ax.xaxis.tick_top()  # Display x-axis ticks on top.

In [191]: 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 [192]: from pandas.plotting import table

In [193]: fig, ax = plt.subplots(1, 1)

In [194]: table(ax, np.round(df.describe(), 2), loc="upper right", colWidths=[0.2, 0.2, 0.2]);

In [195]: 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 [196]: np.random.seed(123456)

In [197]: df = pd.DataFrame(np.random.randn(1000, 10), index=ts.index)

In [198]: df = df.cumsum()

In [199]: plt.figure();

In [200]: df.plot(colormap="cubehelix");
../_images/cubehelix.png

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

In [201]: from matplotlib import cm

In [202]: plt.figure();

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

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

In [204]: np.random.seed(123456)

In [205]: dd = pd.DataFrame(np.random.randn(10, 10)).map(abs)

In [206]: dd = dd.cumsum()

In [207]: plt.figure();

In [208]: dd.plot.bar(colormap="Greens");
../_images/greens.png

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

In [209]: plt.figure();

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

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

In [211]: plt.figure();

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

Построение графиков напрямую с помощью Matplotlib

В некоторых ситуациях может быть предпочтительнее или необходимо готовить графики непосредственно с помощью matplotlib, например, когда определенный тип графика или настройка не поддерживается (или еще не поддерживается) pandas. Series и DataFrame объекты ведут себя как массивы и, следовательно, могут быть переданы непосредственно в функции matplotlib без явных преобразований.

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

In [213]: np.random.seed(123456)

In [214]: price = pd.Series(
   .....:     np.random.randn(150).cumsum(),
   .....:     index=pd.date_range("2000-1-1", periods=150, freq="B"),
   .....: )
   .....: 

In [215]: ma = price.rolling(20).mean()

In [216]: mstd = price.rolling(20).std()

In [217]: plt.figure();

In [218]: plt.plot(price.index, price, "k");

In [219]: plt.plot(ma.index, ma, "b");

In [220]: plt.fill_between(mstd.index, ma - 2 * mstd, ma + 2 * mstd, color="b", alpha=0.2);
../_images/bollinger.png

Графические бэкэнды

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/2.2.2/user_guide/visualization.html

Spec-Zone.ru

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