-
Notifications
You must be signed in to change notification settings - Fork 54
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
[MRG] NetworkPlot class to enable interactive visualizations and animations #649
Conversation
@jasmainak @rythorpe perhaps it'd be a good idea to make this a separate file? If we can find a solution to updating the section colors very rapidly, we can even consider adding a "play" button inside the GUI (or on the HNN website!) like the example here: https://matplotlib.org/stable/gallery/animation/unchained.html @chenghuzi you might have some good insight on how to make the current code more "reactive" |
examples/howto/plot_hnn_animation.py
Outdated
@@ -0,0 +1,37 @@ | |||
""" | |||
================================ | |||
XX. Modifying local connectivity |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to be fixed :)
examples/howto/plot_hnn_animation.py
Outdated
elev_slider = IntSlider(min=-100, max=100, value=10, continuous_update=False) | ||
azim_slider = IntSlider(min=-100, max=100, value=-100, continuous_update=False) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't ipympl
a dependency of hnn-gui
? Do you still need this?
Codecov ReportAttention: Patch coverage is
❗ Your organization needs to install the Codecov GitHub app to enable full functionality. Additional details and impacted files@@ Coverage Diff @@
## master #649 +/- ##
==========================================
- Coverage 92.33% 91.51% -0.82%
==========================================
Files 27 25 -2
Lines 5059 4819 -240
==========================================
- Hits 4671 4410 -261
- Misses 388 409 +21 ☔ View full report in Codecov by Sentry. |
Agnostic about saving to a different file ... see my comment about the azimuth/elevation control. Maybe it makes the class thinner? |
hnn_core/viz.py
Outdated
@@ -1185,3 +1198,234 @@ def plot_laminar_csd(times, data, contact_labels, ax=None, colorbar=True, | |||
plt_show(show) | |||
|
|||
return ax.get_figure() | |||
|
|||
|
|||
class NetworkPlot: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
class NetworkPlot: | |
class NetworkDataPlotter: |
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NetworkPlotter
? It might useful too for just visualizing the 3D morphology without any data too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah if data is None
hnn_core/viz.py
Outdated
self.init_network_plot() | ||
self._update_axes() | ||
|
||
def get_voltages(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wondering if this should be in Network
class ... then you can pass data
to the NetworkDataPlotter
class. You can plot not just voltages but other quantities
Dropping this here for easy testing once we get closer to merging. I think rendering movies is going to be a longish wait for larger networks, but not absurdly so (maybe like 5-10 minutes? if you downsample?) import hnn_core
import os.path as op
from hnn_core import jones_2009_model, simulate_dipole, read_params
from hnn_core.network_models import add_erp_drives_to_jones_model
from hnn_core.viz import NetworkPlot
hnn_core_root = op.dirname(hnn_core.__file__)
params_fname = op.join(hnn_core_root, 'param', 'default.json')
params = read_params(params_fname)
params.update({'N_pyr_x': 3, 'N_pyr_y': 3})
net = jones_2009_model(params)
net.set_cell_positions(inplane_distance=300)
add_erp_drives_to_jones_model(net)
dpl = simulate_dipole(net, dt=0.5, tstop=170, record_vsec='all')
net_plot = NetworkPlot(net)
net_plot.export_movie('demo.gif', dpi=200) |
hnn_core/viz.py
Outdated
|
||
self.ax.view_init(self._elev, self._azim) | ||
|
||
def export_movie(self, fname, dpi=300): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jasmainak here's the export function!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are some solutions here that might speed up the exporting by circumventing the matplotlib animation module:
https://stackoverflow.com/questions/4092927/generating-movie-from-python-without-saving-individual-frames-to-files
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to add a progressbar using a callback? I don't think the speed is a showstopper here. Maybe a param called "decim" could be added to take every nth frame. Make it work, make it nice, make it fast ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely would be a nice addition but I think I'd need to be much more matplotlib savvy to know how to implement that 😄
Great work! Although, I'm concerned about the reactivity of our GUI. We are taking snapshots from the buffer and using |
525c749
to
3c0bccc
Compare
examples/howto/plot_hnn_animation.py
Outdated
############################################################################### | ||
from hnn_core import jones_2009_model, simulate_dipole | ||
from hnn_core.network_models import add_erp_drives_to_jones_model | ||
from hnn_core.viz import NetworkPlot |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
from hnn_core.viz import NetworkPlot | |
from hnn_core.viz import NetworkPlotter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm guessing the name of this class got changed somewhere along the way and you forgot to update it here?
examples/howto/plot_hnn_animation.py
Outdated
net_plot.azim = azim | ||
return net_plot.fig | ||
|
||
time_slider = IntSlider(min=0, max=len(net_plot.times), value=1, continuous_update=False) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For some reason the interactive slider didn't work for me. It might be a version issue and totally unrelated to your code here. Have you encountered a similar issue at any point @ntolley?
@rythorpe @jasmainak this PR is ready for review! Two weird errors have come up however. First it seems like sphinx-gallery doesn't support python versions older than 3.8 Does this mean our minimum python version needs to be updated? Also the windows unit tests are failing with an error in the GUI code... This is the offending line in case you guys have any ideas on the possible cause: |
Yup just confirmed, sphinx now requires python>=3.8 |
.circleci/config.yml
Outdated
@@ -27,7 +27,7 @@ jobs: | |||
command: | | |||
export PATH=~/miniconda/bin:$PATH | |||
conda update --yes --quiet conda | |||
conda create -n testenv --yes pip python=3.7 | |||
conda create -n testenv --yes pip python=3.8 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think we need to update setup.py
and our unit tests with python>=3.8
as well to ensure all builds are getting tested properly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Honestly if this only impacts the documentation building I don't think it's necessary
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that's true but you won't realize if other dependencies start requiring 3.8 now that you have updated it here. I don't think we have a CI that tests for python < 3.8? Better to be consistent and update readme/setup etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went ahead and updated this in #677. We'll see if it fixes the Windows test_viz.py
error....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
excellent!!
Ugh, I'm guessing the most recent version of matplotlib has diverged for windows vs. linux. Something to do with the |
Co-authored-by: Mainak Jas <jasmainak@users.noreply.github.com>
Aside from @jasmainak's spelling error and my incredibly nitpicky punctuation suggestion above, this looks great @ntolley ! |
Co-authored-by: Ryan Thorpe <ryvthorpe@gmail.com>
I've enabled auto-merge! Thanks @ntolley for this incredible feature - I'm very excited to put it to good use 😄 |
Here's my first pass at creating a viz class that can be used to quickly render the full 3D network, as well as membrane potentials of individual sections. This is meant to be largely generic and flexible so that it can be co-opted for other purposes. I think the most interesting applications at the moment would be:
The current strategy for the class is to do all of the heavy lifting at the initialization (namely creating the 3D object, and mapping the voltage recordings to the appropriate colors). For a quick demo, the code below can be run on my laptop on a single core in approximately 20 sec:
If you want to play around with visualizing the voltages, you can try the following code block: