pythonpython-3.xplotlyplotly-python

Control duplication of legend items in Python Plotly.express


I am using plotly.express to produce a figure with 3 subplots. The legend repeats for each subplot, so I have 3 legend listings (one for each subplot) for each item. All operate together when I click them to turn off/turn on (which is fine, no need for independent operation). Is there a way to reduce this to 1 legend listing per item? The legend is variable as it is a file name, so I can't use fixed legend title. The 'Ambient' part can be ignored for the purpose of this question. enter image description here

    fig = make_subplots(rows=1, cols=3,
                        column_titles=['Velocity m/s', 'Temperature C',
                                       'Salinity '],
                        row_titles=['Depth m', 'Depth m'],
                        shared_yaxes=True)

    fig1 = px.line(dfs, x='Sound Velocity', y='Depth',
                   color='File')
    fig2 = px.line(dfs, x='Temperature', y='Depth',
                   color='File')
    fig3 = px.line(dfs, x='Salinity', y='Depth',
                   color='File')

    dips = dfs['File'].nunique()  # Count number of different files

    for dip in range(dips):
        fig.add_trace(fig1['data'][dip], row=1, col=1)

    for dip in range(dips):
        fig.add_trace(fig2['data'][dip], row=1, col=2)

    for dip in range(dips):
        fig.add_trace(fig3['data'][dip], row=1, col=3)

    fig.update_layout(template="plotly_dark")
    fig.add_trace(go.Scatter(y=[z_min, z_max], x=[rv_min, v_max],
                             line=dict(color='#D7CECE', width=2,
                             dash='dash'), name="Ambient"))

Excerpt from the Dataframe crossing two files (SVP-3 & SVP-4).

    Date/Time   Depth   Sound Velocity  Pressure    Temperature Conductivity    Salinity    Density File
1377    22/10/2023 05:17    -2.719  1545.445    2.719   29.25   59.854  36.58   1023.179    SVP-3@YOTI 2-DEL.txt
1378    22/10/2023 05:17    -2.092  1545.432    2.092   29.248  59.854  36.582  1023.178    SVP-3@YOTI 2-DEL.txt
1379    22/10/2023 05:17    -1.592  1545.418    1.592   29.248  59.852  36.581  1023.175    SVP-3@YOTI 2-DEL.txt
1380    22/10/2023 05:17    -1.178  1545.41 1.178   29.247  59.848  36.579  1023.172    SVP-3@YOTI 2-DEL.txt
1381    22/10/2023 05:17    -0.691  1545.408    0.691   29.246  59.854  36.584  1023.174    SVP-3@YOTI 2-DEL.txt
1382    22/10/2023 05:17    -0.171  1545.415    0.171   29.247  59.844  36.576  1023.166    SVP-3@YOTI 2-DEL.txt
1383    24/10/2023 15:59    -1.39   1543.341    1.39    29.397  56.71   34.315  1021.423    SVP-4@YOTI 2-DEL.txt
1384    24/10/2023 15:59    -1.585  1543.34 1.585   29.397  56.708  34.314  1021.423    SVP-4@YOTI 2-DEL.txt
1385    24/10/2023 15:59    -2.261  1543.356    2.261   29.395  56.704  34.312  1021.425    SVP-4@YOTI 2-DEL.txt
1386    24/10/2023 15:59    -2.788  1543.38 2.788   29.396  56.71   34.315  1021.429    SVP-4@YOTI 2-DEL.txt
1387    24/10/2023 15:59    -3.173  1543.383    3.173   29.396  56.712  34.317  1021.432    SVP-4@YOTI 2-DEL.txt
1388    24/10/2023 15:59    -3.591  1543.373    3.591   29.395  56.71   34.316  1021.434    SVP-4@YOTI 2-DEL.txt
1389    24/10/2023 15:59    -4.095  1543.358    4.095   29.39   56.706  34.316  1021.438    SVP-4@YOTI 2-DEL.txt
1390    24/10/2023 16:00    -4.654  1543.339    4.654   29.382  56.696  34.315  1021.442    SVP-4@YOTI 2-DEL.txt
1391    24/10/2023 16:00    -5.362  1543.197    5.362   29.35   56.64   34.3    1021.444    SVP-4@YOTI 2-DEL.txt

Problem solved, thanks to the answer from #EricLavault. Updated graphic exactly as required. Much neater code, used exactly as given, including reduced trace_groupgap suggestion. enter image description here


Solution

  • There is one trace per color (file) in each subplot and all traces have showlegend=True set by default. Since the color in each subplot refers to the same set of files (and because there is no need to toggle the visibility of individual items in the same subplot), the idea would be to set showlegend=True only once for a given file.

    For example (with a bit of refactoring, leveraging go.Figure.add_traces()) :

    fig = make_subplots(rows=1, cols=3,
                        column_titles=['Velocity m/s', 'Temperature C',
                                        'Salinity '],
                        row_titles=['Depth m', 'Depth m'],
                        shared_yaxes=True)
    
    for i, column in enumerate(['Sound Velocity', 'Temperature', 'Salinity']):
        _fig = px.line(dfs, x=column, y='Depth', color='File')
        _fig.update_traces(showlegend= i == 0)
        fig.add_traces(_fig['data'], rows=1, cols=i+1)
    

    The legend will end up with one item per group, you might want to decrease its tracegroupgap :

    fig.update_layout(template="plotly_dark", legend_tracegroupgap=1)