Я пытаюсь создать двумерную гистограмму данных swepam (скорость протонов по оси Y и время по оси X) с разбивкой по времени по годам и скоростью протонов по 25 км/с. Я также пытаюсь нормализовать столбцы 2D-гистограммы. Я хотел бы сделать так, чтобы количество отдельных счетчиков в y-бине делилось на общее количество счетчиков в сумме столбцов до одного в каждом y-бине для данного столбца/временного интервала. Надеюсь, это имеет смысл, но если нет, я буду рад уточнить. Я также пытаюсь наложить данные из ssn на гистограмму в виде линейного графика.
Моя проблема двоякая. Во-первых, и что более важно, я могу отобразить гистограмму, но не могу отобразить линейный график. Во-вторых, цветная полоса гистограммы продолжает закрывать заголовки осей независимо от положения.
Ниже приведен код, который я собрал, чтобы попытаться построить этот график:
Код: Выделить всё
fig=plt.figure()
ax1 = fig.add_subplot(111)
ax2 = ax1.twinx()
# Define the range for proton speed bins
speed_min = 245
speed_max = swepam.proton_speed.max() + 25
speed_step = 25
speed_bins = np.arange(speed_min, speed_max, speed_step)
# Define the range for years
year_min = swepam['Datetime'].dt.year.min()
year_max = swepam['Datetime'].dt.year.max()
year_bins = np.arange(year_min, year_max + 1, 1) # include the last year
# Map the 'Datetime' to 'year' as a new column for easier grouping
swepam['Year'] = swepam['Datetime'].dt.year
# Create the 2D histogram data
histogram = np.zeros((len(speed_bins)-1, len(year_bins)-1))
for i, year in enumerate(year_bins[:-1]):
year_data = swepam[swepam['Year'] == year]
hist, _ = np.histogram(year_data['proton_speed'], bins=speed_bins)
histogram[:, i] = hist
# Normalize by year columns
histogram_normed = histogram / histogram.sum(axis=0)
# Create a heatmap DataFrame
heatmap_data = pd.DataFrame(
histogram_normed,
index=speed_bins[:-1],
columns=year_bins[:-1]
)
# Create the Seaborn heatmap
sns.heatmap(heatmap_data, annot=False, fmt=".2f", linewidths=.5, cmap='viridis', cbar_kws=dict(label = 'Counts (column bins sum to one)', use_gridspec = False, location = "bottom"), ax = ax1)
ax1.set_xlabel('Year')
ax1.set_ylabel('Proton Speed (km/s)')
# Invert the y-axis to have the higher speed bins at the top
ax1.invert_yaxis()
# Resample SSN data to get the monthly mean just in case.
ssn_monthly_mean = ssn_data['ssn'].resample('M').mean().reset_index()
# Plot the SSN data using Seaborn's lineplot on the secondary y-axis (ax2)
sns.lineplot(data=ssn_monthly_mean, x='Datetime', y='ssn', ax=ax2, color="orange", label='Monthly Mean SSN')
# Set secondary y-axis limits if needed
ax2.set_ylim(ssn_monthly_mean['ssn'].min(), ssn_monthly_mean['ssn'].max())
# Set the ylabel for the secondary y-axis and create the legend
ax2.set_ylabel('SSN', color='black')
ax2.legend(loc='upper left')
# Title and layout adjustments
plt.title('Proton Speed Distribution with SSN Overlay')
#plt.tight_layout()
plt.show()

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


Я пытался использовать seaborn, matplotlib, и даже создание графиков с нуля, используя минимальное количество стандартных процедур. Однако ничего не помогло. Некоторые методы, которые я пробовал, работают лучше, чем другие. Однако некоторые методы в конечном итоге вызывают больше проблем, например ошибки переполнения при работе с объектами Datetime.
Заранее благодарим вас за любую помощь, которую вы можете оказать!
Подробнее здесь: https://stackoverflow.com/questions/787 ... rn-heatmap