1

Is there a means to control the distance between the stacked bars in the example below, i.e. between the “cat” and “dog” (black arrow) and between “10 minutes” and “30 minutes” (yellow arrow)?

import plotly.graph_objects as go
x = [
    ["10 minutes", "10 minutes", "30 minutes", "30 minutes", "60 minutes", "60 minutes"],
    ["Cat", "Dog", "Cat", "Dog", "Cat", "Dog"]
]
fig = go.Figure()
fig.add_bar(x=x,y=[1,2,3,4,5,6], name="increase")
fig.add_bar(x=x,y=[9,8,7,6,5,4], name="decrease")
fig.add_bar(x=x,y=[5,5,5,5,5,5], name="unchanged")

fig.update_layout(barmode="stack", showlegend=True, template='plotly',
                  #bargap=0.3,
                  bargroupgap=0.2,
                  #height=500,
                  #width=1000,
                 )
fig.update_yaxes(ticks='outside',
                 dtick=2,
                 ticklen=10,
                 linewidth=1,
                 linecolor="black",
                 tickfont=dict(size=20)
                )
fig.update_xaxes(ticks="", tickfont=dict(size=12),                 
                )
fig.show()

gives

Generated plot from code

hans
  • 323
  • 1
  • 14
  • 1
    as with a lot of plotly questions on SO, this will likely need to be solved with some sort of workaround. i would start with trying to place the bars by using actual x values, and then replace the ticks with the intended category like Cat and Dog. i'll circle back to this when i have time later – Derek O May 16 '23 at 02:04

1 Answers1

0

@Derek O Thanks for your suggestions that got me going, in particular this one here https://stackoverflow.com/a/75951042/14672356

Now the stacked bar plot is with error bars and time via annotations.

import plotly.graph_objects as go

y1_values=[5,4,4,5,6,5]
y2_values=[9,8,7,6,5,4]
y3_values=[4,6,7,7,7,9]

y1_errors = [0.5, 0.6, 0.4, 0.7, 0.5, 0.8]
y2_errors = [0.4, 0.3, 0.5, 0.7, 0.3, 0.5]
y3_errors = [0.6, 0.2, 0.3, 0.4, 0.4, 0.4]

fig = go.Figure()
#config = dict({'scrollZoom': True})


# Bars for increase with error bars
fig.add_bar(x=[1,1.5,2.2,2.7,3.4,3.9],y=y3_values, name="Increase", marker_color='#FF6692',
            error_y=dict(type="data", array=y3_errors, thickness=2, width=10),
            base=[sum(x) for x in zip(y1_values, y2_values)]
           )

# Bars for decrease with error bars
fig.add_bar(x=[1,1.5,2.2,2.7,3.4,3.9],y=y2_values, name="Decrease", marker_color='#19D3F3',
            error_y=dict(type="data", array=y2_errors, thickness=2, width=10),
            base=y1_values
           )

# Bars for unchanged with error bars
fig.add_bar(x=[1,1.5,2.2,2.7,3.4,3.9],y=y1_values, name="Unchanged", marker_color='#00CC96',
            error_y=dict(type="data", array=y1_errors, thickness=2, width=10),
            base=[0]*6
           )

# Annotation for bar1 and bar2
fig.add_annotation(text="10 minutes",
                  xref="paper", yref="paper",
                  x=0.07, y=-0.18,
                  showarrow=False,
                  font_size=20
                  )

# Annotation for bar3 and bar4
fig.add_annotation(text="30 minutes",
                  xref="paper", yref="paper",
                  x=0.5, y=-0.18,
                  showarrow=False,
                  font_size=20
                  )

# Annotation for bar5 and bar6
fig.add_annotation(text="60 minutes",
                  xref="paper", yref="paper",
                  x=0.93, y=-0.18,
                  showarrow=False,
                  font_size=20
                  )

# Layout
fig.update_layout(barmode="stack", showlegend=True, template='plotly_white',
                  height=700,
                  width=1000,
                  legend=dict(title='', orientation="h", traceorder='normal', x=0.46, y=1.05,
                  bgcolor='rgba(0,0,0,0)', bordercolor='rgba(0,0,0,1)', borderwidth=0,
                  font_size=20
                             )
                 )

fig.update_yaxes(showline=True, showgrid=False, linewidth=0.5, linecolor='black',
                 title='<b>Percent</b>', titlefont=dict(size=24), title_standoff=30,
                 ticks='outside',
                 dtick=2,
                 ticklen=10,
                 tickfont=dict(size=20),
                 range=[0,20]
                )

fig.update_xaxes(title='', tickvals=[1,1.5,2.2,2.7,3.4,3.9],
                           ticktext=["<b>Cat</b><br>n = 15", "<b>Dog</b><br>n = 15",
                                     "<b>Cat</b><br>n = 15", "<b>Dog</b><br>n = 15",
                                     "<b>Cat</b><br>n = 15", "<b>Dog</b><br>n = 15"],
                           ticks="", tickfont_size=20, linecolor="black", linewidth=1
                ) 

fig.show()

Stacked bar plot with error bars and annotations

hans
  • 323
  • 1
  • 14