From 38f515dc48ae81cff02d5d41ac46e13a695d8f3c Mon Sep 17 00:00:00 2001 From: lpc Date: Wed, 2 Dec 2020 17:39:05 +0100 Subject: [PATCH 1/5] More colors in CSSToExcelConverter.NAMED_COLORS (GH37967) --- pandas/io/formats/excel.py | 157 +++++++++++++++++++++++++++++++++---- 1 file changed, 143 insertions(+), 14 deletions(-) diff --git a/pandas/io/formats/excel.py b/pandas/io/formats/excel.py index bded853f383e0..00b526ffd6c16 100644 --- a/pandas/io/formats/excel.py +++ b/pandas/io/formats/excel.py @@ -65,27 +65,156 @@ class CSSToExcelConverter: CSS processed by :meth:`__call__`. """ + # source: matplotlib 3.3.3, matplotlib.colors.CSS4_COLORS NAMED_COLORS = { - "maroon": "800000", - "brown": "A52A2A", - "red": "FF0000", - "pink": "FFC0CB", - "orange": "FFA500", - "yellow": "FFFF00", - "olive": "808000", - "green": "008000", - "purple": "800080", - "fuchsia": "FF00FF", - "lime": "00FF00", - "teal": "008080", + "aliceblue": "F0F8FF", + "antiquewhite": "FAEBD7", "aqua": "00FFFF", - "blue": "0000FF", - "navy": "000080", + "aquamarine": "7FFFD4", + "azure": "F0FFFF", + "beige": "F5F5DC", + "bisque": "FFE4C4", "black": "000000", + "blanchedalmond": "FFEBCD", + "blue": "0000FF", + "blueviolet": "8A2BE2", + "brown": "A52A2A", + "burlywood": "DEB887", + "cadetblue": "5F9EA0", + "chartreuse": "7FFF00", + "chocolate": "D2691E", + "coral": "FF7F50", + "cornflowerblue": "6495ED", + "cornsilk": "FFF8DC", + "crimson": "DC143C", + "cyan": "00FFFF", + "darkblue": "00008B", + "darkcyan": "008B8B", + "darkgoldenrod": "B8860B", + "darkgray": "A9A9A9", + "darkgreen": "006400", + "darkgrey": "A9A9A9", + "darkkhaki": "BDB76B", + "darkmagenta": "8B008B", + "darkolivegreen": "556B2F", + "darkorange": "FF8C00", + "darkorchid": "9932CC", + "darkred": "8B0000", + "darksalmon": "E9967A", + "darkseagreen": "8FBC8F", + "darkslateblue": "483D8B", + "darkslategray": "2F4F4F", + "darkslategrey": "2F4F4F", + "darkturquoise": "00CED1", + "darkviolet": "9400D3", + "deeppink": "FF1493", + "deepskyblue": "00BFFF", + "dimgray": "696969", + "dimgrey": "696969", + "dodgerblue": "1E90FF", + "firebrick": "B22222", + "floralwhite": "FFFAF0", + "forestgreen": "228B22", + "fuchsia": "FF00FF", + "gainsboro": "DCDCDC", + "ghostwhite": "F8F8FF", + "gold": "FFD700", + "goldenrod": "DAA520", "gray": "808080", + "green": "008000", + "greenyellow": "ADFF2F", "grey": "808080", + "honeydew": "F0FFF0", + "hotpink": "FF69B4", + "indianred": "CD5C5C", + "indigo": "4B0082", + "ivory": "FFFFF0", + "khaki": "F0E68C", + "lavender": "E6E6FA", + "lavenderblush": "FFF0F5", + "lawngreen": "7CFC00", + "lemonchiffon": "FFFACD", + "lightblue": "ADD8E6", + "lightcoral": "F08080", + "lightcyan": "E0FFFF", + "lightgoldenrodyellow": "FAFAD2", + "lightgray": "D3D3D3", + "lightgreen": "90EE90", + "lightgrey": "D3D3D3", + "lightpink": "FFB6C1", + "lightsalmon": "FFA07A", + "lightseagreen": "20B2AA", + "lightskyblue": "87CEFA", + "lightslategray": "778899", + "lightslategrey": "778899", + "lightsteelblue": "B0C4DE", + "lightyellow": "FFFFE0", + "lime": "00FF00", + "limegreen": "32CD32", + "linen": "FAF0E6", + "magenta": "FF00FF", + "maroon": "800000", + "mediumaquamarine": "66CDAA", + "mediumblue": "0000CD", + "mediumorchid": "BA55D3", + "mediumpurple": "9370DB", + "mediumseagreen": "3CB371", + "mediumslateblue": "7B68EE", + "mediumspringgreen": "00FA9A", + "mediumturquoise": "48D1CC", + "mediumvioletred": "C71585", + "midnightblue": "191970", + "mintcream": "F5FFFA", + "mistyrose": "FFE4E1", + "moccasin": "FFE4B5", + "navajowhite": "FFDEAD", + "navy": "000080", + "oldlace": "FDF5E6", + "olive": "808000", + "olivedrab": "6B8E23", + "orange": "FFA500", + "orangered": "FF4500", + "orchid": "DA70D6", + "palegoldenrod": "EEE8AA", + "palegreen": "98FB98", + "paleturquoise": "AFEEEE", + "palevioletred": "DB7093", + "papayawhip": "FFEFD5", + "peachpuff": "FFDAB9", + "peru": "CD853F", + "pink": "FFC0CB", + "plum": "DDA0DD", + "powderblue": "B0E0E6", + "purple": "800080", + "rebeccapurple": "663399", + "red": "FF0000", + "rosybrown": "BC8F8F", + "royalblue": "4169E1", + "saddlebrown": "8B4513", + "salmon": "FA8072", + "sandybrown": "F4A460", + "seagreen": "2E8B57", + "seashell": "FFF5EE", + "sienna": "A0522D", "silver": "C0C0C0", + "skyblue": "87CEEB", + "slateblue": "6A5ACD", + "slategray": "708090", + "slategrey": "708090", + "snow": "FFFAFA", + "springgreen": "00FF7F", + "steelblue": "4682B4", + "tan": "D2B48C", + "teal": "008080", + "thistle": "D8BFD8", + "tomato": "FF6347", + "turquoise": "40E0D0", + "violet": "EE82EE", + "wheat": "F5DEB3", "white": "FFFFFF", + "whitesmoke": "F5F5F5", + "yellow": "FFFF00", + "yellowgreen": "9ACD32", } VERTICAL_MAP = { From 675415bb2b0cf7c21ccd363f78ee4975b483ff04 Mon Sep 17 00:00:00 2001 From: lpc Date: Wed, 2 Dec 2020 20:01:12 +0100 Subject: [PATCH 2/5] added test: check names --- pandas/tests/io/formats/test_to_excel.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pandas/tests/io/formats/test_to_excel.py b/pandas/tests/io/formats/test_to_excel.py index 4f1af132204bb..c5b7b097ebfd4 100644 --- a/pandas/tests/io/formats/test_to_excel.py +++ b/pandas/tests/io/formats/test_to_excel.py @@ -2,6 +2,7 @@ ExcelFormatter is tested implicitly in pandas/tests/io/excel """ +import string import pytest @@ -313,3 +314,9 @@ def test_css_to_excel_bad_colors(input_color): with tm.assert_produces_warning(CSSWarning): convert = CSSToExcelConverter() assert expected == convert(css) + + +def tests_css_named_colors_valid(): + upper_hexs = set(map(str.upper, string.hexdigits)) + for color in CSSToExcelConverter.NAMED_COLORS.values(): + assert len(color) == 6 and all(c in upper_hexs for c in color) From d6e919cd0d416c11fec4e3c14ec1bbdc84c9171e Mon Sep 17 00:00:00 2001 From: lpc Date: Wed, 2 Dec 2020 22:56:42 +0100 Subject: [PATCH 3/5] added tests: check presence of mpl CSS4 colors --- pandas/tests/io/formats/test_to_excel.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pandas/tests/io/formats/test_to_excel.py b/pandas/tests/io/formats/test_to_excel.py index c5b7b097ebfd4..968ad63eaceef 100644 --- a/pandas/tests/io/formats/test_to_excel.py +++ b/pandas/tests/io/formats/test_to_excel.py @@ -6,6 +6,8 @@ import pytest +import pandas.util._test_decorators as td + import pandas._testing as tm from pandas.io.formats.css import CSSWarning @@ -320,3 +322,12 @@ def tests_css_named_colors_valid(): upper_hexs = set(map(str.upper, string.hexdigits)) for color in CSSToExcelConverter.NAMED_COLORS.values(): assert len(color) == 6 and all(c in upper_hexs for c in color) + + +@td.skip_if_no_mpl +def test_css_named_colors_from_mpl_present(): + from matplotlib.colors import CSS4_COLORS as mpl_colors + + pd_colors = CSSToExcelConverter.NAMED_COLORS + for name, color in mpl_colors.items(): + assert name in pd_colors and pd_colors[name] == color[1:] From dde07c041b289b8887a54db1296b1f146eb6a6ef Mon Sep 17 00:00:00 2001 From: lpc Date: Thu, 3 Dec 2020 19:30:38 +0100 Subject: [PATCH 4/5] color list in separate module --- pandas/io/formats/_color_data.py | 151 ++++++++++++++++++++++++++++++ pandas/io/formats/excel.py | 154 +------------------------------ 2 files changed, 154 insertions(+), 151 deletions(-) create mode 100644 pandas/io/formats/_color_data.py diff --git a/pandas/io/formats/_color_data.py b/pandas/io/formats/_color_data.py new file mode 100644 index 0000000000000..8f68bf26f2961 --- /dev/null +++ b/pandas/io/formats/_color_data.py @@ -0,0 +1,151 @@ +# source: matplotlib._color_data (3.3.3) +CSS4_COLORS = { + "aliceblue": "F0F8FF", + "antiquewhite": "FAEBD7", + "aqua": "00FFFF", + "aquamarine": "7FFFD4", + "azure": "F0FFFF", + "beige": "F5F5DC", + "bisque": "FFE4C4", + "black": "000000", + "blanchedalmond": "FFEBCD", + "blue": "0000FF", + "blueviolet": "8A2BE2", + "brown": "A52A2A", + "burlywood": "DEB887", + "cadetblue": "5F9EA0", + "chartreuse": "7FFF00", + "chocolate": "D2691E", + "coral": "FF7F50", + "cornflowerblue": "6495ED", + "cornsilk": "FFF8DC", + "crimson": "DC143C", + "cyan": "00FFFF", + "darkblue": "00008B", + "darkcyan": "008B8B", + "darkgoldenrod": "B8860B", + "darkgray": "A9A9A9", + "darkgreen": "006400", + "darkgrey": "A9A9A9", + "darkkhaki": "BDB76B", + "darkmagenta": "8B008B", + "darkolivegreen": "556B2F", + "darkorange": "FF8C00", + "darkorchid": "9932CC", + "darkred": "8B0000", + "darksalmon": "E9967A", + "darkseagreen": "8FBC8F", + "darkslateblue": "483D8B", + "darkslategray": "2F4F4F", + "darkslategrey": "2F4F4F", + "darkturquoise": "00CED1", + "darkviolet": "9400D3", + "deeppink": "FF1493", + "deepskyblue": "00BFFF", + "dimgray": "696969", + "dimgrey": "696969", + "dodgerblue": "1E90FF", + "firebrick": "B22222", + "floralwhite": "FFFAF0", + "forestgreen": "228B22", + "fuchsia": "FF00FF", + "gainsboro": "DCDCDC", + "ghostwhite": "F8F8FF", + "gold": "FFD700", + "goldenrod": "DAA520", + "gray": "808080", + "green": "008000", + "greenyellow": "ADFF2F", + "grey": "808080", + "honeydew": "F0FFF0", + "hotpink": "FF69B4", + "indianred": "CD5C5C", + "indigo": "4B0082", + "ivory": "FFFFF0", + "khaki": "F0E68C", + "lavender": "E6E6FA", + "lavenderblush": "FFF0F5", + "lawngreen": "7CFC00", + "lemonchiffon": "FFFACD", + "lightblue": "ADD8E6", + "lightcoral": "F08080", + "lightcyan": "E0FFFF", + "lightgoldenrodyellow": "FAFAD2", + "lightgray": "D3D3D3", + "lightgreen": "90EE90", + "lightgrey": "D3D3D3", + "lightpink": "FFB6C1", + "lightsalmon": "FFA07A", + "lightseagreen": "20B2AA", + "lightskyblue": "87CEFA", + "lightslategray": "778899", + "lightslategrey": "778899", + "lightsteelblue": "B0C4DE", + "lightyellow": "FFFFE0", + "lime": "00FF00", + "limegreen": "32CD32", + "linen": "FAF0E6", + "magenta": "FF00FF", + "maroon": "800000", + "mediumaquamarine": "66CDAA", + "mediumblue": "0000CD", + "mediumorchid": "BA55D3", + "mediumpurple": "9370DB", + "mediumseagreen": "3CB371", + "mediumslateblue": "7B68EE", + "mediumspringgreen": "00FA9A", + "mediumturquoise": "48D1CC", + "mediumvioletred": "C71585", + "midnightblue": "191970", + "mintcream": "F5FFFA", + "mistyrose": "FFE4E1", + "moccasin": "FFE4B5", + "navajowhite": "FFDEAD", + "navy": "000080", + "oldlace": "FDF5E6", + "olive": "808000", + "olivedrab": "6B8E23", + "orange": "FFA500", + "orangered": "FF4500", + "orchid": "DA70D6", + "palegoldenrod": "EEE8AA", + "palegreen": "98FB98", + "paleturquoise": "AFEEEE", + "palevioletred": "DB7093", + "papayawhip": "FFEFD5", + "peachpuff": "FFDAB9", + "peru": "CD853F", + "pink": "FFC0CB", + "plum": "DDA0DD", + "powderblue": "B0E0E6", + "purple": "800080", + "rebeccapurple": "663399", + "red": "FF0000", + "rosybrown": "BC8F8F", + "royalblue": "4169E1", + "saddlebrown": "8B4513", + "salmon": "FA8072", + "sandybrown": "F4A460", + "seagreen": "2E8B57", + "seashell": "FFF5EE", + "sienna": "A0522D", + "silver": "C0C0C0", + "skyblue": "87CEEB", + "slateblue": "6A5ACD", + "slategray": "708090", + "slategrey": "708090", + "snow": "FFFAFA", + "springgreen": "00FF7F", + "steelblue": "4682B4", + "tan": "D2B48C", + "teal": "008080", + "thistle": "D8BFD8", + "tomato": "FF6347", + "turquoise": "40E0D0", + "violet": "EE82EE", + "wheat": "F5DEB3", + "white": "FFFFFF", + "whitesmoke": "F5F5F5", + "yellow": "FFFF00", + "yellowgreen": "9ACD32", +} diff --git a/pandas/io/formats/excel.py b/pandas/io/formats/excel.py index 00b526ffd6c16..7bfda91843da9 100644 --- a/pandas/io/formats/excel.py +++ b/pandas/io/formats/excel.py @@ -25,6 +25,8 @@ from pandas.io.formats.format import get_level_lengths from pandas.io.formats.printing import pprint_thing +from ._color_data import CSS4_COLORS + class ExcelCell: __fields__ = ("row", "col", "val", "style", "mergestart", "mergeend") @@ -65,157 +67,7 @@ class CSSToExcelConverter: CSS processed by :meth:`__call__`. """ - # source: matplotlib 3.3.3, matplotlib.colors.CSS4_COLORS - NAMED_COLORS = { - "aliceblue": "F0F8FF", - "antiquewhite": "FAEBD7", - "aqua": "00FFFF", - "aquamarine": "7FFFD4", - "azure": "F0FFFF", - "beige": "F5F5DC", - "bisque": "FFE4C4", - "black": "000000", - "blanchedalmond": "FFEBCD", - "blue": "0000FF", - "blueviolet": "8A2BE2", - "brown": "A52A2A", - "burlywood": "DEB887", - "cadetblue": "5F9EA0", - "chartreuse": "7FFF00", - "chocolate": "D2691E", - "coral": "FF7F50", - "cornflowerblue": "6495ED", - "cornsilk": "FFF8DC", - "crimson": "DC143C", - "cyan": "00FFFF", - "darkblue": "00008B", - "darkcyan": "008B8B", - "darkgoldenrod": "B8860B", - "darkgray": "A9A9A9", - "darkgreen": "006400", - "darkgrey": "A9A9A9", - "darkkhaki": "BDB76B", - "darkmagenta": "8B008B", - "darkolivegreen": "556B2F", - "darkorange": "FF8C00", - "darkorchid": "9932CC", - "darkred": "8B0000", - "darksalmon": "E9967A", - "darkseagreen": "8FBC8F", - "darkslateblue": "483D8B", - "darkslategray": "2F4F4F", - "darkslategrey": "2F4F4F", - "darkturquoise": "00CED1", - "darkviolet": "9400D3", - "deeppink": "FF1493", - "deepskyblue": "00BFFF", - "dimgray": "696969", - "dimgrey": "696969", - "dodgerblue": "1E90FF", - "firebrick": "B22222", - "floralwhite": "FFFAF0", - "forestgreen": "228B22", - "fuchsia": "FF00FF", - "gainsboro": "DCDCDC", - "ghostwhite": "F8F8FF", - "gold": "FFD700", - "goldenrod": "DAA520", - "gray": "808080", - "green": "008000", - "greenyellow": "ADFF2F", - "grey": "808080", - "honeydew": "F0FFF0", - "hotpink": "FF69B4", - "indianred": "CD5C5C", - "indigo": "4B0082", - "ivory": "FFFFF0", - "khaki": "F0E68C", - "lavender": "E6E6FA", - "lavenderblush": "FFF0F5", - "lawngreen": "7CFC00", - "lemonchiffon": "FFFACD", - "lightblue": "ADD8E6", - "lightcoral": "F08080", - "lightcyan": "E0FFFF", - "lightgoldenrodyellow": "FAFAD2", - "lightgray": "D3D3D3", - "lightgreen": "90EE90", - "lightgrey": "D3D3D3", - "lightpink": "FFB6C1", - "lightsalmon": "FFA07A", - "lightseagreen": "20B2AA", - "lightskyblue": "87CEFA", - "lightslategray": "778899", - "lightslategrey": "778899", - "lightsteelblue": "B0C4DE", - "lightyellow": "FFFFE0", - "lime": "00FF00", - "limegreen": "32CD32", - "linen": "FAF0E6", - "magenta": "FF00FF", - "maroon": "800000", - "mediumaquamarine": "66CDAA", - "mediumblue": "0000CD", - "mediumorchid": "BA55D3", - "mediumpurple": "9370DB", - "mediumseagreen": "3CB371", - "mediumslateblue": "7B68EE", - "mediumspringgreen": "00FA9A", - "mediumturquoise": "48D1CC", - "mediumvioletred": "C71585", - "midnightblue": "191970", - "mintcream": "F5FFFA", - "mistyrose": "FFE4E1", - "moccasin": "FFE4B5", - "navajowhite": "FFDEAD", - "navy": "000080", - "oldlace": "FDF5E6", - "olive": "808000", - "olivedrab": "6B8E23", - "orange": "FFA500", - "orangered": "FF4500", - "orchid": "DA70D6", - "palegoldenrod": "EEE8AA", - "palegreen": "98FB98", - "paleturquoise": "AFEEEE", - "palevioletred": "DB7093", - "papayawhip": "FFEFD5", - "peachpuff": "FFDAB9", - "peru": "CD853F", - "pink": "FFC0CB", - "plum": "DDA0DD", - "powderblue": "B0E0E6", - "purple": "800080", - "rebeccapurple": "663399", - "red": "FF0000", - "rosybrown": "BC8F8F", - "royalblue": "4169E1", - "saddlebrown": "8B4513", - "salmon": "FA8072", - "sandybrown": "F4A460", - "seagreen": "2E8B57", - "seashell": "FFF5EE", - "sienna": "A0522D", - "silver": "C0C0C0", - "skyblue": "87CEEB", - "slateblue": "6A5ACD", - "slategray": "708090", - "slategrey": "708090", - "snow": "FFFAFA", - "springgreen": "00FF7F", - "steelblue": "4682B4", - "tan": "D2B48C", - "teal": "008080", - "thistle": "D8BFD8", - "tomato": "FF6347", - "turquoise": "40E0D0", - "violet": "EE82EE", - "wheat": "F5DEB3", - "white": "FFFFFF", - "whitesmoke": "F5F5F5", - "yellow": "FFFF00", - "yellowgreen": "9ACD32", - } + NAMED_COLORS = CSS4_COLORS VERTICAL_MAP = { "top": "top", From 0f74d17ca0a66ff3623d40be547c563cc0fb670a Mon Sep 17 00:00:00 2001 From: lpc Date: Fri, 4 Dec 2020 19:07:25 +0100 Subject: [PATCH 5/5] cr: comments + fully qualified import + whatsnew --- doc/source/whatsnew/v1.2.0.rst | 1 + pandas/io/formats/_color_data.py | 4 ++++ pandas/io/formats/excel.py | 3 +-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v1.2.0.rst b/doc/source/whatsnew/v1.2.0.rst index e6e5a619b996a..1b9ab9004d82a 100644 --- a/doc/source/whatsnew/v1.2.0.rst +++ b/doc/source/whatsnew/v1.2.0.rst @@ -291,6 +291,7 @@ Other enhancements - Improve numerical stability for :meth:`.Rolling.skew`, :meth:`.Rolling.kurt`, :meth:`Expanding.skew` and :meth:`Expanding.kurt` through implementation of Kahan summation (:issue:`6929`) - Improved error reporting for subsetting columns of a :class:`.DataFrameGroupBy` with ``axis=1`` (:issue:`37725`) - Implement method ``cross`` for :meth:`DataFrame.merge` and :meth:`DataFrame.join` (:issue:`5401`) +- Augmented the list of named colors available for styling Excel exports, enabling all of CSS4 colors (:issue:`38247`) .. --------------------------------------------------------------------------- diff --git a/pandas/io/formats/_color_data.py b/pandas/io/formats/_color_data.py index 8f68bf26f2961..e5b72b2befa4f 100644 --- a/pandas/io/formats/_color_data.py +++ b/pandas/io/formats/_color_data.py @@ -1,3 +1,7 @@ +# GH37967: Enable the use of CSS named colors, as defined in +# matplotlib.colors.CSS4_COLORS, when exporting to Excel. +# This data has been copied here, instead of being imported from matplotlib, +# not to have ``to_excel`` methods require matplotlib. # source: matplotlib._color_data (3.3.3) CSS4_COLORS = { "aliceblue": "F0F8FF", diff --git a/pandas/io/formats/excel.py b/pandas/io/formats/excel.py index 7bfda91843da9..c59c964c62da0 100644 --- a/pandas/io/formats/excel.py +++ b/pandas/io/formats/excel.py @@ -21,12 +21,11 @@ from pandas.core import generic import pandas.core.common as com +from pandas.io.formats._color_data import CSS4_COLORS from pandas.io.formats.css import CSSResolver, CSSWarning from pandas.io.formats.format import get_level_lengths from pandas.io.formats.printing import pprint_thing -from ._color_data import CSS4_COLORS - class ExcelCell: __fields__ = ("row", "col", "val", "style", "mergestart", "mergeend")