Matplotlib DateFormatter для метки оси не работает
Я пытаюсь настроить форматирование меток даты на оси абсцисс, чтобы в нем отображались только значения года и месяца. Из того, что я нашел в Интернете, я должен использовать mdates.DateFormatter
, но он не вступает в силу с моим текущим кодом, как есть. Кто-нибудь видит, где проблема? (даты - это индекс пирамиды данных)
import matplotlib.dates as mdates
import matplotlib.pyplot as plt
import pandas as pd
fig = plt.figure(figsize = (10,6))
ax = fig.add_subplot(111)
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
basicDF['some_column'].plot(ax=ax, kind='bar', rot=75)
ax.xaxis_date()
![enter image description here]()
Воспроизводимый код сценария:
import numpy as np
import matplotlib.dates as mdates
import matplotlib.pyplot as plt
import pandas as pd
rng = pd.date_range('1/1/2014', periods=20, freq='m')
blah = pd.DataFrame(data = np.random.randn(len(rng)), index=rng)
fig = plt.figure(figsize = (10,6))
ax = fig.add_subplot(111)
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
blah.plot(ax=ax, kind='bar')
ax.xaxis_date()
До сих пор не могу найти только год и месяц.
Если я установлю формат после .plot, получим ошибку, подобную этой:
ValueError: DateFormatter обнаружил значение x = 0, что является недопустимой датой. Обычно это происходит потому, что вы не сообщили оси, что она наносит на график даты, например, с помощью x.xaxis_date()
.
То же самое, если я поставлю его перед ax.xaxis_date() или после.
Ответы
Ответ 1
Панды просто плохо работают с пользовательскими форматами даты и времени.
Вам просто нужно использовать raw matplotlib в подобных случаях.
import numpy
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import pandas
N = 20
numpy.random.seed(N)
dates = pandas.date_range('1/1/2014', periods=N, freq='m')
df = pandas.DataFrame(
data=numpy.random.randn(N),
index=dates,
columns=['A']
)
fig, ax = plt.subplots(figsize=(10, 6))
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
ax.bar(df.index, df['A'], width=25, align='center')
И это дает мне:
![enter image description here]()
Ответ 2
В принятом ответе утверждается, что "панды не будут хорошо работать с пользовательскими форматами даты и времени", но вы можете использовать функцию панд to_datetime()
, чтобы использовать существующий ряд даты и времени в фрейме данных:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter
import pandas as pd
rng = pd.date_range('1/1/2014', periods=20, freq='m')
blah = pd.DataFrame(data = np.random.randn(len(rng)), index=pd.to_datetime(rng))
fig, ax = plt.subplots()
ax.xaxis.set_major_formatter(DateFormatter('%m-%Y'))
ax.bar(blah.index, blah[0], width=25, align='center')
В результате:
![a bar graph with the dates formatted as described]()
Вы можете увидеть различные доступные форматы здесь.