# Updating width between bars in go.Bar()

**URL:** <https://community.plotly.com/t/updating-width-between-bars-in-go-bar/87460>\
**Category:** 📊 Plotly Python\
**Created:** [September 21, 2024, 10:31pm UTC](https://community.plotly.com/t/updating-width-between-bars-in-go-bar/87460 "2024-09-21T22:31:09Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![plotmaster422](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/plotmaster422/32/22680_2.png) [@plotmaster422](https://community.plotly.com/u/plotmaster422)\
**Post date:** [September 21, 2024, 10:31pm UTC](https://community.plotly.com/t/updating-width-between-bars-in-go-bar/87460/1 "2024-09-21T22:31:09Z")

</div>

I am creating barcharts sliced by two categorical variables. The space between the bar groupings is much wider than the space from the bar groupings to the edges of the plot [fig1].

I understand it’s possible to increase the space from bar grouping to edge of plot [fig2], but is there a way to rather reduce this gap between bar groupings instead? This would provide more visual consistency between charts of a different number of groupings.

 ![narrow_gap](https://us1.discourse-cdn.com/flex024/uploads/plot/original/3X/a/7/a7981ec1e8e2c03f44becb84a517bb64fd903ad5.png)

[^fig1, narrow gap]

* * *

 ![wide_gap](https://us1.discourse-cdn.com/flex024/uploads/plot/original/3X/6/b/6b86a369c5d89e9f404b135f489f9302e5f7c714.png)

[^fig2, wide gap]

alternatively, is there any way to manually set the bar width, regardless of how many groupings, so that there is consistency in subplots?

TIA!

---

<div class="post-metadata">

**Author:** ![AIMPED](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/aimped/32/21758_2.png) [@AIMPED](https://community.plotly.com/u/AIMPED)\
**Post date:** [September 23, 2024, 10:58am UTC](https://community.plotly.com/t/updating-width-between-bars-in-go-bar/87460/2 "2024-09-23T10:58:57Z")

</div>

I think this might be related to this:

> [@Unstacking grouped plot creates huge gap between groups. PlotlyExpress](https://community.plotly.com/t/unstacking-grouped-plot-creates-huge-gap-between-groups-plotlyexpress/69698):
>
> Hey peeps! As you can see from the first image my plot is nice and readable, but i’d like to unstack these to be able to easier seperate things. But when i do the gap between the groups becomes huge, i’ve tried searching the forums and google but i’m not able to find any result… I have tried bargap and bargroupgap without any difference, both in “update\_layout” and directly in the plot. with barmod=‘group’ df = pd.read\_parquet("parquets/df.parquet") fig = px.bar(d…

Concerning manual bar\_width:

> [@How to limit bar width with time-series axis](https://community.plotly.com/t/how-to-limit-bar-width-with-time-series-axis/76766/2):
>
> Hi @vvv. I can’t reproduce this: import plotly.graph\_objects as go data = [0, 1, 2, None, 3, None, None, 8] fig = go.Figure(data=go.Bar(y=data)) fig.show() [newplot (11)]

I remember responding to quite some topics concerning bar with, a quick forum search:  
[https://community.plotly.com/search?q=bar\_width%20%40aimped](https://community.plotly.com/search?q=bar_width%20%40aimped)

---

<div class="post-metadata">

**Author:** ![plotmaster422](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/plotmaster422/32/22680_2.png) [@plotmaster422](https://community.plotly.com/u/plotmaster422)\
**Post date:** [September 29, 2024, 1:47am UTC](https://community.plotly.com/t/updating-width-between-bars-in-go-bar/87460/3 "2024-09-29T01:47:09Z")

</div>

Got it, so it has to do with plotly creating space for bars on the back-end side of the equation. Noted.

Just looking above at my two figs it’s interesting that it doesn’t do that for “conversion”, but does for all other graphs [see fig1]. Perhaps I can supply code and you’d be willing to take a look?

TIA!

---

<div class="post-metadata">

**Author:** ![AIMPED](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/aimped/32/21758_2.png) [@AIMPED](https://community.plotly.com/u/AIMPED)\
**Post date:** [September 30, 2024, 6:14am UTC](https://community.plotly.com/t/updating-width-between-bars-in-go-bar/87460/4 "2024-09-30T06:14:09Z")

</div>

@plotmaster422 sure

---

<div class="post-metadata">

**Author:** ![plotmaster422](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/plotmaster422/32/22680_2.png) [@plotmaster422](https://community.plotly.com/u/plotmaster422)\
**Post date:** [September 30, 2024, 1:31pm UTC](https://community.plotly.com/t/updating-width-between-bars-in-go-bar/87460/5 "2024-09-30T13:31:30Z")

</div>

Here is the code. Any workarounds for normalizing the width between bars would be greatly appreciated!

* * *

```auto
def bar_cat_overview__slice_by_categorical(df, categoricals, sliceable, dep, max_cols=4, height=700, bargap=1):

    print(f"Categorical variables are {categoricals}, dependent variable is [{dep}]")

    df = df[categoricals].merge(df[dep], how='outer', left_index=True, right_index=True)
    
    max_rows=ceil(float(len(df.columns))/max_cols)
    
    fig = make_subplots(
        rows=max_rows,
        cols=max_cols,
        subplot_titles=df.drop([sliceable], axis=1).columns).update_layout(
        {"title":f"bars of features, slice by {sliceable}"})
    
    col_cyc = cycle(iter(range(1,max_cols+1)))
    color_list = cycle(iter(px.colors.qualitative.T10[:len(df[sliceable].unique())]))
    
    row=1
    ctr=0

    for j in df.drop([sliceable], axis=1).columns:
        col = next(col_cyc)
        for attr1 in df[j].unique():
            if ctr < 1:
                for attr2 in df[sliceable].unique():
                    fig.add_bar(
                        x = [attr1],
                        y = [df[j][(df[j]==attr1) & (df[sliceable]==attr2)].count()],
                        row=row,
                        col=col,
                        marker={"color": next(color_list)},         
                        name=str(attr2),
                        showlegend=True
                        )
            else:
                for attr2 in df[sliceable].unique():
                    fig.add_bar(
                        x = [attr1],
                        y = [df[j][(df[j]==attr1) & (df[sliceable]==attr2)].count()],
                        row=row,
                        col=col,
                        marker={"color": next(color_list)},         
                        name=str(attr2),
                        showlegend=False
                        )
            ctr+=1

        if col % max_cols == 0:
            row+=1
        col+=1
    return fig.update_layout({"height": height,
                              "barcornerradius": 1,
                              "bargap": bargap,
                              "barmode":"group",
                              "legend": {"title": sliceable}
                             })
        
bar_cat_overview__slice_by_categorical(digital_og, categoricals=categoricals, sliceable="CampaignType", dep="Conversion", max_cols=3, height=800, 
                                       bargap=0.8
                                      )

```

* * *

---

<div class="post-metadata">

**Author:** ![AIMPED](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/aimped/32/21758_2.png) [@AIMPED](https://community.plotly.com/u/AIMPED)\
**Post date:** [October 1, 2024, 5:39am UTC](https://community.plotly.com/t/updating-width-between-bars-in-go-bar/87460/6 "2024-10-01T05:39:21Z")

</div>

could you post a reproducible example?

---

<div class="post-metadata">

**Author:** ![plotmaster422](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/plotmaster422/32/22680_2.png) [@plotmaster422](https://community.plotly.com/u/plotmaster422)\
**Post date:** [October 2, 2024, 6:37pm UTC](https://community.plotly.com/t/updating-width-between-bars-in-go-bar/87460/7 "2024-10-02T18:37:00Z")

</div>

Here you go [apologies for the long function, subplots are dynamic based on df size]:

```auto
import plotly.express as px
import plotly.graph_objs as go
from plotly.subplots import make_subplots
from plotly.offline import *

from math import ceil
from itertools import cycle

def bar_cat_overview__slice_by_categorical(df, categoricals, sliceable, max_cols=4, height=700, bargap=1):
    
    print(f"Categorical variables are {categoricals}")

    max_rows=ceil(float(len(df.columns))/max_cols)
    
    fig = make_subplots(
        rows=max_rows,
        cols=max_cols,
        subplot_titles=df.drop([sliceable], axis=1).columns).update_layout(
        {"title":f"bars of features, slice by {sliceable}"})
    
    col_cyc = cycle(iter(range(1,max_cols+1)))
    color_list = cycle(iter(px.colors.qualitative.T10[:len(df[sliceable].unique())]))
    
    row=1
    ctr=0

    for j in df.drop([sliceable], axis=1).columns:
        col = next(col_cyc)
        for attr1 in df[j].unique():
            if ctr < 1:
                for attr2 in df[sliceable].unique():
                    fig.add_bar(
                        x = [attr1],
                        y = [df[j][(df[j]==attr1) & (df[sliceable]==attr2)].count()],
                        row=row,
                        col=col,
                        marker={"color": next(color_list)},         
                        name=str(attr2),
                        showlegend=True
                        )
            else:
                for attr2 in df[sliceable].unique():
                    fig.add_bar(
                        x = [attr1],
                        y = [df[j][(df[j]==attr1) & (df[sliceable]==attr2)].count()],
                        row=row,
                        col=col,
                        marker={"color": next(color_list)},         
                        name=str(attr2),
                        showlegend=False
                        )
            ctr+=1

        if col % max_cols == 0:
            row+=1
        col+=1
    return fig.update_layout({"height": height,
                              "barcornerradius": 1,
                              "bargap": bargap,
                              "barmode":"group",
                              "legend": {"title": sliceable}
                             })
        
fig = bar_cat_overview__slice_by_categorical(df, categoricals=categoricals, sliceable="A", max_cols=3, height=400, 
                                       bargap=0.8
                                      )
fig

```

copy paste this dataframe and hit go:

```auto
import pandas as pd
import numpy as np

df = pd.DataFrame({
    "A": ["awareness", "retention", "retention", "retention", "awareness", "converison"],
    "B": ["social", "email", "referral", "notification", "PPC", "SEO"],
    "C": ["male", "female", "male", "female", "male", "female"],
    "D": ["confidential", "confidential", "confidential", "confidential", "confidential", "confidential"],
    "E" : [0, 0, 0, 0, 0, 1],

})

categoricals = ["A", "B", "C", "D"]

df

```

see how the widths of the bar are far too narrow? I would like the bar widths to be consistent.

TIA!

---

<div class="post-metadata">

**Author:** ![AIMPED](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/aimped/32/21758_2.png) [@AIMPED](https://community.plotly.com/u/AIMPED)\
**Post date:** [October 7, 2024, 8:59pm UTC](https://community.plotly.com/t/updating-width-between-bars-in-go-bar/87460/8 "2024-10-07T20:59:19Z")

</div>

Yes, I see the problem. As I mentioned already, I do not think there is a built in way to do what you are after. Unfortunately I do not have the time to come up with a fully customized plot for your data, but maybe someone else here on the forums does 🙂

---

<div class="post-metadata">

**Author:** ![plotmaster422](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/plotmaster422/32/22680_2.png) [@plotmaster422](https://community.plotly.com/u/plotmaster422)\
**Post date:** [October 7, 2024, 11:36pm UTC](https://community.plotly.com/t/updating-width-between-bars-in-go-bar/87460/9 "2024-10-07T23:36:42Z")

</div>

no worries, these are more EA graphs than something front-end ready. Thanks for the response!
