Is there a way to refresh a matplotlib cursor on click?

Question:

I’m plotting around 250k points with matplotlib so naturally when I’m moving my mouse to use/refresh a cursor widget, it lags a lot. Therefore, I was looking for one way to optimize the use of this widget and I thought of refreshing the cursor on click to reduce the number of freezes.
I saw this extract from the matplotlib documentation and other examples of click events, however I didn’t manage to find more information about specifically linking the cursor refresh to the mouse click event.

Is it even possible?

Screenshot of the graph and the cursor:
graph & cursor screenshot

Code used to plot the graph and add the cursor:

import matplotlib.pyplot as plt
from matplotlib.widgets import Cursor

fig, ax = plt.subplots(figsize=(20, 8), num="Original Signal")
thismanager = plt.get_current_fig_manager()
thismanager.window.wm_iconbitmap("icon.ico")
thismanager = plt.get_current_fig_manager().window.state('zoomed')
plt.plot(Time, Ampl)
plt.xlabel("Time")
plt.ylabel("Amplitude")
plt.tight_layout()
plt.savefig(filepath[:-4] + "_OriginalSignal.jpeg")
cursor = Cursor(ax, color='r', horizOn=True, vertOn=True)
print('Original Signal file created: "', filepath[:-4], '_OriginalSignal.jpeg".', sep="")
Asked By: Guillaume G

||

Answers:

You can use the Threading library. It will that allow a part of your program, in this case your plotting, to be run on a separate thread. I do this with my Tkinter GUIs were I plot data (around 2k point).

Are you doing real time plotting? If yes, it is not a good idea for that amount of points.

To be fair, with that amount of data it might be a bit too much.

++

Edit:

Ok, as I don’t have the data and the parameters of the cursor try this:

from threading import Thread  

def newcursor():
    # Here place the code of your cursor 
    cursor = Cursor(ax, color='r', horizOn=True, vertOn=True)
    
# Before the print  
t=Thread(target=newcursor)
t.start()

Answered By: Harith 75

If I understand your problem correctly, you wish to not draw the cursor as the mouse moves, but only when (and wherever) you do the left-click. Now your questions are:

Is it even possible?

Yes, using the active property of matplotlib.widgets.Widget base class. You will have to first make the cursor inactive and then activate it inside the on_click handler. You may also need to call fig.canvas.draw() once.

I didn’t manage to find more information about specifically linking the cursor refresh to the mouse click event

This is a two-step process.

  1. Make cursor inactive on mouse movement:
    def on_move(event):
        if cursor.active:
            cursor.active = False
  1. Make cursor active on mouse click:
    def on_click(event):
        cursor.active = True
        cursor.canvas.draw():
  1. Don’t forget to link those events:
    plt.connect("motion_notify_event", on_move)
    plt.connect("button_press_event", on_click)
Answered By: vyi
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.