Skip to content

Commit 5db8071

Browse files
committed
Handle single colors in ContourSet
1 parent 4310fff commit 5db8071

File tree

3 files changed

+52
-10
lines changed

3 files changed

+52
-10
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
Specifying a single color in ``contour`` and ``contourf``
2+
---------------------------------------------------------
3+
4+
`~.Axes.contour` and `~.Axes.contourf` previously accepted a single color
5+
provided it was expressed as a string. This restriction has now been removed
6+
and a single color in any format described in the :ref:`colors_def` tutorial
7+
may be passed.
8+
9+
.. plot::
10+
:include-source: true
11+
:alt: Two-panel example contour plots. The left panel has all transparent red contours. The right panel has all dark blue contours.
12+
13+
import matplotlib.pyplot as plt
14+
15+
fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(6, 3))
16+
z = [[0, 1], [1, 2]]
17+
18+
ax1.contour(z, colors=('r', 0.4))
19+
ax2.contour(z, colors=(0.1, 0.2, 0.5))
20+
21+
plt.show()

lib/matplotlib/contour.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,11 @@ def __init__(self, ax, *args,
702702
self._extend_min = self.extend in ['min', 'both']
703703
self._extend_max = self.extend in ['max', 'both']
704704
if self.colors is not None:
705+
if mcolors.is_color_like(self.colors):
706+
color_sequence = [self.colors]
707+
else:
708+
color_sequence = self.colors
709+
705710
ncolors = len(self.levels)
706711
if self.filled:
707712
ncolors -= 1
@@ -718,19 +723,19 @@ def __init__(self, ax, *args,
718723
total_levels = (ncolors +
719724
int(self._extend_min) +
720725
int(self._extend_max))
721-
if (len(self.colors) == total_levels and
726+
if (len(color_sequence) == total_levels and
722727
(self._extend_min or self._extend_max)):
723728
use_set_under_over = True
724729
if self._extend_min:
725730
i0 = 1
726731

727-
cmap = mcolors.ListedColormap(self.colors[i0:None], N=ncolors)
732+
cmap = mcolors.ListedColormap(color_sequence[i0:None], N=ncolors)
728733

729734
if use_set_under_over:
730735
if self._extend_min:
731-
cmap.set_under(self.colors[0])
736+
cmap.set_under(color_sequence[0])
732737
if self._extend_max:
733-
cmap.set_over(self.colors[-1])
738+
cmap.set_over(color_sequence[-1])
734739

735740
# label lists must be initialized here
736741
self.labelTexts = []
@@ -1498,10 +1503,12 @@ def _initialize_x_y(self, z):
14981503
The sequence is cycled for the levels in ascending order. If the
14991504
sequence is shorter than the number of levels, it's repeated.
15001505
1501-
As a shortcut, single color strings may be used in place of
1502-
one-element lists, i.e. ``'red'`` instead of ``['red']`` to color
1503-
all levels with the same color. This shortcut does only work for
1504-
color strings, not for other ways of specifying colors.
1506+
As a shortcut, a single color may be used in place of one-element lists, i.e.
1507+
``'red'`` instead of ``['red']`` to color all levels with the same color.
1508+
1509+
.. versionchanged:: 3.10
1510+
Previously a single color had to be expressed as a string, but now any
1511+
valid color format may be passed.
15051512
15061513
By default (value *None*), the colormap specified by *cmap*
15071514
will be used.
@@ -1569,10 +1576,10 @@ def _initialize_x_y(self, z):
15691576
15701577
An existing `.QuadContourSet` does not get notified if
15711578
properties of its colormap are changed. Therefore, an explicit
1572-
call `.QuadContourSet.changed()` is needed after modifying the
1579+
call ``QuadContourSet.changed()`` is needed after modifying the
15731580
colormap. The explicit call can be left out, if a colorbar is
15741581
assigned to the `.QuadContourSet` because it internally calls
1575-
`.QuadContourSet.changed()`.
1582+
``QuadContourSet.changed()``.
15761583
15771584
Example::
15781585

lib/matplotlib/tests/test_contour.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,20 @@ def test_given_colors_levels_and_extends():
171171
plt.colorbar(c, ax=ax)
172172

173173

174+
@pytest.mark.parametrize('color, extend', [('darkred', 'neither'),
175+
('darkred', 'both'),
176+
(('r', 0.5), 'neither'),
177+
((0.1, 0.2, 0.5, 0.3), 'neither')])
178+
def test_single_color_and_extend(color, extend):
179+
z = [[0, 1], [1, 2]]
180+
181+
_, ax = plt.subplots()
182+
levels = [0.5, 0.75, 1, 1.25, 1.5]
183+
cs = ax.contour(z, levels=levels, colors=color, extend=extend)
184+
for c in cs.get_edgecolors():
185+
assert same_color(c, color)
186+
187+
174188
@image_comparison(['contour_log_locator.svg'], style='mpl20', remove_text=False)
175189
def test_log_locator_levels():
176190

0 commit comments

Comments
 (0)