Search code examples
pythonplotlyplotly-python

Plotly: How to change legend item names?


I want to change the names of the items in the legend. A reproducible example below.

import plotly.express as px
df = px.data.iris()
colorsIdx = {'setosa': '#c9cba3', 'versicolor': '#ffe1a8',
             'virginica': '#e26d5c'}
cols      = df['species'].map(colorsIdx)

fig = px.scatter_3d(df, x='sepal_length', y='sepal_width', z='petal_width',
              color=cols)
fig.show()

enter image description here

Because i assigned my own colors to the species i want to rename the legend so it doesn't appear as '#c9cba3', '#ffe1a8' & '#e26d5c'. instead i want to be "setosa" "versicolor" & "virginica"


Solution

  • In general you can use:

    fig.for_each_trace(lambda t: t.update(name = newnames[t.name]))
    

    Where in your case newnames would be the dict:

    {'#c9cba3': 'setosa', '#ffe1a8': 'versicolor', '#e26d5c': 'virginica'}
    

    And you've already specified a dict with similar info in colorsIdx, so you just need to switch keys and values with:

    newnames = {y:x for x,y in colorsIdx.items()}
    

    enter image description here

    However, you should be aware that there's more going on here! In px.scatter(), the color argument has got little to do with actual colors, but rather which variable in a pandas dataframe to look for unique values to assign a color to. Have a look at what happens when you change your:

    colorsIdx = {'setosa': '#c9cba3', 'versicolor': '#ffe1a8',
                 'virginica': '#e26d5c'}
    

    ...to:

    colorsIdx = {'setosa': '#magic', 'versicolor': '#color',
                 'virginica': '#function'}
    

    The colors are the very same in your sample plot because of what I explained initially:

    enter image description here

    To actually specify colors in your case, use color_discrete_map=dict() and use color for species variable. This way you can actually define your desired colors, and you won't have to rename your legend elements.

    Plot:

    enter image description here

    Complete code:

    import plotly.express as px
    df = px.data.iris()
    
    fig = px.scatter_3d(df, x='sepal_length', y='sepal_width', z='petal_width',
                  color='species',
                  color_discrete_map={'setosa': 'steelblue', 
                                      'versicolor': 'firebrick',
                                      'virginica': 'green'})
    fig.show()