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

Fixing plt.show() in plot_network for network_animation #405

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

mi-les
Copy link

@mi-les mi-les commented Feb 6, 2024

Summary

Solves issue #389 which describes problems using wntr.graphics.network.network_animation in Jupyter Notebooks by adding a show_plot parameter to the wntr.graphics.network.plot_network function.

show_plot is set to 'True' by default on wntr.graphics.network.plot_network, but changed to False within wntr.graphics.network.network_animation. This makes network_animation work as intended.

Tests and documentation

None; docstring for the show_plot parameter of the wntr.graphics.network.plot_network function added

Acknowledgement

By contributing to this software project, I acknowledge that I have reviewed the software quality assurance guidelines and that my contributions are submitted under the Revised BSD License.

@kaklise
Copy link
Collaborator

kaklise commented Mar 11, 2024

Thanks for submitting this PR! We'll test this out in Jupyter notebooks and other IDEs and get back to you.

@kbonney
Copy link
Collaborator

kbonney commented Mar 12, 2024

@mi-les, what platform are you using for running notebooks? I use VSCode, which is notoriously bad at showing plots in notebooks, and I still only see the first frame when I try to run an example using your code. I think this is an issue with VSCode rather than your code, so I would like to check it on a whatever platform you used.

@mi-les
Copy link
Author

mi-les commented Mar 13, 2024

@kbonney I am using VS Code as well, together with the IPython.display module. Sorry about not providing the script earlier:

import wntr
import matplotlib.pyplot as plt
# from wntr.graphics.network import network_animation
from IPython.display import HTML

wn = wntr.network.WaterNetworkModel("examples/networks/Net1.inp")

sim = wntr.sim.EpanetSimulator(wn)
results = sim.run_sim()

demand = results.node["demand"]

anim = wntr.graphics.network_animation(wn, node_attribute=demand.iloc[0:4])
# plt.show()
HTML(anim.to_jshtml())

With the original code, this did not work.

Using plt.show() only shows the first frame in Jupyter Notebooks... Could add the note how to view the animations nicely using IPython.display.HTML in Jupyter Notebooks to the documentation.

@kaklise
Copy link
Collaborator

kaklise commented Apr 12, 2024

This works for me, but as stated above, the first frame is displayed in addition to the network animation and the user would need to add HTML(anim.to_jshtml()) when using a Jupyter notebook. Other interactive plot options in wntr.graphics (plot_interactive_network and plot_leaflet_network) save html files, and the plotly interactive network has an input argument to "auto_open". Could similar behavior be used to here to save and display the animation?

@mi-les
Copy link
Author

mi-les commented Apr 15, 2024

Showing the last slide can be suppressed by:

html = HTML(anim.to_jshtml())
display(html)
plt.close()

I agree that this is a bit inelegant, but I see the problem on the matplotlib/Jupyter side.

The network_animation function could be adjusted to save the html files like the other functions. But in my opinion it is better to return the animation object and let the users interact with it according to their needs. A tip on how to use it in Jupyter notebooks could be provided in the documentation.

@kbonney
Copy link
Collaborator

kbonney commented Apr 15, 2024

The lingering first frame is more of an issue with how Jupyter works by default than how the code is set up. By default, jupyter will always capture the initial plotted figure and display it, in addition to the display of the animation. There are a lot of ideas in this SEO thread, but none of them solve the problem without additional work on the user's end. Even if we directly return the HTML object, jupyter still finds that initial frame and will attempt to plot it in the output.

The cleanest solution I have found is to use the jupyter magic command % matplotlib notebook. The following code snippet just produces the animation figure and nothing else. This would be a straightforward recommendation to the user for using the animation function in a notebook setting.

%matplotlib notebook

import wntr
import matplotlib.pyplot as plt

plt.rcParams["animation.html"] = "jshtml"


wn = wntr.network.WaterNetworkModel("Net1.inp")

sim = wntr.sim.EpanetSimulator(wn)
results = sim.run_sim()

demand = results.node["pressure"]

anim = wntr.graphics.network_animation(wn, node_attribute=demand.iloc[0:4])
display(anim)

@kbonney
Copy link
Collaborator

kbonney commented Apr 15, 2024

Here's a draft of something we could paste into the docstring and/or the network animation section of the graphics page in the documentation:

When using network_animation in a Jupyter notebook, it is recommended to use the % matplotlib notebook magic at the beginning of your notebook and using the IPython.display.display function to display the animation in the cell's output. For example,

%matplotlib notebook
import wntr
from IPython.display import display

anim = wntr.graphics.network_animation(...)
display(anim)

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.

None yet

3 participants