Download IPython notebook here. Binder badge.

Demo notebook

[1]:
# This is just for convenience to retreive files
import sisl
siesta_files = sisl._environ.get_environ_variable("SISL_FILES_TESTS") / "sisl" / "io" / "siesta"

The basics

The first thing you will need to do in order to use plots is to import them from the sisl.viz.plotly module:

[2]:
from sisl.viz.plotly import Plot

Let’s start plotting!

Why can’t I just tell the computer to plot the file?! This is the question milions of students around the world ask themselves when they get introduced to computational physics. Then time passes, and you learn to deal with it. You might even build your own scripts in an attempt to mitigate the pain. But hey:

[3]:
Plot(siesta_files / "SrTiO3.bands")
info:0: SislInfo:

The plot has been initialized correctly, but the current settings were not enough to generate the figure.
Error: Could not read or generate data for BandsPlot from any of the possible sources.
Here are the errors for each source:
        - aiida bands: AttributeError.'NoneType' object has no attribute '_get_bandplot_data'
        - path: ValueError.You need to provide at least 2 points of the path to draw the bands. Please update the 'path' setting. The current path is: []
        - band structure: ValueError.No band structure (k points path) was provided
        - bands file: FileNotFoundError.[Errno 2] No such file or directory: '_THIS_DIRECTORY_DOES_NOT_EXIST_/sisl/io/siesta/SrTiO3.bands'

[4]:
Plot(siesta_files / "SrTiO3.RHO", axes=[0,1], nsc=[2,1,1], zsmooth='best')
info:0: SislInfo:

The plot has been initialized correctly, but the current settings were not enough to generate the figure.
Error: Could not read or generate data for GridPlot from any of the possible sources.
Here are the errors for each source:
        - grid file: SileError.rhoSileSiesta(SrTiO3.RHO, base=/home/docs/checkouts/readthedocs.org/user_builds/sisl/checkouts/v0.11.0/docs/visualization/plotly/basic-tutorials/_THIS_DIRECTORY_DOES_NOT_EXIST_/sisl/io/siesta).read_grid_size could not read grid sizes. (ierr=2)
        - grid: ValueError.grid was not set

See what we did there? We passed some extra arguments (axes and nsc) to get the exact plot that we want.

But how do you know which words to use?

Be patient, we will get there.

Ok, but still, you only have different scripts that plot different things. And you use this fancy Plot() stuff to catch our attention.

Not really. In fact, what Plot() does is to initialize a plot instance. If you store it into a variable you can check for yourself.

[5]:
plot = Plot(siesta_files / "SrTiO3.RHO", axes=[0,1], nsc=[2,1,1], zsmooth="best")
plot.__class__
info:0: SislInfo:

The plot has been initialized correctly, but the current settings were not enough to generate the figure.
Error: Could not read or generate data for GridPlot from any of the possible sources.
Here are the errors for each source:
        - grid file: SileError.rhoSileSiesta(SrTiO3.RHO, base=/home/docs/checkouts/readthedocs.org/user_builds/sisl/checkouts/v0.11.0/docs/visualization/plotly/basic-tutorials/_THIS_DIRECTORY_DOES_NOT_EXIST_/sisl/io/siesta).read_grid_size could not read grid sizes. (ierr=2)
        - grid: ValueError.grid was not set

[5]:
sisl.viz.plotly.plots.grid.GridPlot
[6]:
plot.show("png")
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/tmp/ipykernel_2875/291154134.py in <module>
----> 1 plot.show("png")

~/checkouts/readthedocs.org/user_builds/sisl/checkouts/v0.11.0/sisl/viz/plotly/plot.py in show(self, listen, return_figWidget, *args, **kwargs)
   1187                 warn(e)
   1188
-> 1189         return self.figure.show(*args, **kwargs)
   1190
   1191     def _ipython_display_(self, return_figWidget=False, **kwargs):

~/checkouts/readthedocs.org/user_builds/sisl/conda/v0.11.0/lib/python3.8/site-packages/plotly/basedatatypes.py in show(self, *args, **kwargs)
   3396         import plotly.io as pio
   3397
-> 3398         return pio.show(self, *args, **kwargs)
   3399
   3400     def to_json(self, *args, **kwargs):

~/checkouts/readthedocs.org/user_builds/sisl/conda/v0.11.0/lib/python3.8/site-packages/plotly/io/_renderers.py in show(fig, renderer, validate, **kwargs)
    387
    388     # Mimetype renderers
--> 389     bundle = renderers._build_mime_bundle(fig_dict, renderers_string=renderer, **kwargs)
    390     if bundle:
    391         if not ipython_display:

~/checkouts/readthedocs.org/user_builds/sisl/conda/v0.11.0/lib/python3.8/site-packages/plotly/io/_renderers.py in _build_mime_bundle(self, fig_dict, renderers_string, **kwargs)
    295                         setattr(renderer, k, v)
    296
--> 297                 bundle.update(renderer.to_mimebundle(fig_dict))
    298
    299         return bundle

~/checkouts/readthedocs.org/user_builds/sisl/conda/v0.11.0/lib/python3.8/site-packages/plotly/io/_base_renderers.py in to_mimebundle(self, fig_dict)
    126
    127     def to_mimebundle(self, fig_dict):
--> 128         image_bytes = to_image(
    129             fig_dict,
    130             format=self.format,

~/checkouts/readthedocs.org/user_builds/sisl/conda/v0.11.0/lib/python3.8/site-packages/plotly/io/_kaleido.py in to_image(fig, format, width, height, scale, validate, engine)
    132     # Raise informative error message if Kaleido is not installed
    133     if scope is None:
--> 134         raise ValueError(
    135             """
    136 Image export using the "kaleido" engine requires the kaleido package,

ValueError:
Image export using the "kaleido" engine requires the kaleido package,
which can be installed using pip:
    $ pip install -U kaleido

Note also that it’s not exactly a Plot, but a GridPlot. This means that it will have settings and methods that are specific to this kind of plot. Settings may be found by printing the variable.

You can ``print(plot)`` to see how they look like if you really can’t wait. Here’s a cell for you, we won’t know:

[ ]:

Are you done? Good. Now if you want to make a better use of that cell do help(plot) instead. You will see a list of the mehods that are available to you in this plot. Actually we are more interested in the specific methods that this plot has, so when you reach the line:

Methods inherited from sisl.viz.plotly.Plot:

you can stop reading.

Let’s try one of those!

[7]:
# We already have a plot stored
plot.scan(steps=15)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
/tmp/ipykernel_2875/448345151.py in <module>
      1 # We already have a plot stored
----> 2 plot.scan(steps=15)

~/checkouts/readthedocs.org/user_builds/sisl/checkouts/v0.11.0/sisl/viz/plotly/plots/grid.py in scan(self, along, start, stop, step, num, breakpoints, mode, animation_kwargs, **kwargs)
   1076             breakpoints = np.linspace(*along_range, int(num) + 1)
   1077
-> 1078         if breakpoints[-1] == self.grid.cell[along, along]:
   1079             breakpoints[-1] = self.grid.cell[along, along] - self.grid.dcell[along, along]
   1080

AttributeError: 'NoneType' object has no attribute 'cell'

Ok, now it starts to make sense… but looking at the help message is a bit tedious, don’t you think?

Yes, I agree. The plan is to have an individual notebook to showcase the abilities of each plot, because, you know, we came here to visualize. But we’re not quite there yet, sorry.

Btw… why did an animation come out of nowhere?

Magic doesn’t exist, so of course someone has developed it.

I’m sure it’s complicated as hell to use. This is why you’ve been hiding it from us…

Well, you can judge for yourself.

[8]:
from sisl.viz.plotly import Animation, BandsPlot

bands_file = siesta_files / "SrTiO3.bands"

# There are two main ways to build an animation for yourself

# You can either provide already initialized plots to Animation
plots = [ Plot(bands_file, bands_color=color) for color in ("green", "orange", "red")]

from_animation = Animation(plots=plots)

# Or use the animated class method
from_animated = BandsPlot.animated(
    "bands_color", ("green", "orange", "red"), # Animate the bands_color setting with this values
    fixed = {"bands_file": bands_file}, # Keep this settings fixed for all frames
)

# Show them both
from_animation.show()
from_animated.show()
info:0: SislInfo:

The plot has been initialized correctly, but the current settings were not enough to generate the figure.
Error: Could not read or generate data for BandsPlot from any of the possible sources.
Here are the errors for each source:
        - aiida bands: AttributeError.'NoneType' object has no attribute '_get_bandplot_data'
        - path: ValueError.You need to provide at least 2 points of the path to draw the bands. Please update the 'path' setting. The current path is: []
        - band structure: ValueError.No band structure (k points path) was provided
        - bands file: FileNotFoundError.[Errno 2] No such file or directory: '_THIS_DIRECTORY_DOES_NOT_EXIST_/sisl/io/siesta/SrTiO3.bands'

info:0: SislInfo:

The plot has been initialized correctly, but the current settings were not enough to generate the figure.
Error: Could not read or generate data for BandsPlot from any of the possible sources.
Here are the errors for each source:
        - aiida bands: AttributeError.'NoneType' object has no attribute '_get_bandplot_data'
        - path: ValueError.You need to provide at least 2 points of the path to draw the bands. Please update the 'path' setting. The current path is: []
        - band structure: ValueError.No band structure (k points path) was provided
        - bands file: FileNotFoundError.[Errno 2] No such file or directory: '_THIS_DIRECTORY_DOES_NOT_EXIST_/sisl/io/siesta/SrTiO3.bands'

info:0: SislInfo:

The plot has been initialized correctly, but the current settings were not enough to generate the figure.
Error: Could not read or generate data for BandsPlot from any of the possible sources.
Here are the errors for each source:
        - aiida bands: AttributeError.'NoneType' object has no attribute '_get_bandplot_data'
        - path: ValueError.You need to provide at least 2 points of the path to draw the bands. Please update the 'path' setting. The current path is: []
        - band structure: ValueError.No band structure (k points path) was provided
        - bands file: FileNotFoundError.[Errno 2] No such file or directory: '_THIS_DIRECTORY_DOES_NOT_EXIST_/sisl/io/siesta/SrTiO3.bands'

info:0: SislInfo:

The plot has been initialized correctly, but the current settings were not enough to generate the figure.
Error: Could not read or generate data for BandsPlot from any of the possible sources.
Here are the errors for each source:
        - aiida bands: AttributeError.'NoneType' object has no attribute '_get_bandplot_data'
        - path: ValueError.You need to provide at least 2 points of the path to draw the bands. Please update the 'path' setting. The current path is: []
        - band structure: ValueError.No band structure (k points path) was provided
        - bands file: FileNotFoundError.[Errno 2] No such file or directory: '_THIS_DIRECTORY_DOES_NOT_EXIST_/sisl/io/siesta/SrTiO3.bands'

So, you basically get the same animation in both cases. But is it really the same?

[9]:
# Let's save them
from_animation.save("From_animation.plot")
from_animated.save("From_animated.plot")
[9]:
True

If you go to the directory where this tutorials are and you run the command ll -h you will see the following (moreless): - From_animated.plot weights 679 KB - From_animation.plot weights 855 KB

I’ll give you a moment to solve the mistery…

That’s right! Animation has detected that some data can be shared between plots and it is doing so.

But how?!

Again, settings. It’s always about settings.

But you must know that this is a crucial feature for plots with larger data, like the charge density scan we saw previously. In that case, your computer might not even be able to sustain such HUGE quantities of data. Therefore, there is a template_plot keyword that you can provide to both animated and Animation to explicitly set the plot that will share data.

By the way, here’s a cell for you to check that I’m not lying, try checking the shared attribute of the plot that came from the animated method.

[ ]:

Ok, I see. Can you tell us how to load the plots that you saved there?

Sure:

[10]:
from sisl.viz.plotly import load
#load("I know you have an intuition of what to put here")

Thanks, but what’s the point of saving them anyway?

Well, you can: - Open them later and they will already contain all the data. - Share it with other people easily.

However, if you just want to share the plot and not the data, you have beter and more lightweight options: - Save it as a picture (you probably already saw the picture icon that appears when you hover the plot at the top-right corner) - Save it as html using the .html() method: Great for keeping functionality and vital for animations. - Take the figure attribute and save it however you want.

This last point brings me to a breakpoint in our relation. I have to make a confession: I haven’t developed the figures themselves, these areplotlyfigures.

Aha! I knew there was something you were hiding.

Yes, indeed. I was hiding that, since Plot is an extension of plotly Figure, all plotly methods are available to you to postprocess the plot that you obtained as you wish:

[11]:
# Let's build a plot
plot = Plot(siesta_files / "SrTiO3.RHO", axes=[0,1], nsc=[2,1,1], zsmooth="best", title="The importance of the green line")

# And now let's draw a line a line indicating something super important
# using the plotly add_scatter method on our figure
plot.add_scatter(x=[0,4], y=[1,3],line_width=5, line_color="lightgreen", showlegend=False)
info:0: SislInfo:

The plot has been initialized correctly, but the current settings were not enough to generate the figure.
Error: Could not read or generate data for GridPlot from any of the possible sources.
Here are the errors for each source:
        - grid file: SileError.rhoSileSiesta(SrTiO3.RHO, base=/home/docs/checkouts/readthedocs.org/user_builds/sisl/checkouts/v0.11.0/docs/visualization/plotly/basic-tutorials/_THIS_DIRECTORY_DOES_NOT_EXIST_/sisl/io/siesta).read_grid_size could not read grid sizes. (ierr=2)
        - grid: ValueError.grid was not set

Now you got a taste of the basic things that you should expect from sisl’s visualization module. We hope that you liked what you saw :)

If you are willing to know more, please keep on reading the notebook. We appreciate your interest and we are definitely willing to show more. And we honestly think you won’t regret it.

Let’s talk about settings

Finally!

Life is unpredictable.

And that’s why needing to define all the parameters of your plot on initialization seems like too much to ask. That’s why, we’ve separated the work of our plots into three main processes:

  • Reading the data.

  • Processing the data.

  • Displaying the figure.

At this point, you probably already see that there is clearly at least one step that you don’t want to be doing all the time: Reading your 300MB file.

I get it, I can run different steps to update my plot as I need. But how would I know, if it was not me that developed the plot? Do I have to look into the code of each plot?!

No, that’s the point of settings. Plots have settings (as you have previously discovered, I know what you did in that cell…). And plots know which settings are run in each step of the process. So, when you update a setting, don’t worry, they will know what to do.

And how do I “update a setting”?

[12]:
# Get the bands plot
plot = Plot(siesta_files / "SrTiO3.bands")

# If you don't know what are the settings that you can change, print the plot
# print(plot)

# But I already know, so I will update them using the update_settings method
plot.update_settings(Erange=[-5,5], gap=True)
info:0: SislInfo:

The plot has been initialized correctly, but the current settings were not enough to generate the figure.
Error: Could not read or generate data for BandsPlot from any of the possible sources.
Here are the errors for each source:
        - aiida bands: AttributeError.'NoneType' object has no attribute '_get_bandplot_data'
        - path: ValueError.You need to provide at least 2 points of the path to draw the bands. Please update the 'path' setting. The current path is: []
        - band structure: ValueError.No band structure (k points path) was provided
        - bands file: FileNotFoundError.[Errno 2] No such file or directory: '_THIS_DIRECTORY_DOES_NOT_EXIST_/sisl/io/siesta/SrTiO3.bands'

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
/tmp/ipykernel_2875/3778781439.py in <module>
      6
      7 # But I already know, so I will update them using the update_settings method
----> 8 plot.update_settings(Erange=[-5,5], gap=True)

~/checkouts/readthedocs.org/user_builds/sisl/checkouts/v0.11.0/sisl/viz/plotly/configurable.py in update_settings(self, *args, **kwargs)
    419             # the available kwargs for the plot class and provide more help to the user
    420             def update_settings(self, *args, **kwargs):
--> 421                 return self._update_settings(*args, **kwargs)
    422
    423             update_settings.__doc__ = f"Updates the settings of this plot.\n\nDocs for {new_cls.__name__}:\n\n{get_configurable_docstring(new_cls)}"

~/checkouts/readthedocs.org/user_builds/sisl/checkouts/v0.11.0/sisl/viz/plotly/configurable.py in _update_settings(self, run_updates, **kwargs)
    554             #Do things after updating the settings
    555             if len(self.settings_history.last_updated) > 0 and run_updates:
--> 556                 self._run_updates(self.settings_history.last_updated)
    557
    558         return self

~/checkouts/readthedocs.org/user_builds/sisl/checkouts/v0.11.0/sisl/viz/plotly/configurable.py in _run_updates(self, for_keys)
    582         # Execute the functions that we need to execute.
    583         for f_name in func_names:
--> 584             getattr(self, f_name)()
    585
    586         return self

~/checkouts/readthedocs.org/user_builds/sisl/checkouts/v0.11.0/sisl/viz/plotly/plotutils.py in apply_to_all_plots(obj, childs_sel, *args, **kwargs)
    817         else:
    818
--> 819             return method(obj, *args, **kwargs)
    820
    821     return apply_to_all_plots

~/checkouts/readthedocs.org/user_builds/sisl/checkouts/v0.11.0/sisl/viz/plotly/configurable.py in func(obj, *args, **kwargs)
    881             def func(obj, *args, **kwargs):
    882                 getattr(obj, method_name)(**kwargs, **extra_kwargs)
--> 883                 return method(obj, *args, **kwargs)
    884
    885         elif when == 'after':

~/checkouts/readthedocs.org/user_builds/sisl/checkouts/v0.11.0/sisl/viz/plotly/plot.py in set_data(self, update_fig, **kwargs)
   1126         self._starting_traces = len(self.data)
   1127
-> 1128         self._set_data()
   1129
   1130         if update_fig:

~/checkouts/readthedocs.org/user_builds/sisl/checkouts/v0.11.0/sisl/viz/plotly/configurable.py in f_default_setting_args(self, *args, **kwargs)
    962                     pass
    963
--> 964         return f(self, *args, **kwargs)
    965
    966     return f_default_setting_args

~/checkouts/readthedocs.org/user_builds/sisl/checkouts/v0.11.0/sisl/viz/plotly/plots/bands.py in _set_data(self, Erange, E0, bands_range, spin, bands_width, bands_color, spindown_color, add_band_trace_data, draw_before_bands)
    565
    566         # Shift all the bands to the reference
--> 567         filtered_bands = self.bands - E0
    568
    569         # Get the bands that matter for the plot

~/checkouts/readthedocs.org/user_builds/sisl/checkouts/v0.11.0/sisl/viz/plotly/plot.py in __getattr__(self, key)
    734                 pass
    735
--> 736         raise AttributeError(f"The attribute '{key}' was not found either in the plot, its figure, or in shared attributes.")
    737
    738     def __setattr__(self, key, val):

AttributeError: The attribute 'bands' was not found either in the plot, its figure, or in shared attributes.

And what if I messed up the plot with the new settings?

[13]:
plot.undo_settings()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
/tmp/ipykernel_2875/2508219687.py in <module>
----> 1 plot.undo_settings()

~/checkouts/readthedocs.org/user_builds/sisl/checkouts/v0.11.0/sisl/viz/plotly/configurable.py in undo_settings(self, steps, run_updates)
    618             self.settings_history.undo(steps=steps)
    619             if run_updates:
--> 620                 self._run_updates(diff)
    621         except IndexError:
    622             info(f"This instance of {self.__class__.__name__} does not "

~/checkouts/readthedocs.org/user_builds/sisl/checkouts/v0.11.0/sisl/viz/plotly/configurable.py in _run_updates(self, for_keys)
    582         # Execute the functions that we need to execute.
    583         for f_name in func_names:
--> 584             getattr(self, f_name)()
    585
    586         return self

~/checkouts/readthedocs.org/user_builds/sisl/checkouts/v0.11.0/sisl/viz/plotly/plotutils.py in apply_to_all_plots(obj, childs_sel, *args, **kwargs)
    817         else:
    818
--> 819             return method(obj, *args, **kwargs)
    820
    821     return apply_to_all_plots

~/checkouts/readthedocs.org/user_builds/sisl/checkouts/v0.11.0/sisl/viz/plotly/configurable.py in func(obj, *args, **kwargs)
    881             def func(obj, *args, **kwargs):
    882                 getattr(obj, method_name)(**kwargs, **extra_kwargs)
--> 883                 return method(obj, *args, **kwargs)
    884
    885         elif when == 'after':

~/checkouts/readthedocs.org/user_builds/sisl/checkouts/v0.11.0/sisl/viz/plotly/plot.py in set_data(self, update_fig, **kwargs)
   1126         self._starting_traces = len(self.data)
   1127
-> 1128         self._set_data()
   1129
   1130         if update_fig:

~/checkouts/readthedocs.org/user_builds/sisl/checkouts/v0.11.0/sisl/viz/plotly/configurable.py in f_default_setting_args(self, *args, **kwargs)
    962                     pass
    963
--> 964         return f(self, *args, **kwargs)
    965
    966     return f_default_setting_args

~/checkouts/readthedocs.org/user_builds/sisl/checkouts/v0.11.0/sisl/viz/plotly/plots/bands.py in _set_data(self, Erange, E0, bands_range, spin, bands_width, bands_color, spindown_color, add_band_trace_data, draw_before_bands)
    565
    566         # Shift all the bands to the reference
--> 567         filtered_bands = self.bands - E0
    568
    569         # Get the bands that matter for the plot

~/checkouts/readthedocs.org/user_builds/sisl/checkouts/v0.11.0/sisl/viz/plotly/plot.py in __getattr__(self, key)
    734                 pass
    735
--> 736         raise AttributeError(f"The attribute '{key}' was not found either in the plot, its figure, or in shared attributes.")
    737
    738     def __setattr__(self, key, val):

AttributeError: The attribute 'bands' was not found either in the plot, its figure, or in shared attributes.

The undo_settings() method even has a nsteps keyword that will allow you to go way back. No one will ever know about your “little experiments”.

Monitoring changes

Plots can keep track of the files that they read.

Using this, you can check if there are updates available for a given plot very easily.

[14]:
plot = Plot(siesta_files / "SrTiO3.bands")
plot.updates_available()
info:0: SislInfo:

The plot has been initialized correctly, but the current settings were not enough to generate the figure.
Error: Could not read or generate data for BandsPlot from any of the possible sources.
Here are the errors for each source:
        - aiida bands: AttributeError.'NoneType' object has no attribute '_get_bandplot_data'
        - path: ValueError.You need to provide at least 2 points of the path to draw the bands. Please update the 'path' setting. The current path is: []
        - band structure: ValueError.No band structure (k points path) was provided
        - bands file: FileNotFoundError.[Errno 2] No such file or directory: '_THIS_DIRECTORY_DOES_NOT_EXIST_/sisl/io/siesta/SrTiO3.bands'

[14]:
False

Of course there are no available updates, you just read the file…

Yeah, thanks.

Do I have to be checking for updates until there is one? That’s pointless.

Well, you can, sure, if you want. But of course there is a method already there for you.

Let’s build a different plot that makes sense tracking.

[15]:
from sisl.viz.plotly import ForcesPlot
forces = ForcesPlot(out_file="../files/water/water.out")
info:0: SislInfo:

The plot has been initialized correctly, but the current settings were not enough to generate the figure.
Error: Could not read or generate data for ForcesPlot from any of the possible sources.
Here are the errors for each source:
        - siesta_output: FileNotFoundError.[Errno 2] No such file or directory: '../files/water/water.out'

Oops! Seems that these plots are not that great after all.

We are trying to make a plot out of a file that doesn’t even exist. So, the error is fair enough.

Although it does not yet exist, Lets make the plot listen for updates:

[16]:
forces.listen()

Wow, impressive. Seems like it didn’t do much…

Well, that’s the point of the listen method. It runs asyncronously. This means that it does not block the execution of other code. It basically means that, while this plot is listening for updates, you can continue doing things on the notebook.

But enough talk, let’s see it working. Go to the files/water folder and execute siesta so that it sends the output to a file called water.out:

siesta < water.fdf > water.out

Let’s see what happens…

Did you see how the plot was changing? The plot does not know when to stop listening. Who knows, maybe an update will come sometime. Let’s take a moment to stop it.

[17]:
forces.stop_listening()

You probably saw that the updating process didn’t look great. That is because we need to clear the output and plot the figure again each time.

So classy…

Well, the plot is only doing that because it does not find the appropiate jupyter notebook widgets. Check which widgets are you missing:

[18]:
forces._widgets
[18]:
{'plotly_avail': False,
 'plotly_error': False,
 'events_avail': False,
 'events_error': False,
 'plotly': False,
 'events': False}

If you have plotly available but it indicates an error, it is probably because, although you are in your environment’s kernel, you are running jupyter notebook from a different environment.

Just run the notebook from your environment, or uncomment this cell and run it (don’t remove the !) to install plotly also in the environment that you are running the notebook.

[19]:
#!pip3 install plotly

Then close and open the jupyter server again with jupyter notebook or however you do it (restarting the kernel is not enough).

Regarding events, it is a widget that will provide you with the ability to use keyboard shortcuts on the plots. It can be very handy, but if you don’t want it, that’s fine.

If you want to have it:

[20]:
#!pip3 install ipyevents
#!jupyter nbextension enable --py --user ipyevents

Or with conda:

[21]:
#!conda install -c conda-forge ipyevents

If you installed event, let’s take a moment to see if it works.

Close the server and open it again with jupyter notebook or however you like to do it (restarting the kernel is probably not enough).

[22]:
plot = Plot(siesta_files / "SrTiO3.RHO")
plot.show()
info:0: SislInfo:

The plot has been initialized correctly, but the current settings were not enough to generate the figure.
Error: Could not read or generate data for GridPlot from any of the possible sources.
Here are the errors for each source:
        - grid file: SileError.rhoSileSiesta(SrTiO3.RHO, base=/home/docs/checkouts/readthedocs.org/user_builds/sisl/checkouts/v0.11.0/docs/visualization/plotly/basic-tutorials/_THIS_DIRECTORY_DOES_NOT_EXIST_/sisl/io/siesta).read_grid_size could not read grid sizes. (ierr=2)
        - grid: ValueError.grid was not set

Try to play with it and see if it works.

Place your mouse on top of the plot and press any key. You should see it logged in the left-down corner.

Then press shift+? to see all the available shortcuts for this plot. Try to use them. If you’ve gotten here, there should be no problem now :)

Fun part is that you don’t need to stick to the shortcuts that are provided by default, you can build your own so that it fits perfectly your requirements. More on this in upcoming tutorials. But feel free to add a little pressure so that we do it faster, we will appreciate your enthusiasm for sure.