Search code examples
pythonplotlyplotly-pythonplotly-express

Trace graph measurement not right plotly


I am trying to replicate this graph: link, the one for household savings.

This is my data:

[{'Year': 2020,
  'Country': 'Austria',
  'total_wealth': 1965.0672,
  'total_savings': 53.364},
 {'Year': 2020,
  'Country': 'Belgium',
  'total_wealth': 2701.08,
  'total_savings': 56.856},
 {'Year': 2020,
  'Country': 'Denmark',
  'total_wealth': 3292.4772,
  'total_savings': 22.956},
 {'Year': 2020,
  'Country': 'Germany',
  'total_wealth': 2071.3288,
  'total_savings': 65.668},
 {'Year': 2020,
  'Country': 'Italy',
  'total_wealth': 2500.7532,
  'total_savings': 40.904},
 {'Year': 2020,
  'Country': 'Netherlands',
  'total_wealth': 3180.148,
  'total_savings': 75.328},
 {'Year': 2020,
  'Country': 'Sweden',
  'total_wealth': 2747.4992,
  'total_savings': 67.8}]

I want the trace graph to be a bit more close with the bar chart, and annotations next to the markers, I am not sure how can i adjust the scale a bit since it shows 0. Can anyone give suggestions as to where i am going wrong?


Solution

  • The reason why your graph differs from what you expect is in the data of the graphs of the examples in the reference and the numerical values of your data. First, the annotations on the right side of the graph were originally positioned x=ydn-2000 pixels to the left. I have corrected this to x=ydn-200. Secondly, the x-axis scale on the left side is too large, so I changed it to dtick=500.

    import plotly.graph_objects as go
    from plotly.subplots import make_subplots
    import pandas as pd
    
    
    # Creating two subplots
    fig = make_subplots(rows=1, cols=2, specs=[[{}, {}]], shared_xaxes=False,
                        shared_yaxes=False, vertical_spacing=0.001)
    
    fig.append_trace(go.Bar(
        x=new_df['total_savings'],
        y=new_df['Country'],
        marker=dict(
            color='rgba(50, 171, 96, 0.6)',
            line=dict(
                color='rgba(50, 171, 96, 1.0)',
                width=1),
        ),
        name='Household savings, percentage of household disposable income',
        orientation='h',
    ), 1, 1)
    
    fig.append_trace(go.Scatter(
        x=new_df['total_wealth'], y=new_df['Country'],
        mode='lines+markers',
        line_color='rgba(165, 187, 191 )',
        name='Household net worth, Million USD/capita',
    ), 1, 2)
    
    fig.update_layout(
        title='Household savings & net worth for eight OECD countries',
        yaxis=dict(
            showgrid=False,
            showline=False,
            showticklabels=True,
            domain=[0, 0.85],
        ),
        yaxis2=dict(
            showgrid=False,
            showline=True,
            showticklabels=False,
            linecolor='rgba(102, 102, 102, 0.8)',
            linewidth=2,
            domain=[0, 0.85]
        ),
        xaxis=dict(
            zeroline=False,
            showline=False,
            showticklabels=True,
            showgrid=True,
            domain=[0, 0.42],
        ),
        xaxis2=dict(
            zeroline=False,
            showline=False,
            showticklabels=True,
            showgrid=True,
            domain=[0.47, 1],
            side='top',
            dtick=500,
        ),
        legend=dict(x=0.029, y=1.038, font_size=10),
        margin=dict(l=90, r=20, t=70, b=70),
        paper_bgcolor='rgb(220, 220, 220)',
        plot_bgcolor='rgb(220, 220, 220)',
        width=1000,
        height=600
    
    )
    
    annotations = []
    
    y_s = new_df['total_savings'].round(decimals=2)
    y_nw = new_df['total_wealth'].round()
    
    # Adding labels
    for ydn, yd, xd in zip(y_nw, y_s, new_df['Country']):
        # labeling the scatter savings
        annotations.append(dict(xref='x2', yref='y2',
                                y=xd, x=ydn - 200,
                                text='{:,}'.format(ydn) + 'M',
                                font=dict(family='sans-serif', size=14,
                                          color='rgb(128, 0, 128)'),
                                showarrow=False))
        # labeling the bar net worth
        annotations.append(dict(xref='x1', yref='y1',
                                y=xd, x=yd + 8,
                                text=str(yd) + '%',
                                font=dict(family='sans-serif', size=14,
                                          color='rgb(50, 171, 96)'),
                                showarrow=False))
    
    fig.update_layout(annotations=annotations)
    
    fig.show()
    

    enter image description here