Approximately 4.5% of the world’s population is colorblind.
million folks worldwide having only one kind of visible impairment. The numbers get considerably larger should you have been to take all circumstances into consideration. But, it’s a hardly ever mentioned matter.
As an information skilled, you don’t need anybody misinterpreting your visuals. Certain, being further clear is extra work, however you’ll make an honest chunk of the inhabitants happier.
At present you’ll get 5 actionable ideas for making your present visualizations accessible.
Concrete Tips for Implementing Accessibility In Your Knowledge Visualization
However first, let’s go over some normal pointers you need to comply with when Accessibility is a high precedence.
Every little thing listed beneath is a curated and considerably shortened guidelines of the A11Y project. If you happen to’re questioning, “A11Y” is an abbreviation for “accessibility” (11 letters between “A” and “Y”).
Anyhow, right here’s what you need to take note of:
- Don’t depend on colour to elucidate the info – An honest chunk of the inhabitants is colour blind or suffers from another visible impairment. Patterns are a method to go.
- If utilizing colour, go along with darker, high-contrast tones – Mild and low-contrast colours make it almost unattainable to tell apart between teams on a chart visually.
- Don’t disguise vital information behind interactions – Hover occasions can be found solely on the desktop. The vast majority of your customers are on smartphones.
- Use labels and legends – With out them, the reader doesn’t know what the info represents.
- Translate information into clear insights – Simplify the info as a lot as attainable, after which some. You don’t need something to be open for interpretation.
- Present context and clarify the visualization – If possible, annotate information factors of curiosity, and add subtitle/caption.
- Have customers with display readers in thoughts – Individuals with visible impairments use display readers to navigate net pages. Use alt textual content to explain your embedded charts.
With these in thoughts, I got here up with 5 actionable tweaks you can also make to your visualizations proper now.
Let’s dive into #1.
1. Use a Excessive-Distinction or Colorblind-Pleasant Coloration Palette
The simplest method to perceive why colour selection issues is by doing the fallacious factor first.
Take into account the next dataset:
x = np.array(["New York", "San Francisco", "Los Angeles", "Chicago", "Miami"])
y1 = np.array([50, 63, 40, 68, 35])
y2 = np.array([77, 85, 62, 89, 58])
y3 = np.array([50, 35, 79, 43, 67])
y4 = np.array([59, 62, 33, 77, 72])
It’s an ideal candidate for a stacked bar chart. In different phrases, to point out workplace areas on the X-axis and stack worker counts on the Y-axis.
Now think about you’re actually into the colour inexperienced.
You may need to colour particular person bar parts in numerous shades of inexperienced. It’s a horrible follow (apart from some monochromatic colour palettes), as you possibly can see from the next:
plt.bar(x, y1, label="HR", colour="#32a852")
plt.bar(x, y2, backside=y1, label="Engineering", colour="#3ebd61")
plt.bar(x, y3, backside=y1 + y2, label="Advertising and marketing", colour="#2bc254")
plt.bar(x, y4, backside=y1 + y2 + y3, label="Gross sales", colour="#44c767")
plt.title("[DON'T] Worker Rely Per Location And Division", loc="left", fontdict={"weight": "daring"}, y=1.06)
plt.xlabel("Workplace Location")
plt.ylabel("Rely")
plt.legend(loc="higher proper", ncol=4)
plt.ylim(high=320)
plt.present()
Many individuals marvel what their chart would seem like if it was printed in a black-and-white guide.
This one would look solely marginally worse, however solely as a result of it appears horrendous from the get-go. Distinguishing between bar parts is difficult even for folks with out visible impairments.
You can use this website to check the contrast between two colors.
Let’s repair it by utilizing a high-contrast colour palette.
Customized Excessive-Distinction Coloration Palette
I’ll proceed with the idea you want the colour inexperienced.
Query: how will you create a high-contrast colour palette from one colour?
Reply: begin with a darkish shade and end with a colour comparable sufficient to your major colour. On this case, yellow-gold is an ideal candidate.
You get the most effective of each worlds this fashion. You’re nonetheless utilizing colours you want and the colours don’t should get lighter (which would scale back the distinction) as you undergo bar segments.
In follow, this boils right down to enjoying round with the colour
parameter for all segments:
plt.bar(x, y1, label="HR", colour="#14342B")
plt.bar(x, y2, backside=y1, label="Engineering", colour="#60935D")
plt.bar(x, y3, backside=y1 + y2, label="Advertising and marketing", colour="#BAB700")
plt.bar(x, y4, backside=y1 + y2 + y3, label="Gross sales", colour="#F5E400")
plt.title("[DO] Worker Rely Per Location And Division", loc="left", fontdict={"weight": "daring"}, y=1.06)
plt.xlabel("Workplace Location")
plt.ylabel("Rely")
plt.legend(loc="higher proper", ncol=4)
plt.ylim(high=320)
plt.present()

A lot simpler on the eyes.
Predefined Colorblind Coloration Palette
However contemplate the next situations:
- You don’t have the time to mess around with totally different colour combos
- You do have the time, however there are a few dozen classes in your dataset (learn: dozen colours to seek out)
There’s a neater resolution to make your chart colour scheme simpler on the eyes whereas accounting for folks with visible impairments.
One such resolution is to make use of a colorblind-friendly colour palette.
The primary line of the snippet reveals you ways:
plt.type.use("tableau-colorblind10")
plt.bar(x, y1, label="HR")
plt.bar(x, y2, backside=y1, label="Engineering")
plt.bar(x, y3, backside=y1 + y2, label="Advertising and marketing")
plt.bar(x, y4, backside=y1 + y2 + y3, label="Gross sales")
plt.title("[DO] Worker Rely Per Location And Division", loc="left", fontdict={"weight": "daring"}, y=1.06)
plt.xlabel("Workplace Location")
plt.ylabel("Rely")
plt.legend(loc="higher proper", ncol=4)
plt.ylim(high=320)
plt.present()

This palette comprises 10 colorblind-friendly colours, so it’s a great match for charts with 10 teams or much less.
If you happen to want extra, possibly you’ll be higher off rethinking your visualization technique.
2. Cease Utilizing Colours – Use Patterns As a substitute
One other nice method to take away any sort of misinterpretation out of your charts is to make use of patterns as a substitute of colours (or as an addition to colours).
Matplotlib has 10 hatch patterns you possibly can select from.
You’ll be able to additional customise the hatches by growing their density or by combining a number of patterns. However that’s a subject for one more time.
To implement patterns, add the hatch
parameter to plt.bar()
. The instance beneath removes colour altogether by setting fill=False
:
plt.bar(x, y1, label="HR", fill=False, hatch="*")
plt.bar(x, y2, backside=y1, label="Engineering", fill=False, hatch="xx")
plt.bar(x, y3, backside=y1 + y2, label="Advertising and marketing", fill=False, hatch="..")
plt.bar(x, y4, backside=y1 + y2 + y3, label="Gross sales", fill=False, hatch="//")
plt.title("[DO] Worker Rely Per Location And Division", loc="left", fontdict={"weight": "daring"}, y=1.06)
plt.xlabel("Workplace Location")
plt.ylabel("Rely")
plt.legend(loc="higher proper", ncol=4)
plt.ylim(high=320)
plt.present()

Now there’s no method to misread information on this chart.
Can You Combine Patterns with Coloration?
In order for you the most effective of each worlds, colour + sample is the place it’s at.
You’ll need to take away the fill=False parameter and alter it with colour
. Or, simply copy the next code snippet:
plt.bar(x, y1, label="HR", colour="#14342B", hatch="*")
plt.bar(x, y2, backside=y1, label="Engineering", colour="#60935D", hatch="xx")
plt.bar(x, y3, backside=y1 + y2, label="Advertising and marketing", colour="#BAB700", hatch="..")
plt.bar(x, y4, backside=y1 + y2 + y3, label="Gross sales", colour="#F5E400", hatch="//")
plt.title("[DO] Worker Rely Per Location And Division", loc="left", fontdict={"weight": "daring"}, y=1.06)
plt.xlabel("Workplace Location")
plt.ylabel("Rely")
plt.legend(loc="higher proper", ncol=4)
plt.ylim(high=320)
plt.present()

Darkish patterns are clearly seen on bar segments, however that may not at all times be the case.
The edgecolor
parameter controls the sample colour. Let’s see what occurs after setting it to white:
plt.bar(x, y1, label="HR", colour="#14342B", hatch="*", edgecolor="#FFFFFF")
plt.bar(x, y2, backside=y1, label="Engineering", colour="#60935D", hatch="xx", edgecolor="#FFFFFF")
plt.bar(x, y3, backside=y1 + y2, label="Advertising and marketing", colour="#BAB700", hatch="..", edgecolor="#FFFFFF")
plt.bar(x, y4, backside=y1 + y2 + y3, label="Gross sales", colour="#F5E400", hatch="///", edgecolor="#FFFFFF")
plt.title("[MAYBE] Worker Rely Per Location And Division", loc="left", fontdict={"weight": "daring"}, y=1.06)
plt.xlabel("Workplace Location")
plt.ylabel("Rely")
plt.legend(loc="higher proper", ncol=4)
plt.ylim(high=320)
plt.present()

The sample is seen for HR and Engineering departments, however the two on the highest are a special story.
You might need no hassle seeing the strains on the topmost chart section, however put your self within the footwear of an individual with visible impairments. They need to at all times be your body of reference.
Bear in mind: Mild-colored patterns work effectively on darkish backgrounds. Darkish-colored patterns work effectively on mild backgrounds. Alter accordingly.
3. Don’t Overwhelm Person with the Data
This precept goes in two instructions:
- Don’t put an excessive amount of info on a single chart
- Don’t put too many charts subsequent to one another, e.g., in your purposes/dashboards
Doing each concurrently is considerably of an final sin in information visualization.
Let’s begin by including a pair extra departments into the combination.
The information is getting troublesome to handle with Python lists, so I’ve opted for a Pandas DataFrame as a substitute:
import pandas as pd
df = pd.DataFrame({
"HR": [50, 63, 40, 68, 35],
"Engineering": [77, 85, 62, 89, 58],
"Advertising and marketing": [50, 35, 79, 43, 67],
"Gross sales": [59, 62, 33, 77, 72],
"Buyer Service": [31, 34, 61, 70, 39],
"Distribution": [35, 21, 66, 90, 31],
"Logistics": [50, 54, 13, 71, 32],
"Manufacturing": [22, 51, 54, 28, 40],
"Upkeep": [50, 32, 61, 69, 50],
"High quality Management": [20, 21, 88, 89, 39]
}, index=["New York", "San Francisco", "Los Angeles", "Chicago", "Miami"])
df

Now, utilizing the colorblind-friendly palette, let’s plot the worker depend per location and division as a stacked bar chart. To make issues further crammed, I’ve additionally thrown textual content counts into the combination:
plt.type.use("tableau-colorblind10")
ax = df.plot(type="bar", stacked=True)
for container in ax.containers:
ax.bar_label(container, label_type="heart", fontsize=10, colour="#000000", fontweight="daring")
plt.title("[DON'T] Worker Rely Per Location And Division", loc="left", fontdict={"weight": "daring"}, y=1.06)
plt.xlabel("Workplace Location")
plt.ylabel("Rely")
plt.legend(title="Division", bbox_to_anchor=(1.05, 1), loc='higher left', ncol=1)
plt.present()

Now that’s simply ugly.
Repair #1 – Current Much less Data
One method to clear up this unpresentable mess is by exhibiting much less info to the consumer.
For instance, solely present worker depend in a single metropolis (throughout departments). You’ll be able to then add a dropdown menu to the aspect of the chart so the consumer can management the workplace location.
The next snippet plots workers per division in Chicago as a horizontal bar chart:
chicago_data = df.loc["Chicago"].sort_values()
bars = plt.barh(chicago_data.index, chicago_data.values, colour="#60935D", edgecolor="#000000")
for bar in bars:
plt.textual content(bar.get_width() + 2, bar.get_y() + bar.get_height() / 2, f"{int(bar.get_width())}", va="heart", ha="left", fontsize=14, colour="#000000")
plt.title("[DO] Worker Rely by Division in Chicago", loc="left", fontdict={"weight": "daring"}, y=1.06)
plt.xlabel("Rely")
plt.ylabel("Division")
plt.present()

Repair #2 – Reorganize the Knowledge
If exhibiting much less info isn’t an choice, possibly you possibly can transpose your information.
For instance, we’re coping with 5 workplace areas and 10 departments. Exhibiting 10 columns as a substitute of 10 bar segments is less complicated on the eyes.
This manner, you’ll find yourself exhibiting workplace areas as bar segments as a substitute of departments:
df_transposed = df.T
df_sorted = df_transposed.loc[df_transposed.sum(axis=1).sort_values().index]
ax = df_sorted.plot(type="barh", width=0.8, edgecolor="#000000", stacked=True)
for container in ax.containers:
ax.bar_label(container, label_type="heart", fontsize=10, colour="#FFFFFF", fontweight="daring")
plt.title("[DO] Worker Rely Per Location And Division", loc="left", fontdict={"weight": "daring"}, y=1.06)
plt.xlabel("Workplace Location")
plt.ylabel("Rely")
plt.present()

It’s only a matter of reframing the issue.
The chart on Picture 10 is miles forward of the chart on Picture 8. It’s a reality. Nobody can argue with it.
4. Present In-Depth Explanations of Knowledge On Your Charts
You’ll be able to leverage subtitle and/or caption sections of your chart so as to add further info.
This turns out to be useful once you need to present extra context concerning the information, cite sources, or summarize the principle level(s) of your visualization. The final one is most relevant for folks with visible impairments.
The issue with matplotlib is that it doesn’t have a devoted perform for chart subtitles and captions. You should use suptitle(), however you’ll should mess around with x and y-axis coordinates.
Right here’s an instance:
plt.bar(x, y1, label="HR", colour="#14342B", hatch="*")
plt.bar(x, y2, backside=y1, label="Engineering", colour="#60935D", hatch="xx")
plt.bar(x, y3, backside=y1 + y2, label="Advertising and marketing", colour="#BAB700", hatch="..")
plt.bar(x, y4, backside=y1 + y2 + y3, label="Gross sales", colour="#F5E400", hatch="//")
plt.suptitle("Chart reveals how the workers are distributed per division and per workplace location.nChicago workplace has probably the most workers.", x=0.125, y=0.98, ha="left", fontsize=14, fontstyle="italic")
plt.title("Worker Rely Per Location And Division", fontsize=20, fontweight="daring", y=1.15, loc="left")
plt.xlabel("Workplace Location")
plt.ylabel("Rely")
plt.legend(loc="higher proper", ncol=4)
plt.ylim(high=320)
plt.present()

If you happen to choose a caption over a subtitle, you solely have the change y-axis coordinate in plt.suptitle()
:
plt.bar(x, y1, label="HR", colour="#14342B", hatch="*")
plt.bar(x, y2, backside=y1, label="Engineering", colour="#60935D", hatch="xx")
plt.bar(x, y3, backside=y1 + y2, label="Advertising and marketing", colour="#BAB700", hatch="..")
plt.bar(x, y4, backside=y1 + y2 + y3, label="Gross sales", colour="#F5E400", hatch="//")
plt.suptitle("Chart reveals how the workers are distributed per division and per workplace location.nChicago workplace has probably the most workers.", x=0.125, y=0, ha="left", fontsize=14, fontstyle="italic")
plt.title("Worker Rely Per Location And Division", fontsize=20, fontweight="daring", y=1.06, loc="left")
plt.xlabel("Workplace Location")
plt.ylabel("Rely")
plt.legend(loc="higher proper", ncol=4)
plt.ylim(high=320)
plt.present()

All in all, a subtitle or a caption will be the deciding think about accurately getting your message to an individual with visible impairments.
Simply don’t make it 10 paragraphs lengthy. In any other case, it’s the third level of this text over again.
5. Add Alt Textual content When Embedding Plots
Many individuals with visible impairments use display readers.
The issue with display readers and charts is that they merely can’t coexist. They may be capable of choose up textual components from the graph, however they will’t interpret the visible content material. So, everytime you’re sharing your visualizations (e.g., embedding them into an internet site), you have to add alt textual content.
It is a paragraph the display reader will learn to your consumer.
To display, let’s use the plt.savefig()
perform to avoid wasting the chart as a picture:
plt.bar(x, y1, label="HR", colour="#14342B", hatch="*")
plt.bar(x, y2, backside=y1, label="Engineering", colour="#60935D", hatch="xx")
plt.bar(x, y3, backside=y1 + y2, label="Advertising and marketing", colour="#BAB700", hatch="..")
plt.bar(x, y4, backside=y1 + y2 + y3, label="Gross sales", colour="#F5E400", hatch="//")
plt.suptitle("Chart reveals how the workers are distributed per division and per workplace location.nChicago workplace has probably the most workers.", x=0.125, y=0, ha="left", fontsize=14, fontstyle="italic")
plt.title("Worker Rely Per Location And Division", fontsize=20, fontweight='daring', y=1.06, loc="left")
plt.xlabel("Workplace Location")
plt.ylabel("Rely")
plt.legend(loc="higher proper", ncol=4)
plt.ylim(high=320)
plt.savefig("determine.jpg", dpi=300, bbox_inches="tight")
In a brand new HTML doc, add an
tag that factors to the picture. That is the place you need to present alt textual content:
Doc

You’ll be able to’t see alt textual content once you open the HTML file, however that’s since you’re not utilizing a display reader.
If the display reader is detected, the alt textual content can be mechanically learn to the consumer.
The perfect you are able to do is use a screen reader plugin or level to the picture that doesn’t exist in HTML:


Now the picture can’t be discovered, so alt textual content is displayed as a substitute.
Summing Up Knowledge Visualization Accessibility
And there you’ve gotten it — 5 issues you need to at all times consider when designing information visualizations.
The following tips are useful on the whole however are of important significance when accessibility is crucial. And it at all times needs to be. It requires a tiny bit of additional work out of your finish, however makes your findings accessible to tens of millions of extra folks worldwide.