Search code examples
pythonplotlyplotly-python

Plotly: How to automate y-axis with space for texttemplate?


i try to figure out how to plot this barchart with texttemplate. without cutting them, but also keep the y-axis dynamic. thanks for ideas!

import plotly.express as px

df = px.data.gapminder().query("continent == 'Europe' and year == 2007 and pop > 2.e6")
df.lifeExp = df.lifeExp/100
fig = px.bar(df, y='lifeExp', x='country', text='lifeExp')
fig.update_traces(texttemplate='%{text:.2%}', textposition='outside')
fig.update_layout(uniformtext_minsize=20, uniformtext_mode='show')
plotly.io.write_image(fig, file='bartest.png', format='png')

enter image description here


Solution

  • Setting uniformtext_minsize=20 will make your figure look crowded either way. So instead of fig.update_traces(texttemplate='%{text:.2%}', textposition='outside') I would actually go for:

    fig.update_traces(texttemplate='%{text:.2%}', textposition='inside')
    fig.update_layout(uniformtext_minsize=12, uniformtext_mode='show')
    

    Plot 1

    enter image description here

    Plotly adjusts the size of the yaxis to the size of the bars and not the texts added to it afterwards, so this way you'll prevent any problems with cutting off text. If you for some reason prefer to keep the text elements above the bars, you'll have to adjust the y-aixs accordingly with, for example:

    fig.update_yaxes(range=[0, max(df.lifeExp)*1.2])
    

    But as you can see you'll have to set uniformtext_minsize to an impractically low number in order to make the text elements readable:

    Plot 2

    enter image description here

    Complete code for Plot 1

    import plotly.express as px
    
    df = px.data.gapminder().query("continent == 'Europe' and year == 2007 and pop > 2.e6")
    df.lifeExp = df.lifeExp/100
    fig = px.bar(df, y='lifeExp', x='country', text='lifeExp')
    fig.update_traces(texttemplate='%{text:.2%}', textposition='inside')
    fig.update_layout(uniformtext_minsize=11, uniformtext_mode='show')
    # plotly.io.write_image(fig, file='bartest.png', format='png')
    
    
    fig.show()
    

    Complete code for Plot 2

    import plotly.express as px

    df = px.data.gapminder().query("continent == 'Europe' and year == 2007 and pop > 2.e6")
    df.lifeExp = df.lifeExp/100
    fig = px.bar(df, y='lifeExp', x='country', text='lifeExp')
    fig.update_traces(texttemplate='%{text:.2%}', textposition='outside')
    fig.update_layout(uniformtext_minsize=5, uniformtext_mode='show')
    # plotly.io.write_image(fig, file='bartest.png', format='png')
    fig.update_yaxes(range=[0, max(df.lifeExp)*1.2])
    
    fig.show()