Skip to content
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
12 changes: 10 additions & 2 deletions ultraplot/axes/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -7632,9 +7632,16 @@ def tripcolor(self, *args, **kwargs):
# Update kwargs and handle cmap
kw.update(_pop_props(kw, "collection"))

# NOTE: Matplotlib colors either the vertices, from the positional z, or
# the faces, from the 'facecolors' keyword. Since the input parser pads
# missing positional arguments with None, forwarding a null z would make
# matplotlib warn that the positional parameter has no effect.
values = z
if z is None:
values = kw.get("facecolors", None)
center_levels = kw.pop("center_levels", None)
kw = self._parse_cmap(
triangulation.x, triangulation.y, z, center_levels=center_levels, **kw
triangulation.x, triangulation.y, values, center_levels=center_levels, **kw
)

# Handle patch edges, labels, and guide parameters
Expand All @@ -7643,8 +7650,9 @@ def tripcolor(self, *args, **kwargs):
guide_kw = _pop_params(kw, self._update_guide)

# Plot with the native tripcolor method
zs = () if z is None else (z,)
with self._keep_grid_bools():
m = self._call_native("tripcolor", triangulation, z, **kw)
m = self._call_native("tripcolor", triangulation, *zs, **kw)

# Fix edges and add labels
self._fix_patch_edges(m, **edgefix_kw, **kw)
Expand Down
57 changes: 57 additions & 0 deletions ultraplot/tests/test_2dplots.py
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,63 @@ def test_tricontour_levels_respect_explicit_vmin_vmax():
assert m.norm(0.5) == pytest.approx(0.625)


def _triangulation():
"""
Return a two-triangle unit square, for the tripcolor tests below.
"""
from matplotlib.tri import Triangulation

return Triangulation(
[0.0, 1.0, 0.0, 1.0],
[0.0, 0.0, 1.0, 1.0],
[[0, 1, 2], [1, 3, 2]],
)


def test_tripcolor_facecolors_without_z():
"""
Coloring the faces needs no z, and must not warn about a positional c.

The input parser pads absent positional arguments with None, and forwarding
that null z made matplotlib warn that the positional parameter had no
effect. See the tripcolor override in `ultraplot.axes.plot`.
"""
facecolors = np.array([1.0, 2.0])
_, ax = uplt.subplots()
with warnings.catch_warnings():
warnings.simplefilter("error", UserWarning)
m = ax.tripcolor(_triangulation(), facecolors=facecolors)
assert np.array_equal(m.get_array(), facecolors)
assert m.get_clim() == pytest.approx((1.0, 2.0))


def test_tripcolor_vertex_values_unaffected():
"""
Passing z still colors the vertices, and still sets the color limits.
"""
z = np.array([0.0, 1.0, 2.0, 3.0])
_, ax = uplt.subplots()
with warnings.catch_warnings():
warnings.simplefilter("error", UserWarning)
m = ax.tripcolor(_triangulation(), z)
vmin, vmax = m.get_clim()
assert vmin == pytest.approx(0.0)
assert vmax == pytest.approx(3.0, abs=1e-6)


def test_tripcolor_warns_when_z_and_facecolors_given():
"""
Supplying both is a real conflict: matplotlib discards z, and says so.
"""
_, ax = uplt.subplots()
with pytest.warns(UserWarning, match="Positional parameter c has no effect"):
ax.tripcolor(
_triangulation(),
np.array([0.0, 1.0, 2.0, 3.0]),
facecolors=np.array([1.0, 2.0]),
)


def test_tricontour_explicit_colors_match_levels():
"""
Explicit triangular contour colors should map one-to-one with levels.
Expand Down