Skip to content

ENH: Add Petroff 6 and 8 color cycle style sheets #30065

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Six and eight color Petroff color cycles
----------------------------------------

The six and eight color accessible Petroff color cycles are named 'petroff6' and
'petroff8'.
They compliment the existing 'petroff10' color cycle, added in `Matplotlib 3.10.0`_

For more details see
`Petroff, M. A.: "Accessible Color Sequences for Data Visualization"
<https://arxiv.org/abs/2107.02270>`_.
To load the 'petroff6' color cycle in place of the default::

import matplotlib.pyplot as plt
plt.style.use('petroff6')

or to load the 'petroff8' color cycle::

import matplotlib.pyplot as plt
plt.style.use('petroff8')

.. _Matplotlib 3.10.0: https://matplotlib.org/stable/users/prev_whats_new/whats_new_3.10.0.html#new-more-accessible-color-cycle
23 changes: 23 additions & 0 deletions lib/matplotlib/_cm.py
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The RGB values were determiend from converting the hex using https://www.rapidtables.com/convert/color/hex-to-rgb.html. If a more specific method is desired, I'm happy to double check the RGB values with it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should do, since screens have much more difference between them than a single RGB color step anyway.

(Since I didn't know which was the original format, I did some conversions, thinking that the RGB was the approximation of the 0-1-range. And then read the paper to see that it was the other way around. It seems to match exactly.)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code will exactly convert the top-cycles.json file to the format here:

#!/usr/bin/env python3

import json

with open("top-cycles.json") as infile:
    cycles = json.load(infile)

for k in cycles:
    print(f"_petroff{k}_data = (")
    for c in cycles[k]:
        cf = [str(int(c[i * 2 : (i + 1) * 2], 16) / 255) for i in range(3)]
        print(f"    ({cf[0] + ',':20} {cf[1] + ',':20} {cf[2] + '),':22}  # {c}")
    print(")\n")

Original file line number Diff line number Diff line change
Expand Up @@ -1365,6 +1365,29 @@ def _gist_yarg(x): return 1 - x
(0.8509803921568627, 0.8509803921568627, 0.8509803921568627 ), # d9d9d9
)

# Colorblind accessible palettes from
# Matthew A. Petroff, Accessible Color Sequences for Data Visualization
# https://arxiv.org/abs/2107.02270

_petroff6_data = (
(0.3411764705882353, 0.5647058823529412, 0.9882352941176471), # 5790fc
(0.9725490196078431, 0.611764705882353, 0.12549019607843137), # f89c20
(0.8941176470588236, 0.1450980392156863, 0.21176470588235294), # e42536
(0.5882352941176471, 0.2901960784313726, 0.5450980392156862), # 964a8b
(0.611764705882353, 0.611764705882353, 0.6313725490196078), # 9c9ca1
(0.47843137254901963, 0.12941176470588237, 0.8666666666666667), # 7a21dd
)

_petroff8_data = (
(0.09411764705882353, 0.27058823529411763, 0.984313725490196), # 1845fb
(1.0, 0.3686274509803922, 0.00784313725490196), # ff5e02
(0.788235294117647, 0.12156862745098039, 0.08627450980392157), # c91f16
(0.7843137254901961, 0.28627450980392155, 0.6627450980392157), # c849a9
(0.6784313725490196, 0.6784313725490196, 0.49019607843137253), # adad7d
(0.5254901960784314, 0.7843137254901961, 0.8666666666666667), # 86c8dd
(0.3411764705882353, 0.5529411764705883, 1.0), # 578dff
(0.396078431372549, 0.38823529411764707, 0.39215686274509803), # 656364
)

_petroff10_data = (
(0.24705882352941178, 0.5647058823529412, 0.8549019607843137), # 3f90da
Expand Down
2 changes: 2 additions & 0 deletions lib/matplotlib/colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ class ColorSequenceRegistry(Mapping):
'Set1': _cm._Set1_data,
'Set2': _cm._Set2_data,
'Set3': _cm._Set3_data,
'petroff6': _cm._petroff6_data,
'petroff8': _cm._petroff8_data,
'petroff10': _cm._petroff10_data,
}

Expand Down
5 changes: 5 additions & 0 deletions lib/matplotlib/mpl-data/stylelib/petroff6.mplstyle
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Color cycle survey palette from Petroff (2021):
# https://arxiv.org/abs/2107.02270
# https://github.com/mpetroff/accessible-color-cycles
axes.prop_cycle: cycler('color', ['5790fc', 'f89c20', 'e42536', '964a8b', '9c9ca1', '7a21dd'])
patch.facecolor: 5790fc
5 changes: 5 additions & 0 deletions lib/matplotlib/mpl-data/stylelib/petroff8.mplstyle
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Color cycle survey palette from Petroff (2021):
# https://arxiv.org/abs/2107.02270
# https://github.com/mpetroff/accessible-color-cycles
axes.prop_cycle: cycler('color', ['1845fb', 'ff5e02', 'c91f16', 'c849a9', 'adad7d', '86c8dd', '578dff', '656364'])
patch.facecolor: 1845fb
3 changes: 2 additions & 1 deletion lib/matplotlib/tests/test_colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -1704,7 +1704,8 @@ def test_color_sequences():
assert plt.color_sequences is matplotlib.color_sequences # same registry
assert list(plt.color_sequences) == [
'tab10', 'tab20', 'tab20b', 'tab20c', 'Pastel1', 'Pastel2', 'Paired',
'Accent', 'Dark2', 'Set1', 'Set2', 'Set3', 'petroff10']
'Accent', 'Dark2', 'Set1', 'Set2', 'Set3', 'petroff6', 'petroff8',
'petroff10']
assert len(plt.color_sequences['tab10']) == 10
assert len(plt.color_sequences['tab20']) == 20

Expand Down
Loading