1

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="")
Guillaume G
  • 313
  • 1
  • 2
  • 15
  • What is this **cursor widget**? Is it a MPL element? Ideally, you could store a reference to your widget element and call its `refresh` function. – vyi Dec 19 '22 at 13:34
  • @vyi According to the [documentation](https://matplotlib.org/stable/api/widgets_api.html#matplotlib.widgets.Cursor), `Cursor` is called like this: `matplotlib.widgets.Cursor` and takes multiple arguments but none of them affect it's refresh. [Click events](https://matplotlib.org/stable/gallery/event_handling/coords_demo.html) are a possible solution that I found while looking online, but I didn't manage to set it up for the `Cursor`. – Guillaume G Dec 19 '22 at 13:45

2 Answers2

1

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)
Guillaume G
  • 313
  • 1
  • 2
  • 15
vyi
  • 1,078
  • 1
  • 19
  • 46
0

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()

Guillaume G
  • 313
  • 1
  • 2
  • 15
Harith 75
  • 19
  • 5