0

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:

enter image description here

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:

enter image description here

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()
1

1 Answer 1

1

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()

using mplcursors to display a custom annotation

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.