Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Plot frame #313

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

Merged
merged 22 commits into from
Oct 31, 2023
Merged

Plot frame #313

merged 22 commits into from
Oct 31, 2023

Conversation

kushalkolar
Copy link
Member

@kushalkolar kushalkolar commented Oct 3, 2023

closes #310 closes #342 closes #268

This PR adds a Frame class that manages how plots are shown. Plot and Gridplot, and any future flexilbe gridplot, inherit from Frame.

How this works:

Toolbars

Refactored ipywidget Toolbar that is common between Plot, Gridplot and any future gridplots

Output Contexts

These are classes that "hold" the output of a Plot/Gridplot. They determine how the canvas, toolbar, and any additional widgets are shown. When Plot.show() is called, they return an instance of one of the following output contexts based on the curent plot canvas.

  • JupyterOutputContext
    • Inherits from ipywidgets.VBox and contains the canvas, toolbar, and any other widgets. Manages sidecar if desired.
  • QOutputContext
    • Inherits from QWidget, contains the canvas, qt toolbar, and any other widgets.
  • If the canvas is not jupyter or qt (ex. if it's glfw or offscreen like in our test suite), the output context is just the plot canvas itself.

This cleans up the messy show() calls we previously had everywhere, and cleans up other stuff too. Now the output context manages closing plots too.

BTW, the QOutputContext can also be used in notebooks with if you execute %gui qt before creating plots 😄

@clewis7
Copy link
Member

clewis7 commented Oct 3, 2023

#310

@kushalkolar kushalkolar marked this pull request as ready for review October 29, 2023 20:48
@kushalkolar
Copy link
Member Author

This is working now with JupyterOutputContext! Also fixed the wonky issue with auto-scale and center scene when you had a single controller controlling multiple cameras for diff subplots.

Now onto Qt output context and toolbar.

@kushalkolar
Copy link
Member Author

Everything works on my end, I tested every combination with ipywidgets, sidecar/no sidecar, Qt, and with ImageWidget.

Right now the toolbar implementations are quite repetitive, we can make that nicer in a future PR after we have some time to think about it. Someone must have made a common interface between ipywidgets and Qt that we can use.

qt.mp4

fastplotlib/layouts/_frame/_frame.py Outdated Show resolved Hide resolved
fastplotlib/layouts/_frame/_frame.py Show resolved Hide resolved
fastplotlib/layouts/_frame/_ipywidget_toolbar.py Outdated Show resolved Hide resolved
fastplotlib/layouts/_frame/_ipywidget_toolbar.py Outdated Show resolved Hide resolved
self.output = (frame.canvas, *add_widgets)

if make_toolbar: # make toolbar and stack canvas, toolbar, add_widgets
self.toolbar = IpywidgetToolBar(frame)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if ImageWidget? where is logic for if plot type is imagewidget?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ImageWidget just uses the Gridplot context:

    def show(self, toolbar: bool = True, sidecar: bool = False, sidecar_kwargs: dict = None):
        """
        Show the widget

        Returns
        -------
        OutputContext
        """
        if self.gridplot.canvas.__class__.__name__ == "JupyterWgpuCanvas":
            self._image_widget_toolbar = IpywidgetImageWidgetToolbar(self)

        elif self.gridplot.canvas.__class__.__name__ == "QWgpuCanvas":
            self._image_widget_toolbar = QToolbarImageWidget(self)

        return self.gridplot.show(
            toolbar=toolbar,
            sidecar=sidecar,
            sidecar_kwargs=sidecar_kwargs,
            add_widgets=[self._image_widget_toolbar]
        )

@clewis7
Copy link
Member

clewis7 commented Oct 30, 2023

did you update the requirements file?

@clewis7
Copy link
Member

clewis7 commented Oct 30, 2023

Another thing I see is that when I have two subplots in an imagewidget and the camera y_scales are opposite that when I change click between subplots the flip button is not changing in accordance with the camera y_scale...just stays the same

@kushalkolar
Copy link
Member Author

did you update the requirements file?

No dependency changes here.

@kushalkolar
Copy link
Member Author

Another thing I see is that when I have two subplots in an imagewidget and the camera y_scales are opposite that when I change click between subplots the flip button is not changing in accordance with the camera y_scale...just stays the same

In ipywidgets or Qt?

@clewis7
Copy link
Member

clewis7 commented Oct 30, 2023

Another thing I see is that when I have two subplots in an imagewidget and the camera y_scales are opposite that when I change click between subplots the flip button is not changing in accordance with the camera y_scale...just stays the same

In ipywidgets or Qt?

ipwidgets

@clewis7
Copy link
Member

clewis7 commented Oct 30, 2023

did you update the requirements file?

No dependency changes here.

not even if someone only wants qt? they would need to have pyqt6 installed right?

@kushalkolar
Copy link
Member Author

did you update the requirements file?

No dependency changes here.

not even if someone only wants qt? they would need to have pyqt6 installed right?

Qt land is a bit complicated, so they will have to install Qt themselves separately. We can do toggles later, because to do this properly we need to give users the option of PySide etc and decide how broad we want this support.

@kushalkolar
Copy link
Member Author

Another thing I see is that when I have two subplots in an imagewidget and the camera y_scales are opposite that when I change click between subplots the flip button is not changing in accordance with the camera y_scale...just stays the same

In ipywidgets or Qt?

ipwidgets

I think now I see what you mean, it is wonky! So this is because in ImageWidget all cameras are under one controller. I did not decide how to deal with flipping when controllers are diff. What I will do is if the flip button is clicked, it will flip the camera for the current subplot but also any camera that has the same controller (similar to what I did for panzoom and maintain_aspect).

@kushalkolar kushalkolar merged commit 932454f into main Oct 31, 2023
@kushalkolar kushalkolar mentioned this pull request Oct 31, 2023
@kushalkolar kushalkolar deleted the plot-frame branch October 31, 2023 04:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

make sidecar=False the default? make a PlotFrame class for Toolbar and sidecar functionality Setting the coordinate reference system
2 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.