Case Study 1: Redesigning a Government Report for Accessibility
Tier 3 — Illustrative/Composite Example: This case study follows Dana, a data analyst at the fictional Department of Public Health for the state of "Northfield." The original report, its charts, its accessibility failures, and all redesigns are fictional composites inspired by common patterns in government health publications. All data values, department structures, and specific accessibility complaints are illustrative. The accessibility guidelines referenced (WCAG, Section 508) are real standards.
The Setting
Dana has been at the Northfield Department of Public Health for two years. Every quarter, the department publishes a "Community Health Report" — a 30-page PDF distributed to county health officers, state legislators, community organizations, and the general public. The report includes eight charts created by Dana's predecessor in Excel.
Three weeks ago, Dana received an email from the state's Disability Rights Commission:
"We have reviewed the Q3 2024 Community Health Report and found that several charts are inaccessible to people with visual disabilities. Specifically: (1) charts rely on red-green color distinctions, (2) no alt text is provided for any chart, (3) several charts have low-contrast text, and (4) data tables are not provided as an alternative to visual charts. Please address these issues in the Q4 report."
Dana's director asks her to redesign all eight charts. Dana decides to tackle the three worst offenders first and use them as templates for the remaining five.
Chart 1: The Red-Green Vaccination Map
The Original
The original chart is a county map of Northfield showing childhood vaccination rates. Counties meeting the 90% target are colored green. Counties below the target are colored red. There is no legend explaining the threshold, no data table, and no alt text.
Dana looks at the chart through a deuteranopia simulator. The result: every county appears the same yellowish-brown color. The entire purpose of the chart — showing which counties meet the target — is invisible to roughly 8% of male viewers.
The Problems
- Red-green encoding. The most common form of color vision deficiency renders this chart completely uninformative.
- Binary coloring hides nuance. A county at 89% (just below target) looks identical to one at 60% (a crisis). A county at 91% (barely meeting target) looks identical to one at 99% (excellent).
- No legend. New readers do not know what the colors mean or what the threshold is.
- No alt text. Screen reader users receive no information.
- No data table. The underlying numbers are not available to anyone who cannot process the visual.
The Redesign
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
# Use a sequential colormap instead of binary
fig, ax = plt.subplots(figsize=(10, 7))
# Scatter plot of county centroids (simplified
# from actual choropleth for illustration)
scatter = ax.scatter(
counties["longitude"],
counties["latitude"],
c=counties["vaccination_rate"],
cmap="YlGnBu",
s=counties["population"] / 50,
edgecolors="gray", linewidth=0.5,
vmin=60, vmax=100
)
# Add 90% threshold annotation
cbar = plt.colorbar(scatter, ax=ax,
label="Vaccination Rate (%)")
# Add a marker at 90% on the colorbar
cbar.ax.axhline(y=90, color="black",
linewidth=2, linestyle="--")
cbar.ax.text(1.5, 90, "90% target",
fontsize=9, va="center")
# Mark below-target counties with a symbol
below = counties[counties["vaccination_rate"] < 90]
ax.scatter(below["longitude"], below["latitude"],
marker="v", s=15, color="black",
zorder=5, label="Below 90% target")
ax.set_title("Childhood Vaccination Rates by "
"County\nNorthfield, Q4 2024",
fontsize=13, pad=12)
ax.legend(loc="lower right", fontsize=9)
ax.set_xticklabels([])
ax.set_yticklabels([])
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
plt.tight_layout()
What Changed
-
Sequential colormap (
"YlGnBu") replaces the red-green binary. This palette varies in both hue and luminance, making it distinguishable even in grayscale. The continuous scale shows the full range of vaccination rates, not just above/below. -
Redundant encoding. Counties below the 90% target get a downward-pointing triangle marker in addition to their lighter color. Even if a viewer cannot distinguish the exact color, the triangle signals "below target."
-
Clear legend and colorbar. The colorbar shows the full 60-100% range with a dashed line at the 90% target. The legend explains the triangle marker.
-
Alt text (added in the report):
"Map of vaccination rates by county in Northfield, Q4 2024. Colors range from yellow (low, around 60%) to dark blue (high, around 100%). A dashed line on the color scale marks the 90% target. Seven counties fall below the target, indicated by downward-pointing triangle markers. The lowest rate is in Harper County at 63%. The highest is in Lake County at 98%. Most counties in the central region meet the target; the counties below target are concentrated in the southern and western rural areas."
-
Data table provided alongside the chart in the report, listing every county's rate, population, and whether it meets the target.
Chart 2: The Low-Contrast Trend Lines
The Original
The original shows five chronic disease rates over 10 years, plotted as thin (1-pixel) lines on a white background. The lines are colored light blue, light green, light orange, light purple, and light gray. The legend text is 8-point font in medium gray on white. The axis labels are similarly faint.
The Problems
- Low contrast. The lightest lines (light gray, light yellow) are nearly invisible. The contrast ratio of the legend text against the white background is approximately 2:1, well below the WCAG AA minimum of 4.5:1.
- Thin lines. At 1 pixel wide, the lines are hard to see for anyone with less-than-perfect vision.
- Legend matching. With five similar-lightness colors, matching each line to its legend entry requires strenuous back-and-forth eye movement.
- No key finding. The title says "Chronic Disease Trends" — but what should the reader take away?
The Redesign
fig, ax = plt.subplots(figsize=(10, 5))
diseases = ["Diabetes", "Heart Disease",
"Hypertension", "Asthma", "Obesity"]
colors = ["#E69F00", "#56B4E9", "#009E73",
"#CC79A7", "#0072B2"]
# Colorblind-safe palette (Okabe-Ito)
for i, disease in enumerate(diseases):
subset = trend_df[trend_df["disease"] == disease]
ax.plot(subset["year"], subset["rate"],
color=colors[i], linewidth=2.5,
marker="o", markersize=5)
# Direct label at end of each line
last = subset.iloc[-1]
ax.text(last["year"] + 0.3, last["rate"],
disease, fontsize=10,
color=colors[i], fontweight="bold",
va="center")
ax.set_title("Obesity Rate Has Doubled While "
"Heart Disease Declined\n"
"Northfield Chronic Disease Trends, "
"2014-2024",
fontsize=12, pad=10)
ax.set_xlabel("Year", fontsize=11)
ax.set_ylabel("Rate per 1,000 Adults", fontsize=11)
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
ax.tick_params(labelsize=10)
# Remove legend — direct labels replace it
plt.tight_layout()
What Changed
- Colorblind-safe palette (Okabe-Ito palette, widely recommended). These colors are distinct for all common forms of color vision deficiency.
- Thicker lines (2.5 points) with markers at each data point. Visible at any screen size.
- Direct labels at the end of each line. No legend needed — the viewer does not have to match colors between the legend and the chart.
- Finding in the title. "Obesity Rate Has Doubled While Heart Disease Declined" tells the reader what to look for. The subtitle provides context.
- Larger fonts throughout (10-12 point for labels and annotations, up from 8 point).
Chart 3: The Cluttered Demographic Breakdown
The Original
The original is a 3D pie chart with 12 slices showing the racial/ethnic breakdown of the county's population. Each slice has a gradient fill. The smallest slices (under 3%) are labeled with text that overlaps the adjacent slices. The chart has a drop shadow and sits on a textured background.
The Problems
- 3D effect distorts slice angles, making front slices appear larger than back slices.
- 12 slices — far too many for a pie chart. The smallest slices are indistinguishable.
- Gradient fills add visual complexity without encoding data.
- Overlapping labels make several categories unreadable.
- Drop shadow and textured background are chartjunk.
- Pie chart is wrong for this data. With 12 categories spanning a 1%-35% range, bar charts are far more appropriate.
The Redesign
# Sort by rate, show top 6, group rest as "Other"
demo = demo_df.sort_values("percentage",
ascending=False)
top6 = demo.head(6)
other_pct = demo.iloc[6:]["percentage"].sum()
other_row = pd.DataFrame({
"group": ["Other (6 groups combined)"],
"percentage": [other_pct]
})
plot_df = pd.concat([top6, other_row])
plot_df = plot_df.sort_values("percentage")
fig, ax = plt.subplots(figsize=(8, 5))
bars = ax.barh(plot_df["group"],
plot_df["percentage"],
color="#4d96ff", height=0.6)
# Add value labels
for bar in bars:
width = bar.get_width()
ax.text(width + 0.5, bar.get_y() + 0.3,
f"{width:.1f}%", va="center",
fontsize=10)
ax.set_xlabel("Percentage of Population",
fontsize=11)
ax.set_title("Population by Race/Ethnicity\n"
"Northfield County, 2024 Census "
"Estimates",
fontsize=12, pad=10)
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
ax.set_xlim(0, max(plot_df["percentage"]) * 1.15)
plt.tight_layout()
What Changed
- Horizontal bar chart replaces the pie chart. Bar length (2nd in Cleveland-McGill hierarchy) replaces angle (4th).
- Seven categories (top 6 + Other) replaces 12. Smaller groups are aggregated with a note.
- Single color for all bars. The variable is race/ethnicity (encoded by bar label), not a second variable that needs color distinction.
- Clean styling. No 3D, no gradients, no shadows, no textured background.
- Value labels on each bar eliminate the need to estimate from the axis.
- Horizontal layout makes category labels readable without rotation.
The Department's Response
Dana presents the three redesigns to her director in a before-and-after format. The director's reaction: "I can actually read these now. Why didn't we do this before?"
Dana submits the redesigned Q4 report to the Disability Rights Commission. Their response acknowledges the improvements and provides two additional recommendations:
- Offer the report as an accessible HTML page (not just PDF) so screen readers can navigate it more easily.
- Consider adding a plain-language summary paragraph for each chart, in addition to the alt text, for readers with cognitive disabilities.
Dana adds both to the Q1 2025 report template.
Pedagogical Reflection
This case study demonstrates the redesign workflow in a real institutional context:
-
Accessibility is not optional. Government reports serve the entire public, including people with disabilities. The Disability Rights Commission's review was not unusual — many organizations face similar audits.
-
Common problems cluster. The three charts shared the same failures: poor color choice, missing alt text, no data tables, cluttered design. Fixing one chart creates a template for fixing all of them.
-
Better design is also simpler. In every case, the redesign had fewer visual elements than the original. Removing chartjunk, reducing categories, and switching chart types made the charts both more accessible and more effective.
-
Alt text requires domain knowledge. Writing good alt text forced Dana to articulate what the chart's key finding was — which sometimes revealed that the original chart did not have a clear finding. The discipline of writing alt text improves chart design.
-
Accessibility is iterative. The Disability Rights Commission's follow-up recommendations (HTML format, plain-language summaries) show that accessibility is not a one-time fix but an ongoing commitment to inclusive communication.