Построение временного ряда в виде гистограммы с пандами приводит к неправильному году

У меня есть следующий фрейм данных (за исключением того, что мои фактические данные старше 25 лет):

import pandas as pd


df = pd.DataFrame(
    dict(
        date=pd.date_range(start = "2020-01-01", end = "2020-12-31", freq = "MS"),
        data=[1,2,3,4,5,6,7,8,9,10,11,12]
    ), 
)
df

Выход:

    date    data
0   2020-01-01  1
1   2020-02-01  2
2   2020-03-01  3
3   2020-04-01  4
4   2020-05-01  5
5   2020-06-01  6
6   2020-07-01  7
7   2020-08-01  8
8   2020-09-01  9
9   2020-10-01  10
10  2020-11-01  11
11  2020-12-01  12

И я получаю разные результаты при построении графиков по умолчанию в matplotlib и pandas:

import matplotlib as mpl
import matplotlib.dates as mdates
import matplotlib.pyplot as plt


fig = mpl.figure.Figure(constrained_layout=True)
axs = fig.subplot_mosaic("ac;bd")

ax = axs["a"]
ax.bar(x = "date", height = "data", data=df, width=15)

ax = axs["b"]
ax.bar(x = "date", height = "data", data=df, width=15)

locator = mdates.AutoDateLocator(minticks=12, maxticks=24)
formatter = mdates.ConciseDateFormatter(locator)
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(formatter)

ax = axs["c"]
df.plot.bar(x = "date", y = "data", ax=ax, legend=False)

ax = axs["d"]

df.plot.bar(x = "date", y = "data", ax=ax, legend=False, ) # incorrect year -> 1970 instead of 2020

locator = mdates.AutoDateLocator(minticks=12, maxticks=24)
formatter = mdates.ConciseDateFormatter(locator)
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(formatter)

for k, ax in axs.items():
    for label in ax.get_xticklabels():
        label.set_rotation(40)
        label.set_horizontalalignment('right')

fig

Выход:

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

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


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

import matplotlib as mpl
import matplotlib.dates as mdates
import matplotlib.pyplot as plt
fig = mpl.figure.Figure(constrained_layout=True)
axs = fig.subplot_mosaic("a")

ax = axs["a"]

df.plot.bar(x = "date", y = "data", ax=ax, legend=False) # incorrect year -> 1970 instead of 2020

formatter = mdates.DateFormatter("%Y - %b")
ax.xaxis.set_major_formatter(formatter)

fig

При использовании DateFormatter даты указаны неправильно.

Какие метки осей вам нужны? Мне все примеры кажутся верными. Все точки данных относятся к одному и тому же году (2020), и вы использовали ConciseDateFormatter, поэтому год отображается только для первой точки данных. Используйте DateFormatter, если вам нужен определенный формат для всех ярлыков.

Code Different 17.08.2024 15:53

Я хочу использовать код для последнего графика (внизу справа), но год для него отображается как 1970-Jan.

kdheepak 17.08.2024 16:50

В документации pandas говорится, что он вызывает fig.autoformat_xdate(), но когда я вызываю это вручную, я не получаю тех же результатов в matplotlib. Это ошибка в пандах? Как мне заставить панд вести себя так же, как должен вести себя matplotlib?

kdheepak 17.08.2024 17:06

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

kdheepak 17.08.2024 17:13
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
4
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Когда вы используете гистограмму, координаты x становятся 0, 1, 2, 3 и т. д. Вот почему mdates.DateFormatter возвращает 1970, поскольку он рассматривает эти координаты как секунды, прошедшие с начала эпохи.

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

ax.set_xticklabels(df["date"].dt.strftime("%Y - %b"))

Спасибо за ответ, похоже, в этом проблема. В частности, к сожалению, похоже, что когда кто-то использует df.plot(kind = "bar"), панды всегда рассматривают ось X как категориальные значения. Я перешел на использование площадных диаграмм вместо гистограмм.

kdheepak 17.08.2024 22:22

Я открыл проблему на pandas-dev/pandas с предложением улучшить гистограммы с помощью индексов даты и времени: github.com/pandas-dev/pandas/issues/59543

kdheepak 17.08.2024 23:18

Другие вопросы по теме