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

Add examples + explanations #244

Merged
merged 2 commits into from
Sep 16, 2020
Merged

Add examples + explanations #244

merged 2 commits into from
Sep 16, 2020

Conversation

ianhi
Copy link
Collaborator

@ianhi ianhi commented Jul 11, 2020

  • Explain usage of ioff
    • add an example without it
    • and an example with it
  • Add an example slicing an image stack
    • discuss using set_data
    • advise to use draw_idle
    • Usage of widgets.Output to capture errors in callbacks

I'm gonna link this to #208 and maybe @thomasaarholt is interested in this?

@ianhi
Copy link
Collaborator Author

ianhi commented Jul 11, 2020

I also removed the header_visible.ipynb file as that example also exists in ipympl.ipynb and gives workarounds for errors that no longer occur.

@thomasaarholt
Copy link
Contributor

First off, thanks for doing this! The following is a discussion I've been meaning to have for a while, I just haven't had time.

So, I think that using plt.ioff() / plt.ion() is fine for quick scripts and similar - you may have gotten the idea from myself in a previous post here. After some discussion over in the Hyperspy community, I became aware that using plt.ioff may be a bit overkill to just hide the figure.

Afaik, the ideal way is to capture the figure creation inside an Output widget (thus preventing the figure from being shown immediately), and then either use that Output widget, or the fig.canvas handle, in order to place the figure inside the desired layout.

Here's a modified version of the cell, with the method I describe above:

o = widgets.Output()
with o:
    fig = plt.figure()

ax = fig.gca()
ax.imshow(Z)

layout1 = widgets.AppLayout(
    center=fig.canvas,
    footer=widgets.Button(icon='check'),
    pane_heights=[0, 6, 1]
)

display(layout1)

layout2 = widgets.AppLayout(
    center=o,
    footer=widgets.Button(icon='check'),
    pane_heights=[0, 6, 1]
)
display(layout2)

What do you all think? Notice that I included the display calls. I think it would be good to include an explanation on using display in the notebook, since at the moment the only reason the layout widgets are being displayed is that they are the final bit of code in the cell. The notebook implicitly calls display on anything that is returned as the final line.

@ianhi
Copy link
Collaborator Author

ianhi commented Jul 12, 2020

After some discussion over in the Hyperspy community, I became aware that using plt.ioff may be a bit overkill to just hide the figure.

Can you link those posts? I'm curious to read them.

My sense is the plt.ioff wouldn't be overkill as it does very little. As far as I can tell it sets a boolean to False. So that when draw_if_interactive (https://github.com/matplotlib/matplotlib/blob/27072084bd392f2b98158639eca42c6941bb85e6/lib/matplotlib/pyplot.py#L687) is called by plt.figure the if statement in there will evaluate to false. Though I guess the installation and installation of the (un)install_repl_displayhook (ref) is unnecessary?

A good way of looking at this may be that there is the matplotlib approach to solving this problem (ioff) and the jupyter approach (Output). In that case I think it makes sense to include both approaches in the examples with a discussion of the pros and cons. For example one pro of ioff is that it generalizes to outside the notebook, so if I have a class that will sometimes be used in the notebook and sometimes not then the Output approach wouldn't make sense there.

Notice that I included the display calls. I think it would be good to include an explanation on using display

👍 I think this is not well known. I wonder if its worth having an example of a custom class that basically presents a matplotlib plot with some controls that defines _ipython_display_.

@ianhi
Copy link
Collaborator Author

ianhi commented Jul 16, 2020

I think it would be nice to include the explanation of why it is necessary to use the Output widget from #233 (comment)

@martinRenou
Copy link
Member

@ianhi is this PR ready?

@ianhi
Copy link
Collaborator Author

ianhi commented Sep 11, 2020

@martinRenou not quite. I'd like to include more on the distinction between using an output widget and using plt.ioff. I also advise using draw_idle which I've since learned is not yet implemented for ipympl so maybe I should remove that? I can fix those up this weekend and then check back on monday?

Also: Post release of matplotlib 3.4 we should also update these to include the usage of plt.ioff as a context manager, this is in master but not yet released

- show setting image data + add explanation of `ioff` and `Output`
- update github link
- mention display(fig) for a static embed
- remove stale example and add comment to main example
@ianhi
Copy link
Collaborator Author

ianhi commented Sep 12, 2020

I added an explanation of using widgets.Output to capture the plot to prevent double output and I tweaked the code of the examples in a few places now that I know more (e.g. observe(.., names = 'value') instead of checking in the update function)

@martinRenou this is ready now

@ianhi
Copy link
Collaborator Author

ianhi commented Sep 12, 2020

Does it make sense to mention mpl-interactions in the section on how to connect plots to sliders? The entire reason I made that library was to make those sorts of examples easier.

@ianhi
Copy link
Collaborator Author

ianhi commented Sep 12, 2020

Actually as a broader point maybe it makes sense for this library to have a 3rd party packages section? Looking at https://github.com/matplotlib/ipympl/network/dependents?dependent_type=PACKAGE there are at least 20 packages that depend on/build on ipympl

@ianhi
Copy link
Collaborator Author

ianhi commented Sep 15, 2020

@martinRenou before I forget about this again: does this need any changes? I think we could consider and maybe implement a third party packages area in a separate issue/PR.

@martinRenou
Copy link
Member

No it's totally fine, sorry I missed the

@martinRenou this is ready now

Merging then :) thank you!

@martinRenou martinRenou merged commit 3372f9b into matplotlib:master Sep 16, 2020
@ianhi ianhi deleted the examples branch September 16, 2020 14:37
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.

3 participants