-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
WIP: adding themes #924
WIP: adding themes #924
Conversation
👍 Definitely a long-overdue feature for this library IMO. A few suggestions from me:
† Note:
I think so for now. @jmmease will have a better idea about future proofing for
Yes
Plotly can definitely take care of the docs side after this is merged. Happy to take another look at this after themes are serialized in files. |
Some thoughts with respect to the ipyplotly functionality coming to plotly.py. There are two approaches that I can think of that would work consistently with this new paradigm.
Supporting global themes and theme switching would be straightforward in approach 2, but I think they could be problematic for approach 1. The issue is that with the ipyplotly updates it will be possible to create a Figure with some initial data and then display it. And then properties can be updated and traces can be added to the Figure and the updates will be immediately reflected in the display. So there's not really a "last possible moment" anymore during which to apply the theme. Feel free to let me know if this isn't clear and I can elaborate more. Has there been any discussion on the Plotly.js of setting default properties based on a theme specification? |
I like thinking of themes as transformations that take a Plotly figure and a themes object as input. Maybe
This way, when we migrate to
A new top level Plotly.js method such as |
Wow, thanks for the comments! Looks like I stumbled up on a topic with some history. I will take a little time to review past attempts/how the themes are stored on streambed. But, I do have some comments now @jackparmer: definitely a good idea to have one theme per json file. I wrote as functions while I was testing and haven't take the time to move them to json files. It will be very easy @jackparmer Do you think that the former JSON representation of themes is the way we will ultimately want to do it? While fairly similar, there are a few differences between the two representations (I'll refer to the one here as "style" and the other one as "theme" -- even though the eventual name will be theme). Here's what I can think of so far:
I think a first step towards an implementation that is mergeable will be reaching consensus on JSON representation of themes. @jackparmer @jmmease This implementation of themes came from PlotlyJS.jl where we have long had the ability to update figure attributes in place (e.g. display a plot then restyle markers to be red or add a new trace). I'll talk through how I handled it there and hopefully we can iterate on ways to improve it so we can find the optimal way to apply this in the ipyplotly system. First, here's where information about styles is stored:
Now on to style application
What I am missing here, as @jmmease hinted at, is how styles should be applied to e.g. new traces added to the figure after display. In my current Julia implementation that doesn't happen, which is a bug. Given that I have style attribute on the plot, however, it would be straightforward to apply the style to the new trace before placing it on the figure (I call Note that In this PR I implemented a different system:
If we keep those semantics, I think @jackparmer proposal to have Happy to talk more on this |
Ah, I see, I didn't think about the case of re-applying styles. Thanks for explaining this. Seems like a good argument for storing the theme as a top level object in the Python figure versus a function transform. It could be a strange experience to apply a theme, then add a new trace, and the new trace looks totally different. I just want to make sure this is done in a way that is compatible with the imminent Along similar lines, @alexcjohnson and I were discussing theme "completeness" last night and agreed that if a theme is applied, then a 2nd theme is applied afterwards, the 2nd theme should erase all trace of the 1st theme. This was a big drawback of Plotly's first theme implementation in Chart Studio. CS didn't "clean the slate" between themes so you would get weird leftover artifacts when switching from one theme to another.
I'll leave it to you to decide what to keep and what to change or leave out. It's also a few years old and a bit out-of-date. I agree I'm sure there are other things I'm not thinking through, happy to keep fleshing this out here for as long as needed. To summarize, the 3 things I'd like to see in the next PR if possible:
|
Thanks for the detailed description of how PlotlyJS.jl handles styles @sglyon, that was very helpful. I think supporting styles as you've described will be feasible in the ipyplotly paradigm, and I'm really excited to have them when we're done! There will be some subtleties to sort through. Here are a few that come to mind:
|
I just noticed that cufflinks (https://plot.ly/ipython-notebooks/cufflinks/) also has its own theme support. I haven't looked at their implementation, but it would be nice if this also unified what they are doing. |
@jackparmer I like your idea regarding theme completeness. I think to do that we'd need access to something like I will keep thinking about how we should represent the theme in JSON, but here are some preliminary thoughts:
This is different from the current format for themes in (at least) the following ways:
Thoughts on this? @jmmease in Julia the notion of dynamic properties only just recently landed in the master branch. Thus the idea of doing You make a good point about setting a property to I think that having ipyplotly track/report the difference between Great call on the I haven't looked into the theme support in cufflinks. If what we build here ends up going back upstream into plotly.js then I suppose cufflinks would start to support it also? If that's the case then I think we can look at their implementation for inspiration, aim to build the most sensible theme story here in plotly.py, and then adjust theming in cufflinks to follow suit. |
It looks like the recently added One option would be to not do any property cycling in the theme and just have the theme set |
Hi @sglyon, I just updated master with Plotly.js 1.39.2, which has the new template (theme) support from plotly/plotly.js#2761. With just rerunning code generation it's already usable: fig = go.FigureWidget()
fig.layout.template = {
'layout': {'paper_bgcolor': 'lightgray'},
'data': {'scatter': [{'mode': 'markers',
'marker': {'size': 20, 'symbol': 'square'}},
{'mode': 'markers',
'marker': {'size': 20, 'symbol': 'triangle'}},
]}}
fig.add_scatter(y=[3, 1, 3])
fig.add_scatter(y=[1, 3, 2])
fig Do you have any suggestions for improving the Python API? Here are some of my thoughts:
|
That's fantastic. I'm happy that this is a plotly.js feature and that codegen opened it up to python right away. The one additional feature that PlotlyJS.jl has is the ability to merge themes. So I could have one that handles fonts, another for colors, another for XXX -- then I just call a function like |
Going to close this and we can pick up discussion on the the templates integration in #1161 |
This is request for comments regarding adding styles to plotly.py (another feature from the PlotlyJS.jl library I'm missing on the python side).
The docstrings In this PR have more details (as does the doc section linked to above), but the main idea is that a style defines default arguments for figure attributes. This can happen either for layout attributes, attributes for traces of a specific type, and attributes for traces of any type.
For example, suppose we have this plot:
The plot would look like this with no style applied:
If we do
make_fig().apply_style(go.STYLES["ggplot"])
we get:Or
make_fig().apply_style(go.STYLES["seaborn"])
gives:Or
make_fig().apply_style(go.STYLES["fivethirtyeight"])
:Before merging
I haven't totally finished this code as I wanted to present the concept and get some feedback (even an 👍 or 👎 would be great).
I think I will need some guidance from the team on the best way to incorporate this feature. Here are some questions for you:
go.Figure
?plt.style.use
command? The default for this setting would, of course, be an empty style.Things I need to do before finishing this PR:
EDIT 2-6-18
I've changed the name
style
totheme
in the code, so you would need to make the same change in order to run the examples above