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

add jupyter-sidecar as a dependency, update simple notebook #300

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 14 commits into from
Sep 24, 2023

Conversation

clewis7
Copy link
Member

@clewis7 clewis7 commented Sep 7, 2023

closes #299

Only updated simple.ipynb because the other ones are pretty short

@clewis7 clewis7 requested a review from kushalkolar September 7, 2023 20:42
@kushalkolar
Copy link
Member

kushalkolar commented Sep 7, 2023

idea: what if automate the sidecar part with a kwarg to show(), such as:

plot.show(sidecar=True)  # default is True

# if there should be some kwargs passed to sidecar, such as the title for it etc. 
plot.show(sidecar=True, sidecar_kwargs={...})

In ImageWidget this would have to be implemented such that the sliders are shown in the sidecar, basically the full VBox get sidecar'd

@kushalkolar
Copy link
Member

What happens when you run the tests? Does sidecar interfere with creating the screenshots?

@clewis7
Copy link
Member Author

clewis7 commented Sep 7, 2023

tests passing locally for me, just needed to add sidecar dependency to "tests" in setup.py

@clewis7
Copy link
Member Author

clewis7 commented Sep 7, 2023

idea: what if automate the sidecar part with a kwarg to show(), such as:

plot.show(sidecar=True)  # default is True

# if there should be some kwargs passed to sidecar, such as the title for it etc. 
plot.show(sidecar=True, sidecar_kwargs={...})

In ImageWidget this would have to be implemented such that the sliders are shown in the sidecar, basically the full VBox get sidecar'd

I think this would be cool bc it alleviates having to have:

sc = Sidecar()
with sc:
    display(plot.show())

also would be nice to have plot.close() also close the sidecar if there is one

Maybe each plot instance would have a self.sidecar attribute that is initially None and if sidecar=True in plot.show() it gets initialized?

@kushalkolar
Copy link
Member

You will need to figure out how sidecar works with mulitple with sc: display(plot.show()) calls, and then we will need to determine what type of behavior we want.

Thoughts to get you started:

  • Do repeated with sc: display(plot.show()) calls create new sidecars? Or does it do nothing?
  • If the user closes the sidecar but not the plot, what do repeated with sc: display(plot.show()) calls do?
    • I think that if closing the sidecar allows us to re-display it, we can have the following type of behavior:
      • plot.close() closes the plot and sidecar.
      • if the user closes the sidecar by pressing the "x", the plot can be re-displayed in the sidecar using plot.show(). So users must explicitly close plots using plot.close(), closing the sidecar keeps them in GPU RAM.

@clewis7 clewis7 self-assigned this Sep 11, 2023
@clewis7
Copy link
Member Author

clewis7 commented Sep 11, 2023

Interesting find today, multiple calls of

with sc:
    display(plot.show())

across different running notebooks will open the different plots in the same sidecar with different tabs

@clewis7
Copy link
Member Author

clewis7 commented Sep 11, 2023

image

Subsequent calls to

with sc:
    display(plot.show())

opens the plot a second time in the same tab of the existing sidecar side by side

@clewis7
Copy link
Member Author

clewis7 commented Sep 11, 2023

closing the sidecar does NOT close the plot, can then be re-rendered either in another sidecar or in a cell

@clewis7
Copy link
Member Author

clewis7 commented Sep 11, 2023

if you close the sidecar with "x", then the sidecar instance has been closed and subsequent calls to

with sc:
     display(plot.show()))

does nothing

@clewis7
Copy link
Member Author

clewis7 commented Sep 11, 2023

With all of the above comments in mind:

I think it is most relevant to have:

plot.show(sidecar=True, sidecar_kwargs={...})

and should function as follows:

  • default for all plots is for it to be displayed in sidecar, sidecar=True
  • plot.close() will close the sidecar and plot instance
  • clicking the "x" will close the sidecar but keep the plot in memory and redisplaying the plot via plot.show() will open sidecar with plot again

@clewis7
Copy link
Member Author

clewis7 commented Sep 11, 2023

@kushalkolar added sidecar for plot to start, two issues:

  1. if you close a sidecar with "x", calling plot.show() again will do nothing
  2. I think that this breaks the notebook tests that you have in place, see error message below
Cell In[17], line 2
      1 # testing cell, ignore
----> 2 plot_test("astronaut", plot)

File ~/repos/fastplotlib/examples/notebooks/nb_test_utils.py:32, in plot_test(name, plot)
     29         regenerate_screenshot(name, snapshot.data)
     31 try:
---> 32     assert_screenshot_equal(name, snapshot.data)
     33 except AssertionError:
     34     FAILURES.append(name)

File ~/repos/fastplotlib/examples/notebooks/nb_test_utils.py:44, in assert_screenshot_equal(name, data)
     41 def assert_screenshot_equal(name, data):
     42     ground_truth = iio.imread(SCREENSHOTS_DIR.joinpath(f"nb-{name}.png"))
---> 44     is_similar = np.allclose(data, ground_truth)
     46     update_diffs(name, is_similar, data, ground_truth)
     48     assert is_similar, (
     49         f"notebook snapshot for {name} has changed"
     50     )
...
File ~/venvs/mescore/lib/python3.11/site-packages/numpy/core/numeric.py:2356, in isclose.<locals>.within_tol(x, y, atol, rtol)
   2354 def within_tol(x, y, atol, rtol):
   2355     with errstate(invalid='ignore'):
-> 2356         return less_equal(abs(x-y), atol + rtol * abs(y))

ValueError: operands could not be broadcast together with shapes (269,449,4) (300,500,4) 

must have something to do with canvas size vs the snapshot, perhaps snapshots just need to be regenerated?

@clewis7
Copy link
Member Author

clewis7 commented Sep 11, 2023

nonetheless, sidecar is functional for a single plot as so:

# create a `Plot` instance
plot = Plot()

# get a grayscale image
data = iio.imread("imageio:camera.png")

# plot the image data
image_graphic = plot.add_image(data=data, name="sample-image")

# show the plot
plot.show(sidecar_kwargs={"title": "sample image", "layout": {'width': '800px'}})

image

wanted to get your thoughts before implementing in gridplot and imagewidget

examples/notebooks/simple.ipynb Outdated Show resolved Hide resolved
examples/notebooks/simple.ipynb Outdated Show resolved Hide resolved
fastplotlib/layouts/_plot.py Outdated Show resolved Hide resolved
fastplotlib/layouts/_plot.py Outdated Show resolved Hide resolved
fastplotlib/layouts/_plot.py Outdated Show resolved Hide resolved
fastplotlib/layouts/_plot.py Outdated Show resolved Hide resolved
@kushalkolar
Copy link
Member

With all of the above comments in mind:

I think it is most relevant to have:

plot.show(sidecar=True, sidecar_kwargs={...})

and should function as follows:

  • default for all plots is for it to be displayed in sidecar, sidecar=True
  • plot.close() will close the sidecar and plot instance
  • clicking the "x" will close the sidecar but keep the plot in memory and redisplaying the plot via plot.show() will open sidecar with plot again

This sounds good to me!

Is the 3rd point functional in the current implementation?

@clewis7
Copy link
Member Author

clewis7 commented Sep 12, 2023

This sounds good to me!

Is the 3rd point functional in the current implementation?

works with current implementation, see comments in code...used a cheat code for now not sure if it is best implementation but I couldn't figure out in juypter sidecar how to get access to the close button in order to add a observe method on click

also updated the simple notebook with your changes

@clewis7
Copy link
Member Author

clewis7 commented Sep 12, 2023

still getting error that I mentioned above ab mismatched sizes between canvas and screenshot, even though I regenerated them and ran the tests locally and they passed...but they fail in those cells you have in the notebook

@clewis7
Copy link
Member Author

clewis7 commented Sep 13, 2023

current implementation for Plot and GridPlot assumes that you will not display a plot in sidecar without the toolbar...

@kushalkolar I think this makes sense? To me, you would only want to not have the toolbar if you are not rendering in Jupyter. I could not imagine wanting to use sidecar and not have the toolbar...thoughts? Can update the logic, but not sure it is necessary.

Other: Should we implement Sidecar for ImageWidget? Primary concern is there is currently no close() method for ImageWidget so closing the underlying GridPlot keeps the sliders which would prevent closing Sidecar properly. Could implement close() method and then ImageWidget could function more like Plot and GridPlot do with Sidecar...

fastplotlib/layouts/_gridplot.py Outdated Show resolved Hide resolved
fastplotlib/layouts/_gridplot.py Show resolved Hide resolved
fastplotlib/layouts/_plot.py Outdated Show resolved Hide resolved
fastplotlib/layouts/_plot.py Outdated Show resolved Hide resolved
@kushalkolar
Copy link
Member

current implementation for Plot and GridPlot assumes that you will not display a plot in sidecar without the toolbar...

@kushalkolar I think this makes sense? To me, you would only want to not have the toolbar if you are not rendering in Jupyter. I could not imagine wanting to use sidecar and not have the toolbar...thoughts? Can update the logic, but not sure it is necessary.

Yes this makes sense, I think that if someone wants sidecar but no toolbar that's such a bizarre cornercase. If they don't want toolbars in jupyter in general that's a weird cornercase and they're probably trying to make their own thing, in which case they can customize it themselves

Other: Should we implement Sidecar for ImageWidget? Primary concern is there is currently no close() method for ImageWidget so closing the underlying GridPlot keeps the sliders which would prevent closing Sidecar properly. Could implement close() method and then ImageWidget could function more like Plot and GridPlot do with Sidecar...

Yes sounds good :D

@clewis7 clewis7 marked this pull request as ready for review September 15, 2023 07:57
examples/notebooks/linear_region_selector.ipynb Outdated Show resolved Hide resolved
examples/notebooks/linear_selector.ipynb Outdated Show resolved Hide resolved
# validate vbox if not None
if vbox is not None:
for widget in vbox:
if not isinstance(widget, Widget):
Copy link
Member

Choose a reason for hiding this comment

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

I don't think we can use Widget or any ipywidget imports directly within show() because if ipywidgets is not installed in the environment (if they are using fastplotlib with only glfw or Qt), this will raise a error.

Copy link
Member

Choose a reason for hiding this comment

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

I would just put it in the VBox and let VBox deal with it if it's not the right type.

if not sidecar:
return VBox([self.canvas, self.toolbar.widget])
if self.vbox is not None:
return VBox([self.canvas, self.toolbar.widget, self.vbox])
Copy link
Member

Choose a reason for hiding this comment

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

from the previous comment, I just realized that we can't use VBox in show() because it'll raise an error if using in an environment without ipywidgets. Perhaps we need to split show() into show_desktop() and show_notebook()?

Or have two subclasses of PlotFrame, one for notebook and one for desktop, I think this will be the cleaner solution.

@kushalkolar
Copy link
Member

So this has an issue where it will not work on desktop, but we need to fix that with #310 since this PR has already gotten long.

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 jupyterlab-sidecar a nb dependency?
2 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.