Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Delay output capturing to a further code block #363

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

Closed
ImportanceOfBeingErnest opened this issue Apr 5, 2018 · 9 comments · Fixed by #801
Closed

Delay output capturing to a further code block #363

ImportanceOfBeingErnest opened this issue Apr 5, 2018 · 9 comments · Fixed by #801

Comments

@ImportanceOfBeingErnest
Copy link

Imagine you have a piece of code that would produce some output. Yet, you do not want to show that output (because it's too long or too distracting). Is that possible?

In a more concrete example, I wish to create a matplotlib plot in several steps, having explanations as text in between the code. However I only want the final plot to show up. As an example:

"""
Header
================

Create a plot by importing matplotlib 
and creating a figure with axes
"""

import matplotlib.pyplot as plt
fig, ax = plt.subplots()

####################
# Now we want to add a plot, we do so using 
# :meth: `plot <matplotlib.pyplot.plot>`
# 

ax.plot( .... )
ax.other_stuff()

####################
# Finally we can show the plot
# 

plt.show()

Of course you would only want to have the complete plot being shown at the time you call show.

In a jupyter notebook you would probably use %%capture in those intermediate cells and last state fig to show the plot. But how do you do it here?

@lesteve
Copy link
Member

lesteve commented Apr 5, 2018

I don't see a way to do that currently in sphinx-gallery. I think this would require some tweaks to how we are currently capturing figures at the end of a code-block. IIRC we are currently closing all the figures at the end of a code block. So unless I am wrong, the basic assumption is that a figure is completely built within a code block.

Maybe slightly related to #161 and #284.

In your particular case, you could argue that figures should be only captured when they are "visible" (not sure what the right technical term is and not sure how easy this is), i.e. plt.show() has been called. Of course the script behaviour differs from the notebook behaviour and historically we have tried to follow the former, they may be more details in the linked issues above.

@lesteve
Copy link
Member

lesteve commented Apr 5, 2018

In your particular case, you could argue that figures should be only captured when they are "visible"

Thinking about this a bit more, I don't think that is a good idea and could potentially break existing examples because plt.show() tend to be called only once at the end of the example.

@ImportanceOfBeingErnest
Copy link
Author

Thanks for commenting. I see that the current behaviour is probably useful in many cases where the educational part that needs heavy explanation is not on the side of the figure creation itself. In those cases you can simply have a code block producing the figure with the accumulated data in a small code block.

In matplotlib, documenting the figure creation itself is the part that needs the heavy text. While a solution to the two linked problems would certainly help here, the problem here could potentially much easier be solved - without the need to mess with closed or open figures or the show function.

I think what would help here is any or all of the following:

  • Currently it seems possible to write code that is not executed, but still formatted as code. We would need the inverse: Code that is executed, but does not show within the document. (This seems similar to ignore code-blocks #361.)
  • Postpone code output. Ideally there would be a flag, call it ...capture, to set at some point in the document that states something like: "Do not produce output for all that is comming next." and a second flag, call it ...release, that would let all the code that has accumulated since the last ...capture be executed and its output be produced in the document.
  • A possibly easier per-document flag that does the above for the whole document and shows the output at the end of it.

@lesteve
Copy link
Member

lesteve commented Apr 5, 2018

Thanks for explaining your pain points in detail! At the moment, you will need to resort to work-arounds to achieve something similar to what you want. Quickly looking at your example, it feels like your main options are:

Amongst your proposals, the capture/release feels like the best candidate. Not sure about the naming (funnily enough I would use nocapture in order not to capture the produced plots) and maybe release is not needed, because implicitly the first code-block that does not contain capture is the equivalent of release.

FYI, at the moment the little work I do in sphinx-gallery is to try to get 0.1.14 out of the door. It is rather unlikely that I will find some time to work on anything else until 0.1.14 is released.

@ImportanceOfBeingErnest
Copy link
Author

Yes I'm going with option 1 (creating 2 figures) now (This is how it looks like). The only drawback in this specific case is then that the automatically generated thumbnail only shows one of the figures (and I don't think we want static images employed in that case).

Having those features implemented in the long run would surely be of help for matplotlib documentation.

Not sure about the naming at all. I guess Juypter captures the output from being shown, while sphinx-gallery may capture the output to be shown. This surely depends on the viewpoint (put a fence around yourself and you have captured the whole world 😁). In any case, once such a feature is implemented, the naming should be the least of a problem.

Good luck with the upcoming release.

@lesteve lesteve changed the title Suppress code output Delay output capturing to a further code block Apr 6, 2018
@lesteve
Copy link
Member

lesteve commented Apr 6, 2018

Glad that you found a work-around!

I am going to rename your issue title to track this feature request. Feel free to edit it in case you can think of a better wording.

@larsoner
Copy link
Contributor

larsoner commented Aug 6, 2018

Perhaps a custom scraper after #313 is in could work for your issue?

@ImportanceOfBeingErnest
Copy link
Author

Not sure. How would you select the custom scraper to be used for a particular example?
I would have imagined something like a flag in the document which says #sphnx-gal-command: $output-here$ to controll at which point in the document all gathered output so far shall be put.

@larsoner
Copy link
Contributor

larsoner commented Aug 8, 2018

You would have to write a custom scraper that looked for this tag and only scraped images when it saw it. Probably less than a dozen lines of code, basically what matplotlib_scraper currently does plus this extra check.

Though it does make me think that perhaps the scraper should also take as input the code block being executed.

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.

3 participants