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

Tabbed figure viewer #2194

Open
parrenin opened this issue Jul 2, 2013 · 13 comments
Open

Tabbed figure viewer #2194

parrenin opened this issue Jul 2, 2013 · 13 comments

Comments

@parrenin
Copy link

parrenin commented Jul 2, 2013

If in a code you create many figures, it starts to become inconvenient because each figure creates a new window.
It would be very useful to be able to create workbook of figures organized in tabs.

@petehuang
Copy link
Contributor

@efiring
Copy link
Member

efiring commented Jan 7, 2017

Also related to #7338 in that both involve GUI backend work. In my view, #7338 is addressing a more urgent problem--not just convenience, but making the displayed and saved plot match what one has specified.

@tacaswell tacaswell modified the milestones: 2.1 (next point release), 2.2 (next next feature release) Oct 3, 2017
@astromancer
Copy link
Contributor

If you use one of the qt backends, you can try use: mpl-multitab

@jklymak
Copy link
Member

jklymak commented Jun 10, 2022

@astromancer would you consider adding that to mpl-third-party? Also, maybe could you comment here on how reasonable this was as a 3rd party library versus whether we should be working on including something like this as a tool for the main library? Our GUI work takes a significant maintenance toll if we try to keep parity between backends.

@astromancer
Copy link
Contributor

would you consider adding that to mpl-third-party?

@jklymak Happy to do add it. Do i need to open a PR to do that?

Also, maybe could you comment here on how reasonable this was as a 3rd party library

With the current implementation, this doesn't really serve as an alternative for the pyplot ui in any way. It just takes the canvas from an existing figure and puts it into a tab widget post facto. If the user creates a new figure, that is handled by pyplot in the normal way, and one has to then explicitly add this figure to the tab widget. This work as a proof of concept and was fairly easy to implement (in pyqt/pyside at least), but has some drawbacks and inefficiencies. More work will need to be done to get better interoperability with pyplot, for example getting new figures to appear automatically as new tabs etc. I have zero experience with any of the other backend toolkits, so can't say how difficult it would be to implement tabbed figure managers for those.

@oscargus
Copy link
Contributor

Yes, please create a PR here: https://github.com/matplotlib/mpl-third-party

@tacaswell
Copy link
Member

If the user creates a new figure, that is handled by pyplot in the normal way, and one has to then explicitly add this figure to the tab widget

The slightly weird thing about this is that in add_tab you call plt.close(fig) which (from the point of view of pyplot) orphans the figure and then you then re-embed in your tabs.

More work will need to be done to get better interoperability with pyplot, for example getting new figures to appear automatically as new tabs etc.

I'm not fully convinced that is worth doing. pyplot is really doing two things:

  1. keeping track of implicitly creating UI objects (the QObjects) so that they do not get gc'd + showing them when needed
  2. supporting the implicit plt.plot(...) interface and keeping track of a "current Figure" (and the figure has a "current axes").

While there are decent use-cases for 2, I think that once you get to a multi-tabbed figure like that they start to fall apart (and the implicit state management has gone from an asset that saves you from some boiler plate to a liability where there is now some critical state held some where else in the code that is near impossible to trace) and given the way you have done the API here, the user already has an explicit object (the ui) so we do not need to track that for the user.

I have some further opinions, but I'll express them in terms of a PR to mpl-multitab.

@tacaswell
Copy link
Member

@goobleplax
Copy link

I'm surprised that people have been asking for basic tab support over ten years at this point, yet MatPlotLib maintainers for some reason refuse to offer it at all?

The same issue appears across multiple third-party programs (plotWindow by @superjax and mpl-multitab by @tacaswell), which seems to point to an underlying issue with MatPlotLib and/or implementation of MultiCursor, as mentioned here:

#23328 (comment)

The problem is that the MultiCursor functionality of MatPlotLib does not work properly with tabs. Either a vertical cursor only displays on the last tab, rather than on all tabs.

If there were a generic MatPlotLib interface for dealing with tabs, this would enable all third-party programs to use that interface without needing to create individual workarounds for basic missing functionality such as tab support.

Tabbed interfaces are a universal user-interface design pattern now, so it's strange that the functionality would be completely absent in such a widely used, visual library such as MatPlotLib. The only explanation I've read so far is that... "MatPlotLib is foremost a library". And tabbed interfaces are foremost a universal means of accessing data visualized by libraries like MatPlotLib, so I would hope for the sake of everyone over the past ten years, someone can finally make MatPlotLib compatible with tabs.

The alternative is to force each third-party developer to hack their own version of tabs that has the exact problem described here: everyone has to repeatedly invent different solutions for the same problem. Solving the problem once within MatPlotLib (similar to what has already been done with MultiCursor, only for tab support) would enable everyone to build upon the existing foundation instead of reinventing solutions for design issues that are universally useful to anyone who uses MatPlotLib for anything beyond the most basic purposes.

@jklymak
Copy link
Member

jklymak commented Jun 23, 2022

The only explanation I've read so far is that... "MatPlotLib is foremost a library".

The full explanation is in #23328 (comment) and that tabbed interfaces are complex, and we do not have a large app development team to robustly propagate such an interface across all our operating systems and backends and then maintain it in perpetuity for the users who have grown used to using it.

@goobleplax
Copy link

we do not have a large app development team to robustly propagate such an interface across all our operating systems and backends and then maintain it in perpetuity for the users who have grown used to using it.

That is a strange overgeneralization about "all operating systems and backend... in perpetuity", when, for example, the two options discussed in this conversation (mpl-multitab and plotWindow) both use PyQt.

Supporting one Python binding of one GUI toolkit isn't exactly beyond imagination. The practical benefits of the maintainers offering one or two choices that are well-known, popular, and well-tested, far outweigh the amount of energy required to maintain the "in perpetuity", or at least for however long matplotlib exists.

@tacaswell
Copy link
Member

There are a couple of issues here that I want to address:

First, I want to remind everyone remain professional and avoid personal attacks. All of the maintainers are working on Matplotlib in good faith, please trust us when we say something is either hard our out of scope.

Second, Jody is correct. We are committed to providing parity across the all of the GUI toolkits we support and we are committed to once we put a feature is released to keeping it working for our users going forward. If we support tabs in a first class way for one toolkit (Qt) we should support it for all (tk, wx, gtk, osx).

Third, both the API and UI on tabs are surprisingly complex (for example mpl-multitab is actually 2 mostly independent bits of code one for the 1D tabs, one for the 2D tabs). We provide a basic UI embedding (one figure to one main window) and then the underlying widgets so that application developers and embed Matplotlib in their UI however they want. I can see a couple of paths to get there in a lowest-common-denominator way, but not a good way to toggle the behavior on and off. If you have ideas on how to do this we would be happy to review a PR @goobleplax .

Forth, if we support tabs "natively" or not is unrelated to MultiCursor working between Figures (each tab is its own Figure) because that code assumes all of the Axes are in the same figure (and on the same canvas).

@anntzer
Copy link
Contributor

anntzer commented Jun 5, 2023

As a side point, MultiCursor can be used across multiple figures since #23348.

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

No branches or pull requests

9 participants