I want to change the item shape of my legend from line to any other appealing shape like a box or a circle. Below is my chart. You can see the legend item is showing a colored line. It is not very appealing.
How do I change the shape of the legend item without changing the chart type?

Below is the example of a desired item shape for my legend.

Your best option to hopefully make your legend symbols a bit more visually appealing without messing up the figure traces as well seems to be:
fig.layout.legend.itemsizing = 'constant'
Which will give you the following legend with items that at least look a bit more like a box or rectangle instead of a line:

Instead of this:

The shape of the legend by default reflects the shape of your trace. That also goes for size and shape of a marker symbol. So if you build a plot like this:

Then you can always change the way the legend looks through:
fig.data[0].mode = 'markers+lines'
fig.data[0].marker.symbol = 'diamond'
fig.data[0].marker.size = 12
But the problem is that this goes for the figure traces as well as you can see here:

And I've made a few attempts on setting a marker symbol and then removing the marker for the traces to hopefully retain the marker in the legend. But that doesn't work. And I think we're all better off for it. So that leaves you with my initial suggestion.
# imports
import pandas as pd
import plotly.express as px
# data
df = px.data.stocks()
df = df.drop(['AMZN', 'AAPL', 'MSFT', 'FB'], axis = 1)
colors = px.colors.qualitative.T10
# plotly
fig = px.line(df,
x = 'date',
y = [c for c in df.columns if c != 'date'],
template = 'plotly_dark',
color_discrete_sequence = colors,
title = 'Stocks',
)
fig.data[0].mode = 'markers+lines'
fig.data[0].marker.symbol = 'diamond'
fig.data[0].marker.size = 12
fig.layout.legend.itemsizing = 'constant'
fig.show()
This may be too late, but I found a hacky work-around to customize the legend shapes of a line graph by using the ff configuration:
fig.add_trace(go.Scatter(
x=[1, 2, 3, 4],
y=[10, 15, 13, 17],
name = 'trace 1',
# Set the legendgroup per trace.
# Use this legendgroup with the corresponding shape so clicking the shape's legend will toggle the trace.
legendgroup = 'trace 1',
marker = dict(color='firebrick'),
# Don't show the legend for the trace so only the shape's legend is visible.
showlegend = False,
))
fig.add_trace(go.Scatter(
x=[1, 2, 3, 4],
y=[16, 5, 11, 9],
name = 'trace 2',
legendgroup = 'trace 2',
marker = dict(color='royalblue'),
showlegend = False,
))
fig.add_shape(
name = 'trace 1',
# The shape should match the trace's legend group so it will toggle the shape and the trace as a group.
legendgroup = 'trace 1',
# Show the shape's legend.
showlegend = True,
type = 'rect',
# For sanity, render the shape behind the lines.
# But this shouldn't be necessary because the shape will never get plotted on the graph. See the xn configuration below.
layer = 'below',
# If you don't want a border around your legend's symbol, set the line.width to 0.
line = dict(width = 0),
# The fillcolor should match the trace's marker/line color.
fillcolor = 'firebrick',
# Set the plot points of the shape to 0 so it won't be rendered on the graph.
x0 = 0,
y0 = 0,
x1 = 0,
y1 = 0,
)
fig.add_shape(
name = 'trace 2',
legendgroup = 'trace 2',
showlegend = True,
type = 'rect',
layer = 'below',
line = dict(width = 0),
fillcolor = 'royalblue',
x0 = 0,
y0 = 0,
x1 = 0,
y1 = 0,
)
You can see it in action here: https://codesandbox.io/p/sandbox/goofy-bassi-3xls2j?file=%2Fmain.py%3A2%2C1
Gist
The main configuration properties here are:
legendgroup- which groups traces/shapes into one so when a legend is clicked, it will not only toggle the trace/shape it belongs to, but it will also toggle the others within the same group.shapes - since it appears that plotly bases the legend symbol on the marker of the plot, the shape you define will also be used as the legend symbol of that shape.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With