sisl icon indicating copy to clipboard operation
sisl copied to clipboard

WIP: Facilitate the creation of combined plots

Open pfebrer opened this issue 9 months ago • 9 comments

Since #340, there was the discussion of how to make the API for multiple plots as convenient as possible. This PR attempts to solve it.

In nodify, I introduced the concept of a Batch. If you pass a Batch as an input of a workflow, the workflow will also return a Batch. The most important thing is that only the parts of the workflow that depend on the batch are computed for each item, the rest are shared, saving time and memory.

This is automatically applicable to the plots, since they are workflows:

from nodify import Batch
import sisl

graphene = sisl.geom.graphene()

# Create a batch
scales = Batch(1, 2, 3)
# Then call the plotting function, but passing the batch as an input on several arguments
g_plot = graphene.plot(axes="xy", show_cell=False, atoms_scale=scales, bonds_scale=scales)

g_plot.get() will now return a batch, which contains the three figures.

Now the question is what is the best interface for sisl users. In this PR I have changed slightly the functions that merge plots so that they can support batches. Now one can do for example:

sisl.viz.subplots(g_plot)

newplot (71)

One can also change the way in which batches interact with each other. This is defined by the node's context. In this case they were zipped, but one could ask to take the product as well:

from nodify import temporal_context

with temporal_context(batch_iter="product"):
    sisl.viz.subplots(g_plot).show()

newplot (72)

I have decided that the user must use the merging functions, and g_plot.show() does not show anything, since there is no indication of how the user wants to merge the plots. Also if we were to automatically merge them it would not work in cases like:

# Create a batch
backends = Batch("plotly", "matplotlib")

g_plot =  graphene.plot(axes="xy", backend=backends)

Where the backends are different. In that case one can do:

for plot in g_plot.get():
    plot.show()

Screenshot from 2024-05-25 18-10-12

Do you think this is fine? Is there something that you would change to make it more convenient to use?

Thanks!

pfebrer avatar May 25 '24 16:05 pfebrer