Issue
I'm writing a GUI package on Python with Tkinter module and using matplotlib via FigureCanvasTkAgg to show some graphical data. I also want to interact with this visual representation of the data via canvas.mpl_connect method. Everything works just fine, but I do not satisfied with default arrow-like cursor: it does not allow precise clicking on my data (the actual "click point" does not match with the tip of the arrow) and also it hides from user some area near the click pint. So the question is how to change the default cursor? I tried change it through Tk config methods (like master.config(cursor="tcross")), but apparently matplotlib canvas has its own cursor configuration because this string only changes appearance of the cursor above all parts of main window except MPL canvas, above canvas the default arrow is still being shown.
Solution
First off, a couple of caveats: I'm about to dive into some implementation details. I think the toolbar was recently refactored, so some of this could change with the next version of matplotlib. Furthermore, this values I've specified for the cursor only apply to the TkAgg
backend. The general concept is similar for other backends, but the location of cursord
and the backend-specific cursors will vary. As an example for Qt4Agg
, the cursord
dict is in backend_qt4
instead of backend_qt4agg
, and the values are Qt cursors: e.g. QtCore.Qt.ArrowCursor
.
As I mentioned in my comment, have a look at matplotlib's Cursor
widget. However, the broader issue of how to customize the cursor(s) matplotlib uses is a bit hairier.
The reason that you can't directly change the cursor matplotlib uses (e.g. master.config(cursor='whatever')
) is that the default toolbar overrides it (different cursors for different tools on the toolbar).
One option is to not add the toolbar. In that case, you can just call parent.config(cursor='tcross')
and be done with it. However, you presumably want the toolbar to be present for easier panning/zooming/etc.
The toolbar uses a dict of present cursors for each tool: backend_tkagg.cursord
. The keys for this are int
codes, so it's a bit more readable to refer to them through matplotlib.backend_bases.cursors
. The default tool is the cursors.POINTER
.
As a quick example (For simplicity, I'm using the pyplot
interface to build the canvas, figure, etc.)
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
from matplotlib.backend_bases import cursors
import matplotlib.backends.backend_tkagg as tkagg
# Change the default cursor to any valid TK cursor
# To hide it, you'd use the string "none" (or possibly "no" on windows)
tkagg.cursord[cursors.POINTER] = 'coffee_mug'
fig, ax = plt.subplots()
plt.show()
Note that you can also control the cursor for any tool (e.g. zoom, pan, etc) in the same way. Your options are cursor.HAND
, cursor.POINTER
, cursor.SELECT_REGION
, and cursor.MOVE
.
Answered By - Joe Kington
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.