Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NavigationToolbar2Tk behave unexpected when using it in with Tkinter Canvas #17584

Closed
andreys42 opened this issue Jun 6, 2020 · 12 comments · Fixed by #19400
Closed

NavigationToolbar2Tk behave unexpected when using it in with Tkinter Canvas #17584

andreys42 opened this issue Jun 6, 2020 · 12 comments · Fixed by #19400

Comments

@andreys42
Copy link

andreys42 commented Jun 6, 2020

Bug report

Bug summary

NavigationToolbar2Tk behave unexpected when using it in with Tkinter Canvas(see attached gif for more details). When scroll a little bit my Canvas then tools like zoom, move (e.t.c) works like canvas area still locate on the previous position.

import tkinter
from tkinter import *

from matplotlib.backends.backend_tkagg import (
    FigureCanvasTkAgg, NavigationToolbar2Tk)
from matplotlib.backend_bases import key_press_handler
from matplotlib.figure import Figure

import numpy as np

root = tkinter.Tk()
root.wm_title("Embedding in Tk")

fig = Figure(figsize=(5, 40), dpi=100)
t = np.arange(0, 3, .01)
fig.add_subplot(111).plot(t, 2 * np.sin(2 * np.pi * t))

canvas = FigureCanvasTkAgg(fig, master=root)  # A tk.DrawingArea.
canvas.draw()

scroll_y = Scrollbar(canvas.get_tk_widget(),orient="vertical", command=canvas.get_tk_widget().yview)
scroll_y.grid(row=0, column=1, sticky="ns")

canvas.get_tk_widget().configure(yscrollcommand=scroll_y.set, scrollregion=canvas.get_tk_widget().bbox("all"))

toolbar = NavigationToolbar2Tk(canvas, root)
toolbar.update()

canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1)

tkinter.mainloop()

Actual outcome

ezgif com-video-to-gif

``

Expected outcome
NavigationToolbar2Tk update its action area with new Scrollbar status

Matplotlib version
3.1.3

  • Operating system: Windows 10
  • Matplotlib version: 3.1.3
  • Matplotlib backend (print(matplotlib.get_backend())): TkAgg
  • Python version: 3.7
  • Other libraries: Tkinter version 8.6

All packages installed using updated pip

@QuLogic QuLogic added the GUI: tk label Jun 6, 2020
@anntzer
Copy link
Contributor

anntzer commented Jun 6, 2020

Looks like the trick is to use self._tkcanvas.canvasx(event.x) and self._tkcanvas.canvasy(event.y) everywhere instead of event.x and event.y (https://effbot.org/tkinterbook/canvas.htm#Tkinter.Canvas.canvasx-method).

@andreys42
Copy link
Author

@antzer Are you talking about matplotlib embedding code or my little snippet? If last, then I do not really inderstand where actually I used some "event" features in my snippet...

@anntzer
Copy link
Contributor

anntzer commented Jun 6, 2020

I mean that Matplotlib should do so, not you.

@andreys42
Copy link
Author

Strange that no one still met same troubles

@andreys42
Copy link
Author

@anntzer any ideas for hot fix ?

@anntzer
Copy link
Contributor

anntzer commented Jun 6, 2020

As I said the correct patch to Matplotlib is probably along the lines of what I wrote above, but you'll have to check that by yourself.

@timhoffm
Copy link
Member

timhoffm commented Jun 7, 2020

Strange that no one still met same troubles

I'm not surprised that this has not been reported before, as it's a very specific use case:

  • Most people do not embed matplotlib in applications, but either use the popup window or notebooks.
  • Tk is only one of the supported GUI toolkits.
  • You made the canvas scrollable; I assume that most of the time people let the graph scale to the available canvas space.
  • Zooming and scrolling is not strictly uncommon, but only used in a minority of cases.

The bug is only visible if all of the above comes together.

@andreys42
Copy link
Author

@timhoffm Agree. Do this circumstances mean that this "bug" is low-priority for MPL support team?

@andreys42
Copy link
Author

andreys42 commented Jun 7, 2020

  • You made the canvas scrollable; I assume that most of the time people let the graph scale to the available canvas space.

Is there any other options to fit elongated graph (w = 100, h = 1000) in fixed size Tk canvas and to be able scale, move and so on? I mean I think it's really wide-spread task and I thought its solution already implemented in MatPlotLib. ...

@timhoffm
Copy link
Member

timhoffm commented Jun 8, 2020

Do this circumstances mean that this "bug" is low-priority for MPL support team?

We do not formally have "low-priority" as most of the development is done by volunteers. It really depends case-by-case. If somebody picks this up, it might be fixed quickly, if not it might stay open for a long time. That said, Matplotlib is an open source project and pull requests are always welcome.

Is there any other options [...]

I'm not aware of any.

@andreys42
Copy link
Author

andreys42 commented Jun 8, 2020

@timhoffm btw @anntzer 's suggestion about replacement was right. At least it solved my (topic) problem )
Thank you, mr @anntzer :)

@andreys42
Copy link
Author

andreys42 commented Jun 8, 2020

noticed one more strange thing : size of FigureCanvasTkAgg (which is set as "t1, t2, w, h = self.figure.bbox.bounds" ) is not match with allocated by Tkinter area
(If we firstly create Frame, and then fullfill it with FigureCanvasTkAgg object using place(relheight = 1, relwidth = 1) then size of mpl figure canvas can be bigger than it's parent widget - Frame)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants