Closed newville closed 1 year ago
@newville I have reviewed this pull request and I am fully in flavor of it.
My only suggestion is to handle the case when one want to plot more data in the same plot. In #411 I was proposing to have a controller object handling the data loaded in a Larch session, independently of Wx, but I think for now we could simply give a list of groups to the plot functions. In your example this would be:
plot_mu([cu], show_pre=True, show_post=True)
Furthermore, I would suggest building on top of a base XY plot function, let's say
def plot_xy(data: list, xattr : str = None, yattr: str = None):
"""base XY array(s) plot
data: list of Group
"""
...
For plot_mu
I would add the possibility to specify if raw/norm/flat.
This said, I like the idea of having the same plots of xas_viewer
as simple Plotly-based functions.
@maurov Thanks! I don't disagree with the suggestions. I was mostly just trying to get one working, and then see how to best expand and abstract that.
In the wx code, there is a "get_display()" function that handles the "state / controller" part, and then the plotting commands can use new=True/False
to clear or overplot current traces. So, one would do
plot_mu(group1, norm=True, new=True) plot_mu(group2, norm=True, new=False) # with new=False being the default plot_mu(group2, normt=True)
or maybe write a wrapper that effectively does: [plot_mu(g, norm=True, new=(i==0)) for i,g in enumerate([g1, g2, g3, g4]))
I might suggest considering such an approach.
But one thing I found is that plotly handles some things differently. For example, you have to use a different creator function if you want to use both left and right y
axes. And currently, I don't know of a way to adjust colors, linestyles, etc after the plot is done. It would be nice to at least have a way to select theming.
I expect we'll run into some more of those kinds of "every plotting library is just kind of different" differences too.
@newville personally I would not go too deep in making a full wrapper on top of Plotly.
The user of Jupyter is a Python user, so we do not need to reproduce the domain specific language commands used for Larch console or in the Wx GUI. For a more pythonic approach, I recommend let all the plot functions return the fig
object. This way one can do further fine tuning of the figure, if wanted.
I think it would be much easier (and fast) to code functions that plot a list of groups and let the user or a "controller"-like object to select the groups to plot instead of repeating calls to a plot* function with the new
parameter.
@maurov I think that getting basic plotly plotting functions is a good idea, but having them be more "work like a plain function seems more consistent with existing code and easier to me.
I generally view a function taking a list of objects and then acting on all of them as sort of a fragile design. If we can provide "plot an XAFS Group as type xxx.", then a user can figure out how to run that for a list of XAFS Groups. Like, why support "list of Groups" but not "dict of Groups", "set of Groups", or "Group of Groups"?
I think I don't quite get what a "controller" would do from Python or Jupyter. I think of Controller as the code that does the real work with the data Model and updates to Viewer in a GUI. What would a Controller do in a Jupyter session? Would the user have to create a controller object and then route all data processing calls through that instance of a Controller?
@maurov I think that getting basic plotly plotting functions is a good idea, but having them be more "work like a plain function seems more consistent with existing code and easier to me.
@newville thank you very much indeed for the latest changes. I like the tiny wrapper layer of PlotlyFigure
and I am in favor of the specific plotting functions. Those are very good examples for building others specific plots in Jupyter.
I generally view a function taking a list of objects and then acting on all of them as sort of a fragile design. If we can provide "plot an XAFS Group as type xxx.", then a user can figure out how to run that for a list of XAFS Groups. Like, why support "list of Groups" but not "dict of Groups", "set of Groups", or "Group of Groups"?
OK, fine with that.
I think I don't quite get what a "controller" would do from Python or Jupyter. I think of Controller as the code that does the real work with the data Model and updates to Viewer in a GUI. What would a Controller do in a Jupyter session? Would the user have to create a controller object and then route all data processing calls through that instance of a Controller?
I think I am misusing the world "Controller" as it is in the MCV paradigm. I see it as an object with utility methods that could help the user handling the selection of data loaded in during a Larch session. I keep #411 in mind and provide and example whenever I get some time to work on this.
This is a request for comments, and to continue the discussion in #411.
This PR adds
larch/plot/plotly_xafsplots.py
. Ideally, this will eventually have plotting routines that more or less match those inlarch/wxlib/xafsplots.py
. Currently, onlyplot_mu()
is implemented, with an example notebook inexamples/Jupyter
. I think it would not be hard to do the remaining plotting routines, just some time.Any thoughts or suggestions are welcome. Basically, I think we want to have simple and decent XAFS plots for Jupyter -- is this use of
plotly
good enough?