nas nas -4 years ago 127
Python Question

How can I show plot data in a popup box when I move the mouse to the marker in the plot

I have following lines of code to generate a plot as shown below.

from matplotlib import pyplot as plt
from mpldatacursor import datacursor
from matplotlib import dates as mdates
import datetime

date = [datetime.date(2015, 7, 1), datetime.date(2015, 8, 1), datetime.date(2015, 9, 1), datetime.date(2015, 10, 1), datetime.date(2015, 11, 1), datetime.date(2015, 12, 1), datetime.date(2016, 1, 1), datetime.date(2016, 2, 1)]
people = [0, 0, 0, 0, 0, 0, 122, 38]

fig, ax1 = plt.subplots()
ax2 = ax1.twinx()
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%m/%d/%Y'))
plt.gca().xaxis.set_major_locator(mdates.DayLocator())
lns1 = ax1.plot(date, people, 'ro')
plt.gcf().autofmt_xdate()

datacursor(ax1, hover=True, formatter='customer: {y:0.0f}'.format)
plt.show()


OUTPUT:
enter image description here

What I am trying to do is, to show popup box when I hover on to the marker. But with my code I get pop up appear wherever I move the cursor.

Also is it possible to display date in that popup?

Answer Source

The issue is that you've attached your datacursor to the axes object rather than the plot itself so it will be triggered whenver you move the mouse anywhere within the axes. If you instead attach it to the plot, it will only trigger when you're over a data point.

datacursor(lns1, hover=True, formatter='customer: {y:0.0f}'.format)

If you want to show the date in the cursor, you can get the major tick formatter from the xaxis and use that as your formatter for your data cursor

# Get the formatter that's being used on the axes
xformatter = plt.gca().xaxis.get_major_formatter()

# Apply it to your data cursor
datacursor(lns1, hover=True, formatter= lambda **kwargs: xformatter(kwargs.get('x')))

If you want to specify a different format than that used on the x axis, you can use a DateFormatter object with a custom format string.

from matplotlib.dates import DateFormatter

fmt = DateFormatter('%Y-%m-%d')
datacursor(lns1, hover=True, formatter= lambda **kwargs: fmt(kwargs.get('x')))

Update

If you want the customer label and the date you can do

fmt = DateFormatter('%Y-%m-%d')
datacursor(lns1, hover=True, formatter= lambda **kwargs: 'customer: {y:.0f}'.format(**kwargs) + 'date: ' + fmt(kwargs.get('x')))

As a side-note, datacursor is not built-in like you mentioned. It's part of mpldatacursor.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download