Home > Enterprise >  Changing type of annotation in mplcursors on matplotlib
Changing type of annotation in mplcursors on matplotlib

Time:01-07

The current format

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.ticker import ScalarFormatter
import mplcursors as mpl

class Compound():
    def accumulation(i,t):
        return (1 i)**t
    def discount(i,t):
        return (1-i)**(-t)
    
years= np.linspace(1,1000,12000)

%matplotlib widget

fig, ax = plt.subplots()
ax.yaxis.set_major_formatter(ScalarFormatter(useMathText=True))

plt.plot(years,0.93*Compound.accumulation(0.0225,years))
plt.title('Interest')

mpl.cursor(hover=True).annotation_kwargs

I'm using a Jupiter notebook and I want to change the scientific format in the annotation that mplcursors creates when the cursor hovers above the lines

CodePudding user response:

The mplcursors package uses the matplotlib Axes.format_coord to set the style of the formatters in the annotation box. So, you can define your own format_coord function and use that instead (see, e.g., here).

For example,

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.ticker import ScalarFormatter
import mplcursors as mpl


class Compound():
    def accumulation(i, t):
        return (1   i)**t
    def discount(i, t):
        return (1 - i)**(-t)
    
years = np.linspace(1, 1000, 12000)


def format_coord(x, y):
    # output numbers (not in scientific notation) with one decimal place
    return f"x={x:.1f}, y={y:.1f}"


fig, ax = plt.subplots()
ax.yaxis.set_major_formatter(ScalarFormatter(useMathText=True))

ax.plot(years, 0.93 * Compound.accumulation(0.0225, years))
ax.set_title("Interest")

# switch axes format_coord function to your own 
ax.format_coord = format_coord

mpl.cursor(hover=True)

plt.show()

Unfortunately, this doesn't seem to work with LaTeX/MathText style strings enclosed in $ signs, e.g., using:

def format_coord(x, y):
    yscale = int(np.log10(y))
    
    # return LaTeX style scientific notation
    return rf"x={x:1.1f}, y=${y / 10**yscale:1.1f} \times 10^{yscale}$"

keeps the dollars and does not render it as an equation. Doing that may required a more in-depth hack.

  • Related