Визуализация диаграмм
Примечание
В приведенных ниже примерах предполагается, что вы используете 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();
Если индекс состоит из дат, он вызывает 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();
Вы можете построить один столбец против другого, используя ключевые слова 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");
Примечание
Дополнительные параметры форматирования и стилей см. ниже в разделе форматирование.
Другие графики
Методы построения графиков поддерживают несколько стилей графиков помимо стандартной линии. Эти методы можно указать в качестве ключевого аргумента kind к plot(), и включают:
‘hist’ для гистограммы
‘box’ для ящиковой диаграммы
‘area’ для диаграмм областей
‘scatter’ для диаграмм рассеяния
‘hexbin’ для диаграмм гексагонального разбиения
‘pie’ для круговых диаграмм
Например, гистограмму можно создать следующим образом:
In [14]: plt.figure();
In [15]: df.iloc[5].plot(kind="bar");
Вы также можете создать эти другие графики, используя методы 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 в качестве аргумента. К ним относятся:
Графики также могут быть дополнены ошибками или таблицами.
Диаграммы столбцов
Для помеченных данных, не являющихся временными рядами, вы можете создать диаграмму столбцов:
In [18]: plt.figure();
In [19]: df.iloc[5].plot.bar();
In [20]: plt.axhline(0, color="k");
Вызов метода plot.bar() DataFrame создает диаграмму с несколькими столбцами:
In [21]: df2 = pd.DataFrame(np.random.rand(10, 4), columns=["a", "b", "c", "d"])
In [22]: df2.plot.bar();
Для создания графика столбцов с накоплением передайте stacked=True:
In [23]: df2.plot.bar(stacked=True);
Для получения горизонтальных диаграмм столбцов используйте метод barh:
In [24]: df2.plot.barh(stacked=True);
Гистограммы
Гистограммы можно построить, используя методы 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);
Гистограмму можно сделать накопленной, используя stacked=True. Размер ячеек можно изменить с помощью ключевого слова bins.
In [28]: plt.figure();
In [29]: df4.plot.hist(stacked=True, bins=20);
Вы можете передать другие ключевые слова, поддерживаемые matplotlib hist. Например, горизонтальную и кумулятивную гистограммы можно построить, используя orientation='horizontal' и cumulative=True.
In [30]: plt.figure();
In [31]: df4["a"].plot.hist(orientation="horizontal", cumulative=True);
См. метод hist и документацию matplotlib по гистограммам matplotlib hist documentation для получения дополнительной информации.
Существующий интерфейс DataFrame.hist для построения гистограмм по-прежнему доступен.
In [32]: plt.figure();
In [33]: df["A"].diff().hist();
DataFrame.hist() строит гистограммы столбцов на нескольких подграфиках:
In [34]: plt.figure();
In [35]: df.diff().hist(color="k", alpha=0.5, bins=50);
Ключевое слово by можно указать для построения сгруппированных гистограмм:
In [36]: data = pd.Series(np.random.randn(1000))
In [37]: data.hist(by=np.random.randint(0, 4, 1000), figsize=(6, 4));
Кроме того, ключевое слово 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));
Диаграммы размаха
Диаграмму размаха можно построить, вызвав 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();
Диаграмму размаха можно окрасить, передав 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+");
Также вы можете передать другие ключевые слова, поддерживаемые matplotlib boxplot. Например, горизонтальную и настраиваемую диаграмму размаха можно построить, используя vert=False и positions ключевые слова.
In [44]: df.plot.box(vert=False, positions=[1, 4, 5, 6, 8]);
См. метод boxplot и документацию matplotlib по диаграммам размаха для получения дополнительной информации.
Существующий интерфейс DataFrame.boxplot для построения диаграмм размаха по-прежнему может использоваться.
In [45]: df = pd.DataFrame(np.random.rand(10, 5))
In [46]: plt.figure();
In [47]: bp = df.boxplot()
Вы можете создать стратифицированную диаграмму размаха, используя 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")
Вы также можете передать подмножество столбцов для построения, а также сгруппировать по нескольким столбцам:
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"])
Вы также можете создать группы с помощью 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")
В boxplot, тип возвращаемого значения может контролироваться return_type, ключевым словом. Допустимые варианты {"axes", "dict", "both", None}. Фрейминг, созданный с помощью DataFrame.boxplot с by ключевым словом, также повлияет на тип выходных данных:
| С фреймингом | Тип результата |
|---|---|---|
| Нет | ось |
| Да | 2-мерный массив осей |
| Нет | ось |
| Да | Последовательность осей |
| Нет | словарь объектов |
| Да | Последовательность словарей объектов |
| Нет | namedtuple |
| Да | Последовательность 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")
Подграфики выше разделены сначала по числовым столбцам, затем по значению столбца g. Под подграфиками подграфики сначала разбиваются по значению g, а затем по числовым столбцам.
In [66]: bp = df_box.groupby("g").boxplot()
График площади
Вы можете создать графики площади с помощью 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();
Для создания не стопчатого графика передайте stacked=False. Значение альфа установлено в 0,5, если не указано иное:
In [69]: df.plot.area(stacked=False);
Диаграмма рассеяния
Диаграмму рассеяния можно построить с помощью метода 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");
Чтобы построить несколько групп столбцов на одной оси, повторите метод 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);
Ключевое слово c может быть задано как имя столбца, чтобы задать цвета для каждой точки:
In [75]: df.plot.scatter(x="a", y="b", c="c", s=50);
Если категориальный столбец передан в c, будет создана дискретная цветовая шкала:
Добавлено в версии 1.3.0.
In [76]: df.plot.scatter(x="a", y="b", c="species", cmap="viridis", s=50);
Вы можете передать другие ключевые слова, поддерживаемые matplotlib scatter. Приведенный ниже пример показывает пузырьковую диаграмму, используя столбец DataFrame в качестве размера пузырьков.
In [77]: df.plot.scatter(x="a", y="b", s=df["c"] * 200);
См. метод 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);
Полезным ключевым аргументом является 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);
См. метод 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));
Для круговых диаграмм лучше использовать квадратные фигуры, т.е. соотношение сторон фигуры 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));
Вы можете использовать ключевые слова 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),
....: );
....:
Если вы передаете значения, сумма которых меньше 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));
Для получения дополнительной информации см. документацию по круговым диаграммам 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");
Диаграмма плотности
Вы можете создать диаграммы плотности, используя методы Series.plot.kde() и DataFrame.plot.kde().
In [95]: ser = pd.Series(np.random.randn(1000))
In [96]: ser.plot.kde();
Кривые Эндрюса
Кривые Эндрюса позволяют отображать многомерные данные как большое количество кривых, созданных с использованием атрибутов образцов в качестве коэффициентов для рядов Фурье. Смотрите статью Википедии здесь для получения дополнительной информации. Различием в цвете этих кривых для каждого класса можно визуализировать кластеризацию данных. Кривые, принадлежащие образцам одного класса, обычно будут ближе друг к другу и образуют более крупные структуры.
Примечание: Набор данных «Ирис» доступен здесь.
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");
Параллельные координаты
Параллельные координаты — это метод построения графиков для многомерных данных. Смотрите статью Википедии здесь для знакомства. Параллельные координаты позволяют визуально увидеть кластеры в данных и оценить другие статистические характеристики. В параллельных координатах точки представляются связанными отрезками прямых. Каждая вертикальная линия представляет один атрибут. Один набор связанных отрезков прямых представляет одну точку данных. Точки, которые имеют тенденцию к кластеризации, будут появляться ближе друг к другу.
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");
Диаграмма с запаздыванием
Диаграммы с запаздыванием используются для проверки того, является ли набор данных или временной ряд случайным. Случайные данные не должны демонстрировать никакой структуры на диаграмме с запаздыванием. Структура, не являющаяся случайной, подразумевает, что исходные данные не случайны. Аргумент 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);
Диаграмма автокорреляции
Диаграммы автокорреляции часто используются для проверки случайности во временных рядах. Это делается путем вычисления автокорреляций для значений данных при различных временных лагах. Если временной ряд случайный, такие автокорреляции должны быть близки к нулю для любых и всех временных лагов. Если временной ряд не случайный, то одна или несколько автокорреляций будут существенно отличны от нуля. Горизонтальные линии на графике соответствуют 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);
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");
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");
Форматирование графиков
Установка стиля графика
Начиная с версии 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");
Для каждого типа графика (например, 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);
Управление метками
Вы можете установить аргументы xlabel и ylabel для задания пользовательских меток для осей X и Y. По умолчанию pandas будет использовать имя индекса в качестве метки оси X, а для метки оси Y оставит пустое значение.
In [127]: df.plot();
In [128]: df.plot(xlabel="new x", ylabel="new y");
Масштабы
Вы можете передать 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);
См. также ключевые аргументы logx и loglog.
Построение на вторичной оси Y
Для построения данных на вторичной оси Y используйте ключевой аргумент secondary_y.
In [132]: df["A"].plot();
In [133]: df["B"].plot(secondary_y=True, style="g");
Для построения некоторых столбцов в 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");
Обратите внимание, что столбцы, нарисованные на вторичной оси Y, автоматически отмечаются "(right)" в легенде. Чтобы отключить автоматическое маркирование, используйте ключевой аргумент mark_right=False.
In [138]: plt.figure();
In [139]: df.plot(secondary_y=["A", "B"], mark_right=False);
Пользовательские форматеры для временных рядов
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();
Используя параметр x_compat, вы можете подавить это поведение:
In [142]: plt.figure();
In [143]: df["A"].plot(x_compat=True);
Если у вас есть более одного графика, который нужно подавить, метод 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")
.....:
Автоматическая корректировка делений шкалы дат
TimedeltaIndex теперь использует собственные методы локализации делений matplotlib, это полезно для вызова автоматической корректировки делений шкалы дат из matplotlib для графиков, метки делений которых перекрываются.
См. метод autofmt_xdate и документацию matplotlib для получения дополнительной информации.
Подграфики
Каждый Series в DataFrame может быть нарисован на разных осях с использованием ключевого аргумента subplots:
In [146]: df.plot(subplots=True, figsize=(6, 6));
Использование макета и нацеливание на несколько осей
Макет подграфиков может быть задан ключевым аргументом 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);
Приведенный выше пример идентичен использованию:
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);
Другой вариант - передать аргумент 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");
Отображение с погрешностями
Отображение с погрешностями поддерживается в DataFrame.plot() и Series.plot().
Горизонтальные и вертикальные погрешности могут быть заданы с помощью аргументов xerr и yerr для plot(). Значения погрешности могут быть заданы в различных форматах:
В виде
DataFrameилиdictпогрешностей с именами столбцов, соответствующими атрибутуcolumnsдиаграммыDataFrameили соответствующим атрибутуnameSeries.В виде
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);
Также поддерживаются асимметричные погрешности, однако в этом случае должны быть предоставлены исходные значения погрешностей. Для 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);
Отображение таблиц
Отображение с таблицей 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);
Также вы можете передать другую 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);
Также существует вспомогательная функция 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);
Примечание: Вы можете получить экземпляры таблицы на оси, используя свойство 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");
В качестве альтернативы, мы можем передать саму цветовую карту:
In [201]: from matplotlib import cm
In [202]: plt.figure();
In [203]: df.plot(colormap=cm.cubehelix);
Цветовые карты также можно использовать в других типах графиков, таких как гистограммы:
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");
Графики параллельных координат:
In [209]: plt.figure();
In [210]: parallel_coordinates(data, "Name", colormap="gist_rainbow");
Графики кривых Эндрюса:
In [211]: plt.figure();
In [212]: andrews_curves(data, "Name", colormap="winter");
Построение графиков напрямую с помощью 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);
Графические бэкэнды
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