Unstacking grouped plot creates huge gap between groups. PlotlyExpress

Hi @Mauz a small follow up. I tried to omit the gaps using plotly.graph_objects. I admit, that this solution is quite laborious and far from perfect but it might work as a stating point for you.

import plotly.graph_objects as go
from plotly.subplots import make_subplots
import pandas as pd
import plotly.express as px
import numpy as np

# set number of categories
cat_num = 5

# set number of types
type_num = 20

# create data
categories = []
for i in range(1, cat_num + 1):
    categories.extend([f'category_{i}'] * type_num)

types = [f'type_{i}' for i in range(type_num)] * cat_num    

values = np.random.randint(1, 40, cat_num * type_num)    

# create DataFrame
df = pd.DataFrame({'categories': categories, 'values': values, 'types': types})

# delete some rows from the DataFrame so that category_1 has fewer "types"
df = df.drop(range(1,15))

# groupby categories
gb = df.groupby('categories')

# create base figure
fig = make_subplots(
    rows=cat_num, 
    cols=1,
    shared_xaxes=True, 
    shared_yaxes=False,
    vertical_spacing=0.05
)

# create a lookup so that each "type" gets always the same color
color_code = {t: c for t,c in zip(df.types.unique(), px.colors.qualitative.Alphabet)}

for idx, name_group in enumerate(gb, start=1):
    name, group = name_group
    
    # map colors to existing "types"
    colors = [color_code[t] for t in group['types']]
    
    # append traces to figure
    fig.append_trace(
        go.Bar(
            y=group['types'], 
            x=group['values'],
            orientation='h',
            marker_color=colors,
            name=name,
        ),
        row=idx,
        col=1
    )

# create y-axis titles, start from 1 due to internal subplots row numbering
for idx, name_group in enumerate(gb, start=1):
    name, group = name_group
    fig.update_yaxes(title_text=name, row=idx, col=1)

# do not show traces in legend, hide ticklabels, set height
fig.update_traces(showlegend=False)
fig.update_yaxes(showticklabels=False)        
fig.update_layout(height=600)
fig.show()

which produces: