0

I am using Multicursor to get a cursor on every graph. I want to show the value of the datapoint, which is hit by the cursor, inside a legend during hovering over the graphs, like thisenter image description here

Actually I have thought that this is a standard feature of matplotlib respectively Multicursor, but it seems not. Did someone already something like this or do I have to implement it by my own.

I already found this post matplotlib multiple values under cursor, but this could be just the beginning for the implementation I want.

1 Answer 1

1

I have developed a solution.

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.widgets import MultiCursor
from bisect import bisect_left


fig = plt.figure(figsize=(15, 8))

# create random graph with 60 datapoints, 0 till 59
x = list(range(0,60))

axes_list = [] 

def createRandomGraph(ax,x):
    y = np.random.randint(low=0, high=15, size=60)
    data.append(y)
    ax.plot(x,y, marker='.')


def take_closest(myList, myNumber):
    """
    Assumes myList is sorted. Returns closest value to myNumber.

    If two numbers are equally close, return the smallest number.
    """
    pos = bisect_left(myList, myNumber)
    if pos == 0:
        return myList[0]
    if pos == len(myList):
        return myList[-1]
    before = myList[pos - 1]
    after = myList[pos]
    if after - myNumber < myNumber - before:
       return after, pos
    else:
       return before, pos-1



def show_Legend(event): 
    #get mouse coordinates
    mouseXdata = event.xdata    

    # the value of the closest data point to the current mouse position shall be shown
    closestXValue, posClosestXvalue = take_closest(data[0], mouseXdata)

    i = 1
    for ax in axes_list:
        datalegend = ax.text(1.05, 0.5, data[i][posClosestXvalue],  fontsize=7,
                                      verticalalignment='top', bbox=props, transform=ax.transAxes)               
        ax.draw_artist(datalegend) 

        # this remove is required because otherwise after a resizing of the window there is 
        # an artifact of the last label, which lies behind the new one
        datalegend.remove()
        i +=1

    fig.canvas.update()


# store the x value of the graph in the first element of the list
data = [x]

# properties of the legend labels
props = dict(boxstyle='round', edgecolor='black', facecolor='wheat', alpha=1.5)

for i in range(5):
    if(i>0):        
        # all plots share the same x axes, thus during zooming and panning 
        # we will see always the same x section of each graph
        ax = plt.subplot(5, 1, i+1, sharex=ax)             
    else:
        ax = plt.subplot(5, 1, i+1)        

    axes_list.append(ax)    
    createRandomGraph(ax,x)  

multi = MultiCursor(fig.canvas, axes_list, color='r', lw=1)   

# function show_Legend is called while hovering over the graphs 
fig.canvas.mpl_connect('motion_notify_event', show_Legend)

plt.show()

The output looks like this

enter image description here

Maybe you like it and find it useful

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.