12How many people attend our classes and performances?
Total attendance across classes, performances/events, and community gatherings, by fiscal year, with what those attendees paid in tickets and class fees. Attendance counts people — each registration’s ticket records — rather than registration counts (about 1.7 people per registration); the fiscal year runs July–June and is labeled by its ending year. See Methodology for the event categories, the headcount definition, and the cross-cutting fundraiser / youth / film flags. Class-taking households specifically are profiled in Who takes classes at Hubbard Hall?.
Code
import pandas as pdimport plotly.express as pxfrom hh.io import read_parquetfrom hh.viz import style, BLUEregs = read_parquet("processed", "registrations_enriched.parquet")from hh.analytics.attendance import attendance_by_fyfrom hh.analytics.mailing import fiscal_yeartab = attendance_by_fy(regs)current_fy =int(fiscal_year(pd.Series(pd.Timestamp.today()))[0])complete = tab.loc[tab.index < current_fy] # the current FY is partialCATS = ["classes", "performances_events", "community"]LABEL = {"classes": "Classes", "performances_events": "Performances & events","community": "Community"}
Code
attendees = complete[[f"{c}_att"for c in CATS]].astype(int)attendees["Total"] = attendees.sum(axis=1)attendees.columns = [*map(LABEL.get, CATS), "Total"]attendees.index = [f"FY{fy -2000}"for fy in attendees.index]attendees.index.name ="Fiscal year"ytd =int(tab.loc[current_fy, "total_att"])attendees
Table 12.1
Classes
Performances & events
Community
Total
Fiscal year
FY14
596
2459
100
3155
FY15
1209
2818
335
4362
FY16
1364
2832
314
4510
FY17
1766
2678
308
4752
FY18
2473
2948
221
5642
FY19
2705
1603
276
4584
FY20
1388
1283
192
2863
FY21
390
645
41
1076
FY22
1032
763
58
1853
FY23
2207
1661
0
3868
FY24
2212
1214
67
3493
FY25
1246
2221
134
3601
FY26
1071
2589
150
3810
FY27 attendance is year-to-date as of the latest data pull and will rise as the year fills out (1,021 attendees so far).
Code
long= (complete[[f"{c}_att"for c in CATS]] .rename(columns={f"{c}_att": LABEL[c] for c in CATS}) .reset_index() .melt(id_vars="fy", var_name="Category", value_name="Attendees"))long["FY"] =long["fy"].map(lambda y: f"FY{y -2000}")fig = px.bar(long, x="FY", y="Attendees", color="Category", category_orders={"Category": [LABEL[c] for c in CATS]}, color_discrete_sequence=[BLUE, "#b3cde3", "#f0e9d8"])style(fig).show()
Figure 12.1
Code
revenue = complete[[f"{c}_rev"for c in CATS]].round(0)revenue["Total"] = complete["total_rev"].round(0)revenue.columns = [*map(LABEL.get, CATS), "Total"]revenue.index = [f"FY{fy -2000}"for fy in revenue.index]revenue.index.name ="Fiscal year"revenue.style.format("${:,.0f}")
Table 12.2
Classes
Performances & events
Community
Total
Fiscal year
FY14
$65,871
$42,229
$3,755
$111,855
FY15
$97,202
$71,070
$8,255
$176,526
FY16
$92,445
$69,972
$8,072
$170,489
FY17
$96,018
$70,520
$5,730
$172,269
FY18
$115,593
$89,730
$6,589
$211,911
FY19
$109,800
$54,277
$3,863
$167,940
FY20
$84,025
$37,548
$2,660
$124,234
FY21
$43,043
$17,335
$410
$60,788
FY22
$46,940
$16,985
$0
$63,925
FY23
$79,094
$36,195
$0
$115,289
FY24
$91,515
$26,406
$780
$118,701
FY25
$97,375
$66,141
$1,937
$165,453
FY26
$97,215
$81,782
$2,241
$181,238
Notes on these figures:
Attendees are people, not registrations — a family of four on one registration counts as four. Only attendees whose ticket status is SUCCEEDED are counted, so refunded canceled sections contribute nobody.
Dollars are registration revenue as recorded in Neon — ticket and class fees only, not donations, and gross: a canceled section keeps its refunded amounts (under $2.5k in the latest complete year).
A small share of attendance (363 attendees and $7,571 in FY26) is booked to Neon’s internal house accounts — real walk-up tickets, included here but attached to no household.
FY20–FY22 cover the pandemic period and its reopening.
Events carry cross-cutting flags alongside their category — fundraiser, youth program, and film — so, for example, a concert that is also a fundraiser can be counted either way; those flags do not change the category totals above.