3

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"

vestland
  • 55,229
  • 37
  • 187
  • 305
HarriS
  • 605
  • 1
  • 6
  • 19

2 Answers2

10

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()
vestland
  • 55,229
  • 37
  • 187
  • 305
  • I copy your complete code, but I am facing a problem in each plotly created graph and it is about legend. The legend is `species = setosa, sepecies=versiclor, sepecies = virginica `. How to get rid from these, especially in line graph. Please look at this [image](https://user-images.githubusercontent.com/49120051/125181893-f57a4e00-e226-11eb-8f0d-6faa2895264b.png) whose legend differ from yours! – Girish Kumar Chandora Jul 11 '21 at 03:39
0

Another solution that doesnt rely on creating dict of existing names because sometimes you dont care what the existing legend is and just want to change it

for i,trace in enumerate (fig.data):
  trace.update(name=name_list[i])
user15420598
  • 107
  • 7