Reputation: 1
I know this question has been asked before but I couldn't find the answer to my question so I hope to find a solution here I want to create the chart to show First day of snow vs. Last day of snow. The chart is the following:
the X axis is the year, Y axis is the day in the year that has snow. However, I want to the data label when mouse hover to show the actual date. Example: [x,y] = [140, 1873]. Data label to be '1873-11-18'. The data label comes from different column of the data frame. Here is my dataframe:
fig, ((ax1,ax2)) = plt.subplots(2,1, figsize=(12,8),constrained_layout=True)
colors = ['skyblue', 'coral', 'mediumaquamarine']
Xticks = np.arange(1880, 2021, 20)
snow.plot(x = 'Snow Year', y = ['First DOS', 'Last DOS'], color = colors, ax = ax1)
snow.plot(x = 'Snow Year', y = ['Snow length'], color = 'mediumaquamarine', ax = ax2)
sns.regplot(x='Snow Year',y='First DOS', data = snow, fit_reg=True, ax = ax1)
sns.regplot(x='Snow Year',y='Last DOS', data = snow, fit_reg=True, ax = ax1)
sns.regplot(x='Snow Year',y='Snow length', data = snow, fit_reg=True, ax = ax2)
ax1.legend(bbox_to_anchor=(1,1), loc="upper left")
ax2.legend(bbox_to_anchor=(1,1), loc="upper left")
plt.show()
Upvotes: 0
Views: 1834
Reputation: 80289
You could use the mplcursors library to automatically add an annotation while hovering. The annotation function can adapt the text to be displayed, for example by looking up rows in the dataframe. Newlines ('\n'
) can distribute the text over multiple lines.
Here is an example for the first plot. The code can easily be adapted to display additional columns from the dataframe.
import numpy as np
from numpy.random import randint
import matplotlib.pyplot as plt
import mplcursors
import pandas as pd
import seaborn as sns
def show_annation1(sel):
index = round(sel.target.index)
snow.iloc[index]['First Snow Date']
row = snow.iloc[index]
sel.annotation.set_text(f"{row['First Snow Date']} - {row['Last Snow Date']}\n(Length: {row['Snow length']})")
# create some dummy data for testing purposes
years = np.arange(1870, 2021)
snow = pd.DataFrame({'Snow Year': years,
'First Snow Date': [f'{y - 1}-{randint(11, 13)}-{randint(1, 31)}' for y in years],
'First DOS': randint(135, 200, len(years)),
'Last Snow Date': [f'{y}-{randint(3, 5)}-{randint(1, 31)}' for y in years],
'Last DOS': np.random.randint(250, 304, len(years))})
snow['Snow length'] = snow['Last DOS'] - snow['First DOS']
fig, ((ax1, ax2)) = plt.subplots(2, 1, figsize=(12, 8))
colors = ['skyblue', 'coral', 'mediumaquamarine']
ax2.set_xticks = np.arange(1880, 2021, 20)
snow.plot(x='Snow Year', y=['First DOS', 'Last DOS'], color=colors, ax=ax1)
snow.plot(x='Snow Year', y=['Snow length'], color='mediumaquamarine', ax=ax2)
sns.regplot(x='Snow Year', y='First DOS', data=snow, fit_reg=True, ax=ax1)
sns.regplot(x='Snow Year', y='Last DOS', data=snow, fit_reg=True, ax=ax1)
sns.regplot(x='Snow Year', y='Snow length', data=snow, fit_reg=True, ax=ax2)
ax1.legend(bbox_to_anchor=(1, 1), loc="upper left")
ax2.legend(bbox_to_anchor=(1, 1), loc="upper left")
cursor1 = mplcursors.cursor(ax1.lines, hover=True)
cursor1.connect('add', show_annation1)
# cursor2 = mplcursors.cursor(ax2.lines, hover=True)
# cursor2.connect('add', show_annation2)
plt.tight_layout()
plt.show()
Upvotes: 1