Search code examples
pythonmatplotlibannotationscursormplcursors

Labels for multiple data sets on the same graph using mplcursors


I have two sets of data that I'm graphing on the same plot using matplotlib. I'm using mplcursors to annotate each point using a label array. Unfortunately mplcursors uses the first five labels for both data sets. My question is how do I get the second data set to have it's own custom labels?

I realize for this simple example I could merge the data, but I can't for the project I'm working on.

import matplotlib.pyplot as plt
import mplcursors
import numpy as np

x = np.array([0, 1, 2, 3, 4])
y = np.array([1, 2, 3, 4, 5])
y2 = np.array([2, 3, 4, 5, 6])

fig, ax = plt.subplots()
ax.plot(x, y, "ro")
ax.plot(x, y2, 'bx')

labels = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]

mplcursors.cursor(ax, hover=True).connect(
    "add", lambda sel: sel.annotation.set_text(labels[sel.target.index]))
plt.show()

Solution

  • My comment about using a dictionary would look like this:

    import matplotlib.pyplot as plt
    import mplcursors
    import numpy as np
    
    x = np.array([0, 1, 2, 3, 4])
    y = np.array([1, 2, 3, 4, 5])
    y2 = np.array([2, 3, 4, 5, 6])
    
    fig, ax = plt.subplots()
    line1, = ax.plot(x, y, "ro")
    line2, = ax.plot(x, y2, 'bx')
    
    labels1 = ["a", "b", "c", "d", "e"]
    labels2 = ["f", "g", "h", "i", "j"]
    
    d = dict(zip([line1, line2], [labels1, labels2]))
    
    mplcursors.cursor(ax, hover=True).connect(
        "add", lambda sel: sel.annotation.set_text(d[sel.artist][sel.target.index]))
    
    plt.show()