How to align text left on a plotly bar chart (example image contained) [Plotly-Dash]

plotly annotations
plotly horizontal bar chart
plotly dash documentation
plotly stacked and grouped bar chart
plotly hover text multiple lines
plotly layout
plotly js annotations
dash core components

I need help in adding text to my graph.

I have tried text = 'y' and text-position = 'inside' but the text goes vertical or gets squashed for small bar charts so it can fit inside the bar. I just want it to write across.

Here is a working example of the code that needs fixing:

app = dash.Dash(__name__)
app.css.append_css({'external_url': 'https://codepen.io/amyoshino/pen/jzXypZ.css'})

    labels1 = ['0-7', '8-12', '13-15', '16-20', '21-25', '26+']
values1 = [10, 30, 10, 5, 6, 8]


labels2 = ['India', 'Scotland', 'Germany', 'NW England', 'N Ireland', 'Norway', 'NE England', 'Paris', 'North Africa', 'scandinavia']
values2 = [1, 0, 4, 9, 11, 18, 50, 7, 0, 2]

values3 = [10, 111, 75, 20]
labels4 = ['Safety Manager', 'Office Administrator', 'Internal Officer', 'Assistant Producer']

bar_color = ['#f6fbfc', '#eef7fa', '#e6f3f7', '#deeff5', '#d6ebf2', '#cde7f0', '#c5e3ed', '#bddfeb', '#b5dbe8', '#add8e6']
bar_color2 = ['#e6f3f7', '#deeff5', '#d6ebf2', '#cde7f0', '#c5e3ed', '#bddfeb', '#b5dbe8', '#add8e6']

app.layout = html.Div([
  html.Div([ 
    html.Div([
        dcc.Graph(id = 'age',
                          figure = {
                                    'data': [go.Bar(x = values1,
                                                    y = labels1,
                                                    orientation = 'h',
                                                    marker=dict(color = bar_color2),
                                                    text = labels1,
                                                    textposition = 'inside'
                                                    )
                                            ],
                                    'layout': go.Layout(title = 'Number of respondees per tenure',
                                                        yaxis=dict(
                                                                   zeroline=False,
                                                                   showline=False,
                                                                   showgrid = False,
                                                                   autorange="reversed",
                                                                   ),
                                                            xaxis=dict(
                                                                      zeroline=False,
                                                                      showline=False,
                                                                      showgrid = False
                                                                      )
                                                       )
                                  }
                         )
    ], className = 'four columns'),


    html.Div([
       dcc.Graph(id = 'location',
                                 figure = {
                                          'data': [go.Bar(x = values2,
                                                          y = labels2,
                                                          orientation = 'h',
                                                          marker=dict(color = bar_color),
                                                            text = labels2,
                                                            textposition = 'inside'
                                                         )
                                                  ],
                                          'layout': go.Layout(title = 'Number of respondees per region',
                                                                yaxis=dict(
                                                                          zeroline=False,
                                                                          showline=False,
                                                                          showgrid = False,
                                                                          autorange="reversed",
                                                                         ),
                                                                xaxis=dict(
                                                                          zeroline=False,
                                                                          showline=False,
                                                                          showgrid = False
                                                                         )                                                             ) 
                                        }
                                )
        ], className = 'four columns'),

    html.Div([
            dcc.Graph(id = 'job',
                                  figure = {
                                            'data': [go.Bar(x = values3,
                                                            y = labels4,
                                                            orientation = 'h',
                                                            marker=dict(color = bar_color2),
                                                            text = labels4,
                                                            textposition = 'inside'                                                            
                                                           )
                                                    ],
                                           'layout': go.Layout(title = 'Number of respondees per role',
                                                               yaxis=dict(
#                                                                         automargin=True,
                                                                          zeroline=False,
                                                                          showline=False,
                                                                          showgrid = False,
                                                                          autorange="reversed",
                                                                         ),
                                                                xaxis=dict(
                                                                          zeroline=False,
                                                                          showline=False,
                                                                          showgrid = False
                                                                         )
                                                              ) 
                                           }
                                )
        ], className = 'four columns')


  ], className = 'row')

])

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

Here's the output:

Here's an example of how I want my text to look:

I need help with two things:

  1. Make the text align to the left not the right of the bar.
  2. If the bar length is short I want the text to still be visible (even if the bar length is zero) and not squashed or vertically aligned.

If you can also give an explanation of how to fix y-axis being cut off in the third chart that would be amazing. For now, I have to change the labels to force it to fit which is time-consuming. Is there a way of adding padding to the container or something?

Thanks.

This is an inelegant workaround, but after scouring the plotly python docs, I couldn't find anything that would do exactly what you were asking with the plotly attributes provided. If you need a one-time, quick fix now, try using yaxis=dict(showticklabels=False) and add your labels manually as annotations like:

layout = go.Layout(
    # Hide the y tick labels
        yaxis=dict(
        showticklabels=False),
    annotations=[
        dict(
        # I had to try different x values to get alignment
            x=0.8,
            y='giraffes',
            xref='x',
            yref='y',
            text='Giraffes',
            font=dict(
                family='Arial',
                size=24,
                color='rgba(255, 255, 255)'
            ),
            align='left',
        # Don't show any arrow
            showarrow=False,
        ), 

The output I got looked like:

You can check the Plotly Annotations and Chart Attributes documentation to see if there is anything that better suits your needs.

Edit: I started posting this response before the code was added to the question. Here is an example of how the annotations could be made for the first two y labels of the first graph in the code in question:

app.layout = html.Div([
  html.Div([ 
    html.Div([
        dcc.Graph(id = 'age',
                          figure = {
                                    'data': [go.Bar(x = values1,
                                                    y = labels1,
                                                    orientation = 'h',
                                                    marker=dict(color = bar_color2),
                                                    text = labels1,
                                                    textposition = 'inside'
                                                    )
                                            ],
                                    'layout': go.Layout(title = 'Number of respondees per tenure',
                                                        yaxis=dict(
                                                                   zeroline=False,
                                                                   showline=False,
                                                                   showgrid = False,
                                                                   showticklabels=False
                                                                   autorange="reversed",
                                                                   ),
                                                            xaxis=dict(
                                                                      zeroline=False,
                                                                      showline=False,
                                                                      showgrid = False
                                                                      )
                                                                   ),
                                                            annotations=[dict(
                                                                        x=0.8,
                                                                        y=labels1[0],
                                                                        xref='x',
                                                                        yref='y',
                                                                        text=labels1[0],
                                                                        font=dict(
                                                                            family='Arial',
                                                                            size=24,
                                                                            color='rgba(255, 255, 255)'
                                                                        ),
                                                                        align='left',
                                                                        showarrow=False,
                                                                    ), 
                                                                    dict(
                                                                        x=1.2,
                                                                        y=labels1[1],
                                                                        xref='x',
                                                                        yref='y',
                                                                        text=labels1[1],
                                                                        font=dict(
                                                                            family='Arial',
                                                                            size=24,
                                                                            color='rgba(255, 255, 255)'
                                                                        ),
                                                                        align='left',
                                                                        showarrow=False,
                                                                    ),

Edit 2: @ user8322222, to answer the question in your comment, you could use a list comprehension to make your annotations dictionary like so:

 annotations1 = [dict(x=(len(labels1[i])*0.15), y=labels1[i], xref='x', yref='y', 
text=labels1[i], font=dict(family='Arial', size=24, color='rgba(255, 255, 255)'),
      align='left', showarrow=False) for i in range(len(labels1))]

However I don't think there will be a constant you could multiply by the length of the text in characters (like I used for x in the example) to get perfect alignment. You could use the pixel length or other measures for the string as in this post to devise a more accurate way of determining x to get it properly aligned. Hope that helps.

Part 2. Layout | Dash for Python Documentation, Note: Throughout this documentation, Python code examples are meant to be saved The dash_html_components library contains a component class for every in the Dash application as <h1 style="text-align: center; color: #7FDBFF" >Hello Plotly.js supports over 35 chart types and renders charts in both vector- quality� Controlling text fontsize with uniformtext¶. For the pie, bar, sunburst and treemap traces, it is possible to force all the text labels to have the same size thanks to the uniformtext layout parameter.

You can prevent the y-axis from being cutoff in your third chart by changing the margins of the figure. Add the following code to the inside of the call to go.Layout():

margin=go.layout.Margin(
        l=150, # left margin, in px
        r=80, # right margin, in px
        t=80, # top margin, in px
        b=80, # bottom margin, in px
        pad=0
        )

You can adjust the left margin for different y-axis labels, or you could set it to automatically scale with the length of the longest label.

How to manage the layout of division/figures in dash - Dash, Assume I have a code below: def charts(): data = [go.Bar( the layout for the division/graphs in a dashboard made by dash-plotly in python. I'm trying to create a plotly graph with a Scatter and Graph elements. It all goes nicely, but one issue - the two Y axis don't align around 0. I have tried playing with different attributes, such as 'mirror' and tick0, I also tried following the examples on plotly's site, but it's mostly multiple y-axis with the same graph type.

You can pass text into go.Bar(), where you can set textposition="inside" and insidetextanchor="start", which should solve this issue.

fig = go.Figure(go.Bar(
            x=[20, 14, 23],
            y=['giraffes', 'orangutans', 'monkeys'],
            orientation='h',
            # define the annotations
            text=['giraffes', 'orangutans', 'monkeys'],
            # position, "auto", "inside" or "outside"
            textposition="auto",
            # anchor could be "start" or "end"
            insidetextanchor="start",
            insidetextfont=dict(family='Times', size=13, color='white'),
            outsidetextfont=dict(family='Times', size=13, color='white')))
fig.update_layout(
    yaxis=dict(
        showticklabels=False,
    ))
fig.show()

How to align text left on a plotly bar chart (example image contained), How to align text left on a plotly bar chart (example image contained) [Plotly-Dash ]. I need my y-axis to be on the inside like the image below� I would like to change the position of the hover box in a plotly bar chart. Rather than have it popup on the left or right, I would like it to popup above the bar. Is this possible? I've been googling this and staring at the Plotly R reference page for a couple hours with no luck. Here's a sample:

Single-Page Reference | Python, An example of this would be layout.xaxis.range , which may be specified The scatter trace type encompasses line charts, scatter charts, text charts, and bubble This anchor binds the `x` position to the "left", "center" or "right" of the color bar. (at https://chart-studio.plotly.com or on-premise) generates images on a server, � Customize Displayed Text with a Text Template. To show an arbitrary text in your chart you can use texttemplate, which is a template string used for rendering the information, and will override textinfo. This template string can include variables in %{variable} format, numbers in d3-format's syntax, and date in d3-time-fomrat's syntax.

Dropdown Menus | Python, How to add dropdowns to update Plotly chart attributes in Python. This example demonstrates how to update a single data attribute: chart type with the dict(text="colorscale", x=0, xref="paper", y=1.06, yref="paper", align="left", in a Dash application by passing it to the figure argument of the Graph component from the� Selecting a hovermode in a figure created with plotly.graph_objects¶ The hovermode is a property of the figure layout, so you can select a hovermode no matter how you created the figure, either with plotly.express or with plotly.graph_objects. Below is an example with a figure created with plotly.graph_objects.

plotly.graph_objects.Waterfall — 4.9.0 documentation, constraintext – Constrain the size of text inside or outside a bar to be no contained in tag <extra> is displayed in the secondary box, for example Sets the horizontal alignment of the text content within hover label box. ['left', 'right', ' auto'] (at https://chart-studio.plotly.com or on-premise) generates images on a server,� What I want is a stacked bar chart of of field first. It will have a height of 8 broken down by 2 police, 2 x research etc. Then I want a stacked bar chart of Issue next to the first chart. This second one will have a height of 8 and be stacked by 2 x budget cuts, 1 x time consuming, 1 x lack of oversight etc. I have tried:

Comments
  • Can you provide minimal code that draws the problematic bar plot?
  • @InonPeled Done. cheers.
  • How is variable "html" defined?
  • Wow that's interesting, thanks. Do you know of a quicker way of looping through the labels to do the annotations by any chance?
  • Thanks, I used x=0 and xref='paper' to align all text vertically. These bar charts are connected to a drop-down which contains certain topics. If I select a topic which doesn't have India for example, the annotation for India still appears on the page but the chart doesn't. The annotation appears between the gaps of the other bars. Do you know a fix around this by any chance?