Subplots with grouped bar charts - small lines and excessive spacing

Have been struggling with this for quite some time. I am a plotly (and python) amateur. I am trying to create subplots with grouped bar charts comparing categorical data (K-12 school testing data by ethnicity and status for comparable schools). Things are plotting, but the traces are so small, the subplots are unusable. There are 6 subplots, which all look like this:

tmp

I’m positive there is a better and more plotly and pythonic way to do this, but for the life of me, I cannot figure it out. Any suggestions would be appreciated! Note that I’ve hardcoded a lot of variables in the code that will actually be set by user selections using Dash. β€˜Working’ code:

import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots

# Actual file has thousands of rows and 500+ columns
all = pd.read_csv('https://raw.githubusercontent.com/jbetley/jbetley/main/test3-data.csv', dtype=str)

# Set using Dash components
school = ['1001']
comparable = ['5001','5002','5003','5004']
ethnicity = ['American Indian','Asian','Black','Hispanic','Multiracial','Native Hawaiian or Other Pacific Islander','White']
status = ['Special Education','General Education','Paid Meals','Free/Reduced Price Meals','English Language Learners','Non-English Language Learners']
subject = ['ELA', 'Math','ELA & Math']

schools = school + comparable

fig = make_subplots(
    rows=2, cols=3
)

num_plots = 1

for p in range(1,3):

    if p == 1:
        category = ethnicity.copy()
    else:
        category = status.copy()

    for s in subject:

        c = 1 if num_plots in [1,4] else 2 if num_plots in [2,5] else 3
        r = 1 if num_plots in [1,2,3] else 2

        for index, item in enumerate(category):
            val = item + "|" + s + " Proficient %"
        
            for school in schools:
                
                # '***' = insufficient n-size
                # way to display this visually on graph somehow? text but no bar?
                if all.loc[(all['School ID'] == school)][val].values[0] == '***': 
                    proficiency = 0
                else:
                    proficiency = float(all.loc[(all['School ID'] == school)][val].values[0])

                fig.add_trace(go.Bar(
                            x=[item],
                            y=[proficiency],
                            customdata=[all.loc[(all['School ID'] == school)]['School Name'].values[0]],
                            hovertemplate = "%{customdata} Proficiency: %{y:.1%}<extra></extra>",
                            showlegend=False,
                        ),
                        row = r, col = c
                    )

            fig.update_yaxes(range=[0, 1], dtick=0.2, tickformat=',.0%')
            fig.update_xaxes(type='category')

        num_plots+=1

fig.update_layout(
    font = dict(
        family='Helvetica',
        color='steelblue',
        size=10
        ),
    )
fig.show()

After re-reading my post, I realized my goal may not be entirely clear. I have a data file with thousands of schools (rows). Each school has ~500 data points (columns).

One of the charts I am attempting to graph is a comparison between five schools of test proficiency in a single subject (eg, math) for each ethnic subgroup.

An example of a single category would be black Math proficiency. So I need 5 grouped bars showing the black Math proficiency (a percentage) for each school. The next bar group would be white Math proficiency, then hispanic Math proficiency, and so on.

The next subplot would be English by ethnicity and the next subplot would be combined Math & English by ethnicity. There are 6 ethnicity categories for each subject. So 30 bars total for each subplot (6 categories x 5 schools).

There will be six subplots total.

Hopefully this makes it clearer. I think I’ve made some inroads using express, but I’m not totally there yet.