Display text outside of a trace not working

83 Views Asked by At

I am trying to display percentages outside of the bottom (dark orange) trace on my graph.

Here is my code:

bar2 = go.Figure()
bar2.add_trace(go.Bar(name = 'Halted Trials', 
                     x = bar2_df['Condition'],
                     y = bar2_df['Halted'],
                      text = bar2_df['Percent'],
                      texttemplate = "%{text:.2f}%<br>",
                      textposition = 'outside',
                     marker = dict(color = 'rgb(252, 141, 98)'),
                    ))
bar2.add_trace(go.Bar(name = 'Total Trials', 
                     x = bar2_df['Condition'],
                     y = bar2_df['Total'],
                     marker = dict(color = 'rgb(252, 200, 179)'),
                    ))

bar2.update_layout(barmode = 'stack',
                  yaxis_title = 'Clinical Trials',
                  width = 1000,
                  height = 1000,
                  margin = dict(l = 0, r = 0, t = 0, b = 0, pad = 0),                  
                  legend = dict(
                      orientation = 'h',
                      yanchor = 'bottom',
                      y = -.3,
                      xanchor = 'center',
                      x= .5),
                  plot_bgcolor = 'white',
                  )

Here is the graph generated by the above code: enter image description here

I have tried setting textposition = 'outside', but setting it as both 'inside' or 'outside' displays the same result -- the text is on the inside of the trace. Is there something I'm missing?

update: Their documentation explains why this is happening.

textposition
Code: fig.update_traces(textposition=<VALUE>, selector=dict(type='bar'))
Type: enumerated or array of enumerateds , one of ( "inside" | "outside" | "auto" | "none" )
Default: "auto"
Specifies the location of the text.
"inside" positions text inside, next to the bar end (rotated and scaled if needed).
"outside" positions text outside, next to the bar end (scaled if needed), unless there is another bar stacked on this one, then the text gets pushed inside.
"auto" tries to position text inside the bar, but if the bar is too small and no bar is stacked on this one the text is moved outside.
If "none", no text appears.

My next question -- how can I modify the code to create my desired output?

1

There are 1 best solutions below

0
On

I ended up solving this by referring to this stack overflow post, creating annotations based on the individual y value of each bar.

Here is my resultant code:

halt_cond = pd.DataFrame()
halted_counts = halt_df.groupby('Condition').size().reset_index(name = 'Halted')
total_counts = clin_trials.groupby('Condition').size().reset_index(name = 'Total')
halt_cond = pd.merge(halted_counts, total_counts, on='Condition', how = 'outer')
halt_cond.fillna(0, inplace=True)
halt_cond['Percent'] = (halt_cond['Halted']/halt_cond['Total']).map('{:.2%}'.format)

# create the dataframe of top 10 conditions
bar2_df = halt_cond.sort_values(by = 'Total', ascending = False).head(10)

# create the list for text annotations
xi = bar2_df['Condition']
yi = bar2_df['Halted']
annoText = bar2_df['Percent']
annotationsDict = [dict(
    x = xcoord,
    y = ycoord + 20,
    text = annoText,
    showarrow = False,
) for xcoord, ycoord, annoText in zip(xi, yi, annoText)]


bar2 = go.Figure()
bar2.add_trace(go.Bar(name = 'Halted Trials', 
                     x = bar2_df['Condition'],
                     y = bar2_df['Halted'],
                     marker = dict(color = 'rgb(252, 141, 98)'),
                    ))
bar2.add_trace(go.Bar(name = 'Total Trials', 
                     x = bar2_df['Condition'],
                     y = bar2_df['Total'],
                     marker = dict(color = 'rgb(252, 200, 179)'),
                    ))

bar2.update_layout(barmode = 'stack',
                  yaxis_title = 'Clinical Trials',
                  width = 1000,
                  height = 1000,
                  margin = dict(l = 0, r = 0, t = 0, b = 0, pad = 0),
                  legend = dict(
                      orientation = 'h',
                      yanchor = 'bottom',
                      y = -.3,
                      xanchor = 'center',
                      x= .5),
                   annotations = annotationsDict,
                   plot_bgcolor = 'white'
                  )