Skip to content

Commit e2a89c5

Browse files
authored
Merge pull request #5662 from genrichez/fix-hex-to-rgb-shorthand
fix: handle 3-digit shorthand hex in hex_to_rgb
2 parents c67493d + 82fe3cf commit e2a89c5

4 files changed

Lines changed: 24 additions & 18 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
44

55
## Unreleased
66

7+
### Fixed
8+
- Fix `hex_to_rgb` parsing of 3-digit shorthand hexadecimal colors such as `#FFF` [[#5662](https://github.com/plotly/plotly.py/pull/5662)], with thanks to @genrichez for the contribution!
9+
710

811
## [6.9.0] - 2026-07-09
912

_plotly_utils/colors/__init__.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -752,11 +752,20 @@ def hex_to_rgb(value):
752752
"""
753753
Calculates rgb values from a hex color code.
754754
755-
:param (string) value: Hex color string
755+
:param (string) value: Hex color string. May be a full 6-character code
756+
or a 3-character shorthand code.
756757
757758
:rtype (tuple) (r_value, g_value, b_value): tuple of rgb values
759+
760+
Example:
761+
762+
'#FFFFFF' --> (255, 255, 255)
763+
'#FFF' --> (255, 255, 255)
764+
758765
"""
759766
value = value.lstrip("#")
767+
if len(value) == 3:
768+
value = "".join(c * 2 for c in value)
760769
hex_total_length = len(value)
761770
rgb_section_length = hex_total_length // 3
762771
return tuple(

plotly/matplotlylib/mpltools.py

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
import warnings
1111
import matplotlib.dates
1212

13+
from _plotly_utils.colors import hex_to_rgb
14+
1315

1416
def check_bar_match(old_bar, new_bar):
1517
"""Check if two bars belong in the same collection (bar chart).
@@ -104,23 +106,6 @@ def convert_symbol(mpl_symbol):
104106
return "circle" # default
105107

106108

107-
def hex_to_rgb(value):
108-
"""
109-
Change a hex color to an rgb tuple
110-
111-
:param (str|unicode) value: The hex string we want to convert.
112-
:return: (int, int, int) The red, green, blue int-tuple.
113-
114-
Example:
115-
116-
'#FFFFFF' --> (255, 255, 255)
117-
118-
"""
119-
value = value.lstrip("#")
120-
lv = len(value)
121-
return tuple(int(value[i : i + lv // 3], 16) for i in range(0, lv, lv // 3))
122-
123-
124109
def merge_color_and_opacity(color, opacity):
125110
"""
126111
Merge hex color with an alpha (opacity) to get an rgba tuple.

tests/test_plotly_utils/colors/test_color_conversions.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,15 @@ def test_hex_to_rgb_basic_values():
1212
assert hex_to_rgb("#aabbcc") == (170, 187, 204)
1313

1414

15+
def test_hex_to_rgb_shorthand_3_digit():
16+
assert hex_to_rgb("#fff") == (255, 255, 255)
17+
assert hex_to_rgb("#000") == (0, 0, 0)
18+
assert hex_to_rgb("#abc") == (170, 187, 204)
19+
assert hex_to_rgb("#f00") == (255, 0, 0)
20+
assert hex_to_rgb("#0f0") == (0, 255, 0)
21+
assert hex_to_rgb("#00f") == (0, 0, 255)
22+
23+
1524
def test_label_rgb_formats_tuple():
1625
assert label_rgb((255, 0, 0)) == "rgb(255, 0, 0)"
1726
assert label_rgb((1, 2, 3)) == "rgb(1, 2, 3)"

0 commit comments

Comments
 (0)