Data Visualisation Standards
Data visualisation standards define the rules for representing data graphically across organisational reporting systems. This reference provides lookup tables for chart selection, colour specifications, accessibility requirements, and formatting conventions that apply to all dashboards, reports, and analytical outputs.
Chart Selection
Chart selection depends on the data structure and the analytical question. The following matrix maps data characteristics to appropriate chart types.
By Data Relationship
| Relationship | Data Structure | Primary Chart | Alternatives |
|---|---|---|---|
| Comparison across categories | Categorical × Numeric | Bar chart (horizontal) | Column chart, dot plot |
| Comparison over time | Time series | Line chart | Area chart, column chart |
| Part-to-whole | Categorical × Percentage | Stacked bar (100%) | Treemap, waffle chart |
| Distribution | Single numeric variable | Histogram | Box plot, density plot |
| Correlation | Two numeric variables | Scatter plot | Bubble chart (with third variable) |
| Ranking | Categorical × Numeric (ordered) | Bar chart (sorted) | Lollipop chart, slope chart |
| Flow or process | Source → Destination × Volume | Sankey diagram | Chord diagram |
| Geographic | Location × Numeric | Choropleth map | Bubble map, hex map |
| Hierarchical | Nested categories × Numeric | Treemap | Sunburst, icicle chart |
| Change over time (few categories) | Time × Numeric × 2-5 categories | Multi-line chart | Small multiples |
| Change over time (many categories) | Time × Numeric × 6+ categories | Small multiples | Heatmap |
By Audience and Purpose
| Purpose | Audience | Recommended Approach |
|---|---|---|
| Executive summary | Senior leadership | Single KPI cards, sparklines, 3-5 key metrics maximum |
| Operational monitoring | Programme staff | Real-time gauges, status indicators, exception highlighting |
| Donor reporting | External funders | Clean bar/line charts, clear labels, minimal interactivity |
| Data exploration | Analysts | Interactive filters, drill-down, scatter plots, distributions |
| Public communication | General audience | Simple bar charts, pictograms, infographic style |
| Field teams | Low-bandwidth contexts | Static images, simplified palettes, offline-capable |
Chart Type Specifications
| Chart Type | Maximum Categories | Minimum Data Points | Avoid When |
|---|---|---|---|
| Pie chart | 5 | 2 | Values are similar; precise comparison needed |
| Donut chart | 5 | 2 | Values are similar; more than one ring needed |
| Bar chart (horizontal) | 15 | 1 | Time-based data; continuous values |
| Column chart | 12 | 3 | Labels are long; many categories |
| Line chart | 7 lines | 4 | Comparing exact values; categorical data |
| Area chart | 4 areas | 4 | Overlapping values obscure data |
| Scatter plot | N/A | 10 | Categorical data; few points |
| Histogram | N/A | 30 | Comparing categories; small samples |
| Box plot | 10 | 20 per box | Audience unfamiliar with statistics |
| Treemap | 30 | 3 | Precise comparison needed; small differences |
| Heatmap | 50 × 50 | 3 × 3 | Precise values needed; few cells |
| Choropleth map | N/A | 5 regions | Point data; non-contiguous regions |
Colour Palettes
Colour palettes divide into three functional categories: sequential palettes represent ordered data from low to high, diverging palettes represent data with a meaningful centre point, and categorical palettes distinguish unrelated groups.
Sequential Palettes
Sequential palettes progress from light to dark (or low saturation to high saturation) to represent magnitude. Use these for metrics where higher values have consistent meaning across the dataset.
| Palette Name | Use Case | Hex Values (5 steps) |
|---|---|---|
| Blue sequential | Default for most metrics | #E6F0F5, #A3C4D9, #5A9ABF, #2E6B8A, #0D3B54 |
| Green sequential | Positive outcomes, growth | #E8F4E8, #A8D4A8, #5FB35F, #2E8B2E, #0D5C0D |
| Orange sequential | Attention, warnings | #FFF0E6, #FFD4B3, #FFB380, #E67300, #994D00 |
| Grey sequential | Neutral, background data | #F5F5F5, #D4D4D4, #A3A3A3, #6B6B6B, #333333 |
For continuous data requiring more than 5 steps, interpolate between the provided values. Most BI platforms provide interpolation functions; in Apache Superset, use the LINEAR colour interpolation mode.
Diverging Palettes
Diverging palettes extend outward from a neutral centre point. Use these when data has a meaningful midpoint: zero change, target value, or median. The centre colour should be neutral (white or light grey), with distinct hues extending in each direction.
| Palette Name | Use Case | Below Centre | Centre | Above Centre |
|---|---|---|---|---|
| Red-Blue diverging | Performance vs target | #B22222, #DC6464, #F0F0F0, #6495ED, #1E3A8A | ||
| Brown-Teal diverging | Change from baseline | #8B4513, #C9956C, #F5F5F5, #5F9EA0, #006666 | ||
| Purple-Green diverging | Positive/negative sentiment | #663399, #A385C2, #F0F0F0, #7CB68A, #228B22 |
When using diverging palettes, set the centre point explicitly rather than relying on automatic scaling. A target achievement palette centred on 100% ensures that 80% and 120% receive equal visual weight on opposite sides of the midpoint.
Categorical Palettes
Categorical palettes distinguish unrelated groups without implying order. Colours should be perceptually distinct while maintaining similar saturation and lightness to avoid visual hierarchy.
| Palette Name | Maximum Categories | Hex Values |
|---|---|---|
| Primary categorical | 6 | #2E6B8A, #8B4513, #228B22, #663399, #DC143C, #DAA520 |
| Extended categorical | 10 | Primary + #008B8B, #FF6347, #4682B4, #9ACD32 |
| Muted categorical | 6 | #6B8E9F, #A08060, #7CB68A, #9683A9, #C9736B, #C9B458 |
Beyond 10 categories, categorical palettes become difficult to distinguish. Group smaller categories into an “Other” category, use small multiples, or employ direct labelling instead of a legend.
Colour-Blind Safe Palettes
Approximately 8% of males and 0.5% of females have some form of colour vision deficiency. Red-green colour blindness (deuteranopia and protanopia) is most common. The following palettes remain distinguishable under common colour vision deficiencies.
| Palette Name | Type | Hex Values | Safe For |
|---|---|---|---|
| Blue-Orange safe | Diverging | #0072B2, #56B4E9, #F0F0F0, #E69F00, #D55E00 | Deuteranopia, Protanopia |
| Viridis | Sequential | #440154, #3B528B, #21918C, #5DC863, #FDE725 | All common deficiencies |
| IBM categorical | Categorical | #648FFF, #785EF0, #DC267F, #FE6100, #FFB000 | Deuteranopia, Protanopia |
| Tol bright | Categorical | #4477AA, #EE6677, #228833, #CCBB44, #66CCEE | All common deficiencies |
When colour alone conveys meaning, provide a secondary encoding: pattern fills for bar charts, marker shapes for scatter plots, or direct labels. Dashboard filtering should not rely solely on colour-coded buttons.
Accessibility Requirements
Visualisations must meet WCAG 2.1 Level AA requirements. The following specifications ensure compliance.
Contrast Ratios
| Element | Minimum Contrast Ratio | Measurement Against |
|---|---|---|
| Data elements (bars, lines, points) | 3:1 | Background |
| Adjacent data elements | 3:1 | Each other |
| Text labels | 4.5:1 | Background |
| Large text (18pt+ or 14pt+ bold) | 3:1 | Background |
| Axis lines | 3:1 | Background |
| Gridlines | 1.5:1 | Background (intentionally subtle) |
Verify contrast ratios using tools such as WebAIM Contrast Checker or browser developer tools. For programmatic checking in dashboards, the formula is:
Contrast ratio = (L1 + 0.05) / (L2 + 0.05)
Where L1 is the relative luminance of the lighter colour L2 is the relative luminance of the darker colour
Relative luminance L = 0.2126 × R + 0.7152 × G + 0.0722 × B(with R, G, B values linearised from sRGB)Text Requirements
| Element | Minimum Size | Font Weight | Maximum Characters |
|---|---|---|---|
| Chart title | 16px | Semi-bold (600) | 60 |
| Axis title | 12px | Medium (500) | 30 |
| Axis labels | 11px | Regular (400) | 20 |
| Data labels | 10px | Regular (400) | 10 |
| Legend text | 11px | Regular (400) | 25 |
| Tooltip text | 12px | Regular (400) | 100 |
| Annotation text | 11px | Regular (400) | 80 |
Use sans-serif fonts for all chart text. Recommended families: Inter, Source Sans Pro, Roboto, or system defaults (system-ui). Avoid condensed or light weights below 12px.
Keyboard and Screen Reader Support
Interactive visualisations require keyboard navigation and screen reader compatibility:
| Requirement | Implementation |
|---|---|
| Focus indicators | Visible 2px outline on focusable elements |
| Tab order | Logical sequence: title → legend → data elements → controls |
| Arrow key navigation | Move between data points within a series |
| Data table alternative | Hidden table with complete data for screen readers |
| ARIA labels | aria-label on chart container describing the visualisation |
| Live regions | aria-live="polite" for filter changes affecting displayed data |
The hidden data table pattern provides screen reader users with access to underlying values. Implement as a visually hidden <table> element containing all data points, with <caption> repeating the chart title.
<div class="chart-container" role="img" aria-label="Monthly beneficiary registrations, January to December 2024"> <div class="visually-hidden"> <table> <caption>Monthly beneficiary registrations, January to December 2024</caption> <thead> <tr><th>Month</th><th>Registrations</th></tr> </thead> <tbody> <tr><td>January</td><td>1,245</td></tr> <!-- remaining rows --> </tbody> </table> </div> <!-- visible chart implementation --></div>Typography and Labelling
Number Formatting
| Value Type | Format | Example |
|---|---|---|
| Whole numbers under 10,000 | No separators | 8472 |
| Whole numbers 10,000+ | Thousands separator | 84,720 |
| Large numbers (millions) | Abbreviated with suffix | 2.4M |
| Percentages | One decimal place maximum | 42.7% |
| Currency | Symbol prefix, thousands separator | $1,245,000 |
| Ratios | Colon separator | 3:1 |
| Dates (axis) | Abbreviated month, year | Jan 2024 |
| Dates (tooltips) | Full format | 15 January 2024 |
| Time | 24-hour format | 14:30 |
| Negative numbers | Minus sign prefix | -1,245 |
Apply consistent formatting within a single visualisation. Mixed formats (some values abbreviated, others not) impair comparison.
Label Placement
| Chart Type | Label Position | Alignment |
|---|---|---|
| Horizontal bar | End of bar (outside if space permits) | Left-aligned |
| Column chart | Above column (outside) | Centre-aligned |
| Line chart | End of line or direct on line | Right-aligned |
| Pie/donut | Outside with leader lines | Radial |
| Scatter plot | Adjacent to point (offset) | Left-aligned |
| Map | Centred within region or adjacent to point | Centre-aligned |
Direct labelling (placing values on or adjacent to data elements) eliminates the need for legends when category count is low. Prefer direct labelling for 4 or fewer series on line charts and for all bar charts where space permits.
Axis Conventions
| Axis Element | Convention |
|---|---|
| Y-axis origin | Start at zero for bar and column charts; may start elsewhere for line charts showing change |
| Y-axis maximum | Extend 10-15% beyond highest value to prevent truncation |
| X-axis time intervals | Consistent intervals (daily, weekly, monthly); indicate gaps explicitly |
| Tick marks | 5-7 ticks per axis; round numbers preferred |
| Grid lines | Horizontal only for most charts; vertical for time series if helpful |
| Axis labels | Horizontal where possible; rotate 45° maximum if necessary |
Truncating the y-axis (starting above zero) is acceptable for line charts showing trends where the focus is on change rather than absolute magnitude. Include an axis break symbol (⫽) and note in the title or annotation when truncation occurs.
Legend and Annotation Standards
Legend Placement
| Scenario | Position | Justification |
|---|---|---|
| Chart width exceeds height | Right side, top-aligned | Preserves horizontal chart space |
| Chart height exceeds width | Bottom, centre-aligned | Preserves vertical chart space |
| 2-3 categories | Top, inline with title | Minimises eye movement |
| Interactive dashboard | Clickable legend for filtering | Top or right, prominent |
| Print/export | Below chart | Ensures capture in screenshots |
Legends should appear within the chart container, not separated by whitespace. Maximum legend entries for a single chart: 10. Beyond this threshold, consider small multiples or a different encoding approach.
Annotation Types
| Annotation Type | Use Case | Visual Treatment |
|---|---|---|
| Reference line | Target, threshold, average | Dashed line, 1px, contrasting colour |
| Reference band | Acceptable range, confidence interval | Semi-transparent fill (20% opacity) |
| Callout | Significant event, anomaly explanation | Text box with pointer line |
| Trend line | Statistical trend | Dotted line, distinct from data |
| Period marker | Time period boundaries | Vertical line, labelled |
Reference lines require labels. An unlabelled horizontal line at y=100 communicates nothing; label it “Target: 100” or “Baseline”.
Annotation Text
Annotation text explains what the audience should notice. Write annotations as complete thoughts:
| Poor Annotation | Improved Annotation |
|---|---|
| ”Peak" | "Registration peak of 3,420 during flood response (March 2024)" |
| "Declined" | "25% decline following programme phase-out in District B" |
| "Target" | "Annual target: 50,000 beneficiaries” |
Position annotations close to the data they reference, connected by a leader line if necessary. Avoid overlapping data elements; adjust placement or use callout boxes.
Table Design Standards
Data tables in dashboards and reports follow consistent formatting rules.
Structure
| Element | Specification |
|---|---|
| Header row | Bold text, bottom border (2px), background fill (#F5F5F5) |
| Column alignment | Text left, numbers right, dates centre |
| Row height | Minimum 32px for touch targets |
| Cell padding | 8px horizontal, 4px vertical |
| Row striping | Optional; alternate rows (#FAFAFA) for tables exceeding 10 rows |
| Row borders | 1px, #E0E0E0, between rows |
| Frozen headers | Fixed position on scroll for tables exceeding viewport height |
Numeric Columns
| Requirement | Implementation |
|---|---|
| Decimal alignment | Align on decimal point |
| Negative values | Red text (#B22222) or parentheses for financial contexts |
| Zero values | Display as “0” not blank |
| Null/missing values | Display as ”—” (en dash) with explanatory footnote |
| Totals row | Bold text, top border (2px), positioned at bottom |
| Percentages | Right-align with % symbol; include conditional formatting bars if comparative |
Conditional Formatting
| Format Type | Use Case | Specification |
|---|---|---|
| Data bars | Show relative magnitude | Colour-blind safe blue (#2E6B8A), 50% cell width maximum |
| Colour scale | Heatmap tables | Sequential palette, light-to-dark |
| Icon sets | Status indicators | Traffic light (with redundant symbols), directional arrows |
| Threshold highlighting | Exception flagging | Background fill for cells exceeding threshold |
Traffic light colour coding (red/yellow/green) alone fails accessibility requirements. Combine with shapes: circle for green/good, triangle for yellow/warning, square for red/critical. Alternatively, use symbols: ✓, !, ✗.
Map Visualisation Standards
Geographic visualisations require specific conventions for clarity and accuracy.
Choropleth Maps
| Element | Specification |
|---|---|
| Classification method | Natural breaks (Jenks), quantiles, or equal intervals depending on distribution |
| Number of classes | 5-7 classes maximum |
| Colour palette | Sequential for rates; diverging for deviation from mean |
| No-data regions | Distinct pattern fill (hatching) or grey, labelled in legend |
| Boundary lines | 1px, colour contrasting with adjacent fill values |
| Labels | Region names at centroid for regions above threshold area |
Equal intervals work for normally distributed data. Quantiles ensure equal counts per class but can obscure magnitude differences. Natural breaks optimise for variance within classes; use for skewed distributions.
Point Maps
| Element | Specification |
|---|---|
| Marker size | Minimum 8px diameter; scale by square root of value for proportional symbols |
| Marker shape | Circle default; use distinct shapes for categorical differentiation |
| Clustering | Enable for datasets exceeding 100 points at default zoom |
| Cluster threshold | Cluster when points would overlap by more than 50% |
| Popup content | Location name, primary metric, secondary metrics |
Proportional symbol scaling uses square root of the value to determine radius, ensuring perceived area scales linearly with value:
radius = base_radius × √(value / reference_value)A value of 400 should appear twice the area of a value of 100, requiring a radius 2× larger (√4 = 2).
Basemap Selection
| Context | Basemap | Justification |
|---|---|---|
| Analytical dashboards | Light grey, minimal labels | Reduces visual competition with data layer |
| Field operations | OpenStreetMap or satellite | Road/terrain detail needed for navigation |
| Public reports | Simple political boundaries | Maximises data emphasis |
| Humanitarian response | OCHA COD boundaries | Standard reference for coordination |
For humanitarian contexts, source administrative boundary data from the Common Operational Datasets (CODs) maintained by OCHA. These provide standardised P-codes required for interoperability with cluster information management systems.
Common Mistakes
| Mistake | Problem | Correction |
|---|---|---|
| Pie chart with 8+ segments | Slices become indistinguishable | Use horizontal bar chart |
| 3D effects on any chart | Distorts perception of values | Remove; use 2D charts exclusively |
| Dual y-axes with different scales | Implies false correlation; misleads on magnitude | Use two separate charts |
| Rainbow colour palettes | No perceptual order; fails accessibility | Use sequential or diverging palette |
| Legend-only identification | Requires constant eye movement | Direct label where possible |
| Excessive decimal places | False precision; cognitive load | Round to meaningful precision |
| Inconsistent time intervals | Misleads on rate of change | Use consistent intervals; note gaps |
| Missing zero baseline (bars) | Exaggerates differences | Start y-axis at zero for bar charts |
| Sorted line charts | Implies time relationship | Use bar chart for categorical comparison |
| Unlabelled axes | Values lack context | Label all axes with units |
| Red-green encoding only | Excludes colour-blind users | Add shape, pattern, or label redundancy |
| Rotated labels beyond 45° | Difficult to read | Abbreviate labels or use horizontal bar |
| Gridlines matching data colour | Data becomes camouflaged | Use subtle gridlines (#E0E0E0) |
| Auto-scaled axes between views | Comparison across dashboards misleading | Lock axis scales where comparison needed |
Tool-Specific Implementation
Apache Superset
{ "color_scheme": "custom_org_categorical", "custom_colors": ["#2E6B8A", "#8B4513", "#228B22", "#663399", "#DC143C", "#DAA520"], "label_colors": {}, "shared_label_colors": {}, "map_style": "mapbox://styles/mapbox/light-v10"}Configure organisation palettes in superset_config.py:
EXTRA_CATEGORICAL_COLOR_SCHEMES = [ { "id": "org_categorical", "description": "Organisation standard categorical palette", "label": "Organisation Categorical", "colors": ["#2E6B8A", "#8B4513", "#228B22", "#663399", "#DC143C", "#DAA520"] }]
EXTRA_SEQUENTIAL_COLOR_SCHEMES = [ { "id": "org_blue_sequential", "description": "Organisation standard sequential palette", "label": "Organisation Blue Sequential", "colors": ["#E6F0F5", "#A3C4D9", "#5A9ABF", "#2E6B8A", "#0D3B54"] }]Power BI
Apply organisation palettes via theme JSON:
{ "name": "Organisation Standard", "dataColors": ["#2E6B8A", "#8B4513", "#228B22", "#663399", "#DC143C", "#DAA520"], "background": "#FFFFFF", "foreground": "#333333", "tableAccent": "#2E6B8A", "visualStyles": { "*": { "*": { "labels": [{ "fontFamily": "Inter, sans-serif", "fontSize": {"expr": {"Literal": {"Value": "11D"}}} }], "title": [{ "fontFamily": "Inter, sans-serif", "fontSize": {"expr": {"Literal": {"Value": "16D"}}}, "fontColor": {"solid": {"color": "#333333"}} }] } } }}Import via External Tools → Theme → Import from file, or embed in the .pbix file.
Tableau
Create organisation palette in Preferences.tps (located in My Tableau Repository):
<?xml version='1.0'?><workbook> <preferences> <color-palette name="Organisation Categorical" type="regular"> <color>#2E6B8A</color> <color>#8B4513</color> <color>#228B22</color> <color>#663399</color> <color>#DC143C</color> <color>#DAA520</color> </color-palette> <color-palette name="Organisation Blue Sequential" type="ordered-sequential"> <color>#E6F0F5</color> <color>#A3C4D9</color> <color>#5A9ABF</color> <color>#2E6B8A</color> <color>#0D3B54</color> </color-palette> <color-palette name="Organisation Diverging" type="ordered-diverging"> <color>#B22222</color> <color>#DC6464</color> <color>#F0F0F0</color> <color>#6495ED</color> <color>#1E3A8A</color> </color-palette> </preferences></workbook>For Tableau Server/Cloud, publish palettes via Site Settings → Extensions → Customize.
Metabase
Configure colours in Admin → Settings → Appearance:
Brand color: #2E6B8AChart colors: #2E6B8A, #8B4513, #228B22, #663399, #DC143C, #DAA520Metabase does not support custom sequential palettes in the interface. For advanced customisation, modify frontend/src/metabase/lib/colors.js in a self-hosted deployment.