Search code examples
pythonplotlydata-visualizationplotly-python

Is there a way to prevent the legend on plotly from moving up into the chart when its orientation is horizontal?


Context

I am currently in the middle of creating a data visualisation web app. I am using Plotly to create a timeseries. I am having trouble with the legend.

I want the legend to remain at the bottom as the labels of the data are quite long and so interfere with the overall dimensions of the data. I chose the orientation to be horizontal.

But as I add more data, the legend moves up rather than remain in a fixed position so that the new data can be added going down. Instead the whole legend goes up as new data is added to the chart.

One indicator Many indicators

My code is below:

plotly_fig = px.line(data_frame=dataframe_cols1,x=dataframe_cols1.index,y=Columns_select1,
                            width=780, height=730) # Get data from the dataframe with selected columns, choose the x axis as the index of the dataframe, y axis is the data that will be multiselected
        
        # Legend settings
        plotly_fig.update_layout(showlegend=True)       
        plotly_fig.update_layout(legend=dict(
                          orientation = "h",
                          yanchor="bottom",
                          y=-.50,
                          xanchor="right",
                          x=1
                        ))    

Problem

How can I prevent the legend from moving up as I add new data? In other words, how can I fix the legend in its position to prevent it from 'mingling' with the chart?


Solution

  • There's really only one way; make room and adjust legend position.

    And in this case you would do that through:

    1. fig.update_layout(height=1000)
    2. fig.update_layout(margin=dict(l=20, r=20, t=20, b=20)
    3. fig.update_layout(legend=dict(orientation = "h", yanchor="bottom",y=-1.1,xanchor="left", x=0))

    Sample plot

    enter image description here

    Complete code:

    import pandas as pd
    import numpy as np
    import plotly
    import plotly.express as px
    
    # data
    start = 2021
    ncols = 20
    nrows = 1000
    cols = [str(i) for i in np.arange(start, start+ncols)]
    df = pd.DataFrame(np.random.randint(-1,2, (nrows,ncols)), columns = cols).cumsum()
    df.iloc[0] = 0
    
    # figure
    fig = px.line(df, x=df.index, y=cols,width=780, height=730)
    
    # updating names
    fig.for_each_trace(lambda t: t.update(name=t.name + ' Very lengthy name to reproduce the challenge') )
        
    # legend position
    fig.update_layout(showlegend=True) 
    fig.update_layout(legend=dict(
                      orientation = "h",
                      yanchor="bottom",
                      y=-1.1,
                      xanchor="left",
                      x=0)) 
    
    height = 1000
    fig.update_layout(
        autosize=False,
        width=750,
        height=height)
    
    fig.update_layout(
        margin=dict(l=20, r=20, t=20, b=20),
        paper_bgcolor="LightSteelBlue")
    
    # plotly.offline.plot(fig, filename='C:/plotlyplots/lifeExp.html')
    fig.show()