Я работаю с набором ежемесячных усредненных данных временных рядов, охватывающих более 20 лет, и помещаю данные в фрейм данных pandas. Индекс кадра данных состоит из объектов datetime, которые охватывают временной диапазон набора данных. Я успешно создал подграфик двумерной гистограммы как по времени, так и по другому параметру — скорости протонов. Ось X гистограммы была создана действием, которое выглядит как действие по умолчанию, но я не знаю, как это интерпретировать. Я пытался отформатировать ось X с помощью команд matplotlib, в первую очередь функций локатора/форматирования даты, но они продолжают выдавать огромную ошибку переполнения, которая заканчивается: «OverflowError: int слишком большой для преобразования».
Мне не удалось найти хорошее решение с помощью других вопросов или документации.
Это импорт, который я использовал до сих пор:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime, date, time
import matplotlib.dates as mdates
Ниже приведен фрейм данных pandas, который я использовал. Прошу прощения, если форматирование странное. Я не знал, как поделиться таблицей, поэтому скопировал фрейм данных прямо из своего блокнота. Здесь столбцы должны быть разделены табуляцией.
Datetime proton_density proton_temp He4toprotons proton_speed x_dot_RTN Proton Mass Flux
----------------------------------------------------------------------------------------
1998-01-23 11.625 58930.0 0.0224 380.90 379.91 7.406307e-19
1998-02-19 9.569 64302.0 0.0294 380.99 380.23 6.097867e-19
1998-03-18 8.767 66770.0 0.0348 384.00 383.19 5.630929e-19
1998-04-14 7.410 121090.0 0.0352 448.44 446.58 5.558023e-19
1998-05-11 7.881 102230.0 0.0271 421.21 419.87 5.552362e-19
... ... ... ... ... ... ...
2021-09-19 8.244 55183.0 0.0356 384.52 383.22 5.302183e-19
2021-10-16 9.664 70601.0 0.0115 418.50 416.21 6.764725e-19
2021-11-12 6.137 93617.0 0.0256 450.47 449.30 4.624021e-19
2021-12-09 4.889 96768.0 0.0177 426.52 424.99 3.487845e-19
2022-01-05 7.280 85944.0 0.0310 434.17 433.01 5.286752e-19
Вот код, который я использовал для создания гистограммы:
ax_example = plt.subplot2grid((3, 6), (2, 1), colspan = 2)
H,xedges,yedges = np.histogram2d(SWEPAM_dataframe.index, SWEPAM_dataframe.proton_speed, bins=[50,50])
ax_example.pcolor(xedges, yedges, H.T)
ax_example.set_xlabel("Year")
ax_example.set_ylabel("Proton Speed (km/s)")
Результат был такой:
Как вы можете видеть, ось X по умолчанию не находится в дате и времени. На самом деле я не уверен, как интерпретировать значения оси X по умолчанию, но здесь это не так важно. Я обнаружил, что мне следует использовать некоторую комбинацию ax2.xaxis.set_major_locator(loc)
и ax2.xaxis.set_major_formatter(fmt)
. Однако каждый раз, когда я пытаюсь использовать эти команды, я получаю вышеупомянутую ошибку переполнения, и мне не удается повернуть ось X моей гистограммы в нужные даты.
Публикация вывода команды to_dict позволяет нам легче воспроизвести ваш фрейм данных. Публикации print(df)
, как вы, часто бывает достаточно, за исключением случаев, когда мы имеем дело с типами dtypes, такими как datetime.
Я мог бы воспроизвести вашу проблему. Вопрос в том, почему xedges
возвращает такие большие числа (в диапазоне 10^17), и это нужно выяснить с помощью , как matplotlib читает объекты datetime , в какой единице времени с эпохи.
Я пытался заставить его работать надежно, чтобы дать полный ответ.
Также об этой ошибке переполнения уже сообщалось в Установите данные xaxis в datetime в matplotlib, не получив убедительного ответа.
В качестве альтернативы, seaborn лучше, чем matplotlib, обрабатывает dtype datetime в кадрах данных pandas, не требуя дальнейших манипуляций с осями:
import seaborn as sns
# with input: (without setting `"Datetime"` as index)
df = pd.DataFrame(columns = ['Datetime','proton_density','proton_temp','He4toprotons','proton_speed','x_dot_RTN','Proton_Mass_Flux'],
data = [['1998-01-23',11.625,58930.0,0.0224,380.90,379.91,7.406307e-19],
['1998-02-19', 9.569,64302.0,0.0294,380.99,380.23,6.097867e-19],
['1998-03-18', 8.767,66770.0,0.0348,384.00,383.19,5.630929e-19],
['1998-04-14',7.410,121090.0,0.0352,448.44,446.58,5.558023e-19],
['1998-05-11',7.881,102230.0,0.0271,421.21,419.87,5.552362e-19],
['2021-09-19', 8.244,55183.0,0.0356,384.52,383.22,5.302183e-19],
['2021-10-16', 9.664,70601.0,0.0115,418.50,416.21,6.764725e-19],
['2021-11-12', 6.137,93617.0,0.0256,450.47,449.30,4.624021e-19],
['2021-12-09', 4.889,96768.0,0.0177,426.52,424.99,3.487845e-19],
['2022-01-05', 7.280,85944.0,0.0310,434.17,433.01,5.286752e-19]])
df['Datetime'] = pd.to_datetime(df['Datetime'])
Затем будут созданы ожидаемые 2D-гистограммы и метки осей:
sns.histplot(df, x = "Datetime", y = "proton_speed")
Ось X гистограммы будет равна количеству наносекунд от эпохи datetime (в данном случае эпохи Unix 1970-01-01 00:00). Вы можете вручную преобразовать эти значения наносекунд, чтобы вместо них отображался год, как показано ниже:
from matplotlib import pyplot as plt
import matplotlib.dates as mdates
fig, ax = plt.subplots()
# just use Matplotlib's hist2d
ax.hist2d(x=SWEPAM_dataframe.index, y=SWEPAM_dataframe.proton_speed, bins=[50, 50])
# extract the x-tick locations
xticks = ax.get_xticks()
# convert the values (converted from ns to fraction of a day) to datetime
# and set the tick labels to show the Year ("%Y")
ax.set_xticklabels(
[mdates.num2date(xtick / (86400 * 1e9)).strftime("%Y") for xtick in xticks]
)
@OCa, на самом деле я определил индекс на основе теперь удаленного столбца Datetime через
SWEPAM_dataframe.index = SWEPAM_dataframe.Datetime
. На ваш второй вопрос: эта команда возвращает{'proton_density': {Timestamp('1998-01-23 00:00:00'): 11.625,...}
для пяти точек данных в 1998 году для каждого столбца. Я не слишком знаком с этой командой, поэтому не знаю, является ли это только частью отображаемого возврата. В данных 325 строк.