How to dynamically adjust/shift heatmap to the right enough so that its axis labels don't get cut off?

Here’s an example to demonstrate the issue:

import dash
import dash_core_components as dcc
import dash_html_components as html
import base64
import pandas as pd
import plotly.graph_objs as go

app = dash.Dash()
app.layout = html.Div([
    dcc.Dropdown(
        id='dropdown-div',
        options=[
            {'label': 'Correlation Map', 'value': 'correlation'},
        ],
        style={'width':'30%'},
        placeholder="Select an option...",
    ),
    html.Div(id='output-div')
])

@app.callback(
    dash.dependencies.Output('output-div', 'children'),
    [dash.dependencies.Input('dropdown-div', 'value')]
)
def update_output_div(selection_option):
    data = {'A long column name':[1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000],
            'Another long column name':[10000, 9000, 8000, 7000, 6000, 5000, 4000, 3000, 2000, 1000]
           }
    df = pd.DataFrame(data, columns=['A long column name', 'Another long column name'])

    corr = df.corr()
    z = corr.values

    trace = go.Heatmap(z=z,
                       x=corr.columns,
                       y=corr.columns)
    data=[trace]

    layout = go.Layout(autosize=True,
                       width=700, 
                       height=700,
                       title='Feature Correlation Map')

    return dcc.Graph(
        id='correlation-graph',
        figure={
            'data': data,
            'layout': layout
        }
    )



if __name__ == '__main__':
    app.run_server(debug=True)

It produces the figure with part of its y-axis labels cut off:

To fix this issue, I modified the layout.margin.l parameter to 200 for this particular figure, and then by hit-and-trial, also modified the width parameter to more or less maintain the aspect ratio of the original plot (which was square) as best as the eye could see:

But, obviously, how much the layout.margin.l parameter needs to be changed depends on how long are the column names. So, for every new data that comes in, this would have to be done by hit-and-trial. Is there any way to dynamically/automatically fix this?

Try xaxis: {'automargin': True}, 'yaxis': {'automargin': True}

1 Like