Skip to content
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

Could we access plotly.js default colors in plotly.py ? #1026

Closed
mwouts opened this issue Jun 4, 2018 · 8 comments
Closed

Could we access plotly.js default colors in plotly.py ? #1026

mwouts opened this issue Jun 4, 2018 · 8 comments

Comments

@mwouts
Copy link

mwouts commented Jun 4, 2018

I like very much plotly's default color scale. However, I am not aware of an official way to reproduce it when I want multiple traces to be of the same color. For now I use the explicit list from https://stackoverflow.com/a/44727682, which I have coded into a function (see below). Is there a recommended way to enforce two traces to be of the same color ? Would you consider including in plotly.py the default color scale ? Thanks

from itertools import cycle

def plotly_color_map(names):
    # From https://stackoverflow.com/a/44727682
    plotly_colors = cycle(['#1f77b4',  # muted blue
                           '#ff7f0e',  # safety orange
                           '#2ca02c',  # cooked asparagus green
                           '#d62728',  # brick red
                           '#9467bd',  # muted purple
                           '#8c564b',  # chestnut brown
                           '#e377c2',  # raspberry yogurt pink
                           '#7f7f7f',  # middle gray
                           '#bcbd22',  # curry yellow-green
                           '#17becf'  # blue-teal
                           ])

    return dict(zip(names, plotly_colors))
@jonmmease
Copy link
Contributor

This is an interesting idea. I wonder if this is something that would make sense in the colorlover library. Maybe as colorlover.scales['10']['qual']['Plotly']. What do you think @jackparmer ? Would that work for you @mwouts ?

Also, in case it's useful (to you or to others who find this issue in the future), it is possible to modify this cycle of trace colors that are used by default. This is done using the layout.colorway option.

For example, here's how you could to cause the traces to cycle through red, green, and blue.

import plotly.graph_objs as go
from plotly.offline import iplot, init_notebook_mode
init_notebook_mode()

fig = go.Figure(
    data=[{'y': [1, 2, 3]}, {'y': [2, 1, 3]}, {'y': [1, 3, 2.5]}],
    layout={'colorway': ['red', 'green', 'blue']}
)
iplot(fig)

newplot

@mwouts
Copy link
Author

mwouts commented Jun 4, 2018

Hello @jmmease, yes certainly I could import the colorscale from the colorlover package, that would already be more generic than copying/pasting stackoverflow.

I like the colorway layout option, thanks for sharing.

Finally, I would appreciate to simplify the task of giving same colors to traces that have identical names. Would you have recommendations on how to make the below shorter ?

import plotly.graph_objs as go
from plotly.offline import iplot, init_notebook_mode
init_notebook_mode()

cm = plotly_color_map(['trace1', 'trace2']) # function defined in previous post

fig = go.Figure(
    data=[{'y': [1, 2, 3], 'name':'trace1', 'legendgroup':'trace1',
           'line':{'color': cm['trace1']}},
          {'y': [2, 1, 3], 'name':'trace2', 'legendgroup':'trace2',
              'line':{'color': cm['trace2']}},
          {'y': [1, 2, 3], 'name':'trace1', 'legendgroup':'trace1',
              'showlegend':False, 'xaxis':'x2',
           'line':{'color': cm['trace1']}},
          {'y': [1, 3, 2.5], 'name': 'trace2', 'legendgroup': 'trace2',
           'showlegend': False, 'xaxis': 'x2', 'line': {'color': cm['trace2']}}],
    layout={'xaxis': {'domain': [0, .45]},
            'xaxis2': {'domain': [.55, 1]}}
)
iplot(fig)

newplot-4

@jonmmease
Copy link
Contributor

How about this?

import plotly.graph_objs as go
from plotly.offline import iplot, init_notebook_mode
init_notebook_mode()

cm = plotly_color_map(['trace1', 'trace2']) # function defined in previous post

style1 = {'name':'trace1', 'legendgroup':'trace1', 'line':{'color': cm['trace1']}}
style2 = {'name':'trace2', 'legendgroup':'trace2', 'line':{'color': cm['trace2']}}

fig = go.Figure(
    data=[{'y': [1, 2, 3], **style1},
          {'y': [2, 1, 3], **style2},
          {'y': [1, 2, 3], 'showlegend': False, 'xaxis':'x2', **style1},
          {'y': [1, 3, 2.5], 'showlegend': False, 'xaxis': 'x2', **style2}],
    layout={'xaxis': {'domain': [0, .45]},
            'xaxis2': {'domain': [.55, 1]}}
)
iplot(fig)

Or, if you have a bunch of traces to define, maybe this would be cleaner

trace_names = ['trace1', 'trace2']
cm = plotly_color_map(trace_names)
styles = {
    name: {'name': name, 'legendgroup': name, 'line': {'color': cm[name]}}
    for name in trace_names
}

fig = go.Figure(
    data=[{'y': [1, 2, 3], **styles['trace1']},
          {'y': [2, 1, 3], **styles['trace2']},
          {'y': [1, 2, 3], 'showlegend': False, 'xaxis':'x2', **styles['trace1']},
          {'y': [1, 3, 2.5], 'showlegend': False, 'xaxis': 'x2', **styles['trace2']}],
    layout={'xaxis': {'domain': [0, .45]},
            'xaxis2': {'domain': [.55, 1]}}
)
iplot(fig)

@mwouts
Copy link
Author

mwouts commented Jun 5, 2018

Thanks @jmmease, yes that's much better than what I had. Still, I would prefer not having to code the colors at all even when I have multiple traces with identical name. Don't you think we should open a separate issue for that question on how to remove duplicate legend names? On stackoverflow I found a similar question, but again the solution is to specify colors manually (and use showlegend and legendgroup arguments).

@jonmmease
Copy link
Contributor

@mwouts It's not obvious to me what an API would look like to accomplish this, but if you have some ideas could you open a new issue on the plotly/plotly.js tracker? Adding new plot properties, or changing the behavior of existing properties, has to flow through the JavaScript library first.

While you're at it, do you want to go ahead and create the issue on the colorlover repo to request the plotly colormap?

If these two issues capture what we've discussed here, lets go ahead and close this one. Thanks!

@mwouts
Copy link
Author

mwouts commented Jun 5, 2018

Sure! I've opened the request for plotly colors in colorlover. I'll think a bit more about the other question on how to merge traces in legend, and then open the issue on plotly.js. Thanks !

@jonmmease
Copy link
Contributor

Turns out this has been in plotly.py all along, but I just learned about it today 🙂

>>> from plotly.colors import DEFAULT_PLOTLY_COLORS
>>> DEFAULT_PLOTLY_COLORS
['rgb(31, 119, 180)',
 'rgb(255, 127, 14)',
 'rgb(44, 160, 44)',
 'rgb(214, 39, 40)',
 'rgb(148, 103, 189)',
 'rgb(140, 86, 75)',
 'rgb(227, 119, 194)',
 'rgb(127, 127, 127)',
 'rgb(188, 189, 34)',
 'rgb(23, 190, 207)']

Can you confirm that this is what you were looking for?

@mwouts
Copy link
Author

mwouts commented Aug 24, 2018

Well, yes, exactly! Thanks @jonmmease, that's exactly what I was searching for.

@mwouts mwouts closed this as completed Aug 24, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants