Approximately 4.5% of the world’s population is colorblind.
million individuals worldwide having only one kind of visible impairment. The numbers get considerably increased when you have been to take all circumstances into consideration. But, it’s a not often mentioned subject.
As a knowledge skilled, you don’t need anybody misinterpreting your visuals. Positive, being further clear is extra work, however you’ll make an honest chunk of the inhabitants happier.
At this time you’ll get 5 actionable ideas for making your current visualizations accessible.
Concrete Pointers for Implementing Accessibility In Your Knowledge Visualization
However first, let’s go over some basic tips it is best to observe when Accessibility is a high precedence.
Every thing listed beneath is a curated and considerably shortened guidelines of the A11Y project. When you’re questioning, “A11Y” is an abbreviation for “accessibility” (11 letters between “A” and “Y”).
Anyhow, right here’s what it is best to take note of:
- Don’t depend on colour to clarify the info – An honest chunk of the inhabitants is colour blind or suffers from another visible impairment. Patterns are a option to go.
- If utilizing colour, go along with darker, high-contrast tones – Mild and low-contrast colours make it practically unattainable to differentiate between teams on a chart visually.
- Don’t disguise necessary information behind interactions – Hover occasions can be found solely on the desktop. Nearly all 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 screen readers in thoughts – Individuals with visible impairments use display screen readers to navigate internet 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 best option to perceive why colour selection issues is by doing the improper factor first.
Think about 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 indicate 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 would possibly need to colour particular person bar parts in several shades of inexperienced. It’s a horrible apply (aside 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", 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 surprise what their chart would appear like if it was printed in a black-and-white e book.
This one would look solely marginally worse, however solely as a result of it seems to be horrendous from the get-go. Distinguishing between bar parts is difficult even for individuals with out visible impairments.
You can use this website to check the contrast between two colors.
Let’s repair it through the use of a high-contrast colour palette.
Customized Excessive-Distinction Coloration Palette
I’ll proceed with the belief you want the colour inexperienced.
Query: how are you going to create a high-contrast colour palette from one colour?
Reply: begin with a darkish shade and end with a colour related sufficient to your main colour. On this case, yellow-gold is an ideal candidate.
You get the most effective of each worlds this manner. You’re nonetheless utilizing colours you want and the colours don’t must get lighter (which would cut back the distinction) as you undergo bar segments.
In apply, this boils right down to taking part in 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", 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 eventualities:
- You don’t have the time to mess around with totally different colour combos
- You do have the time, however there are a couple of dozen classes in your dataset (learn: dozen colours to search out)
There’s a neater resolution to make your chart colour scheme simpler on the eyes whereas accounting for individuals 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")
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 match for charts with 10 teams or much less.
When you want extra, possibly you’ll be higher off rethinking your visualization technique.
2. Cease Utilizing Colours – Use Patterns As a substitute
One other nice option to take away any sort of misinterpretation out of your charts is to make use of patterns as an alternative of colours (or as an addition to colours).
Matplotlib has 10 hatch patterns you possibly can select from.
You may additional customise the hatches by rising 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", 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 option to misread information on this chart.
Can You Combine Patterns with Coloration?
If you’d like 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", 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", 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 unique story.
You might need no hassle seeing the strains on the topmost chart phase, however put your self within the footwear of an individual with visible impairments. They need to at all times be your body of reference.
Keep in mind: Mild-colored patterns work nicely on darkish backgrounds. Darkish-colored patterns work nicely on gentle backgrounds. Regulate accordingly.
3. Don’t Overwhelm Consumer 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 tough to handle with Python lists, so I’ve opted for a Pandas DataFrame as an alternative:
import pandas as pd
df = pd.DataFrame({
"HR": [50, 63, 40, 68, 35],
"Engineering": [77, 85, 62, 89, 58],
"Advertising": [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 rely 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 option to clear up this unpresentable mess is by displaying much less info to the consumer.
For instance, solely present worker rely in a single metropolis (throughout departments). You may then add a dropdown menu to the aspect of the chart so the consumer can management the workplace location.
The next snippet plots staff 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 displaying 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 an alternative of 10 bar segments is less complicated on the eyes.
This manner, you’ll find yourself displaying workplace areas as bar segments as an alternative 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 truth. Nobody can argue with it.
4. Present In-Depth Explanations of Knowledge On Your Charts
You may leverage subtitle and/or caption sections of your chart so as to add further info.
This turns out to be useful while 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 individuals with visible impairments.
The issue with matplotlib is that it doesn’t have a devoted operate for chart subtitles and captions. You need to use suptitle(), however you’ll must 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", 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 essentially the most staff.", 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()

When you desire 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", 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 essentially the most staff.", 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 stands out as the deciding consider 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 another time.
5. Add Alt Textual content When Embedding Plots
Many individuals with visible impairments use display screen readers.
The issue with display screen readers and charts is that they merely can’t coexist. They may be capable of choose up textual components from the graph, however they’ll’t interpret the visible content material. So, everytime you’re sharing your visualizations (e.g., embedding them into an internet site), it’s essential to add alt textual content.
It is a paragraph the display screen reader will learn to your consumer.
To display, let’s use the plt.savefig()
operate 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", 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 essentially the most staff.", 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 it is best to present alt textual content:
Doc

You may’t see alt textual content while you open the HTML file, however that’s since you’re not utilizing a display screen reader.
If the display screen reader is detected, the alt textual content will likely be routinely learn to the consumer.
The most effective 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 an alternative.
Summing Up Knowledge Visualization Accessibility
And there you might have it — 5 issues it is best to at all times have in mind when designing information visualizations.
The following pointers are useful on the whole however are of important significance when accessibility is important. And it at all times ought 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 individuals worldwide.