Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2c8f24f

Browse files
committed
Deprecate QuadContourSet.allsegs, .allkinds, .tcolors, .tlinewidths.
Directly construct the relevant path objects and the collections with the right properties instead of carrying around another copy of the information in raw array form. By having fewer intermediate objects lying around for a long time (as attributes of the QuadContourSet) this makes the logic easier to follow.
1 parent a046ee3 commit 2c8f24f

File tree

4 files changed

+48
-39
lines changed

4 files changed

+48
-39
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
``allsegs``, ``allkinds``, ``tcolors`` and ``tlinewidths`` attributes of `.ContourSet`
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
These attributes are deprecated; if required, directly retrieve the vertices
4+
and codes of the Path objects in ``QuadContourSet.collections`` and the colors
5+
and the linewidths of these collections.

lib/matplotlib/colorbar.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -774,8 +774,8 @@ def add_lines(self, *args, **kwargs):
774774
# TODO: Make colorbar lines auto-follow changes in contour lines.
775775
return self.add_lines(
776776
CS.levels,
777-
[c[0] for c in CS.tcolors],
778-
[t[0] for t in CS.tlinewidths],
777+
CS.to_rgba(CS.cvalues, CS.alpha),
778+
[coll.get_linewidths()[0] for coll in CS.collections],
779779
erase=erase)
780780
else:
781781
self, levels, colors, linewidths, erase = params.values()

lib/matplotlib/contour.py

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
"""
44

55
import functools
6-
import itertools
76
from numbers import Integral
87

98
import numpy as np
@@ -767,6 +766,10 @@ def __init__(self, ax, *args,
767766
self.negative_linestyles = \
768767
mpl.rcParams['contour.negative_linestyle']
769768

769+
# The base class _process_args will update _allpaths, which gets picked
770+
# up by _get_allpaths below. OTOH the _process_args of subclasses
771+
# leave _allpaths as None and instead set _contour_generator.
772+
self._allpaths = None
770773
kwargs = self._process_args(*args, **kwargs)
771774
self._process_levels()
772775

@@ -820,23 +823,7 @@ def __init__(self, ax, *args,
820823
self.norm.vmax = vmax
821824
self._process_colors()
822825

823-
if getattr(self, 'allsegs', None) is None:
824-
self.allsegs, self.allkinds = self._get_allsegs_and_allkinds()
825-
elif self.allkinds is None:
826-
# allsegs specified in constructor may or may not have allkinds as
827-
# well. Must ensure allkinds can be zipped below.
828-
self.allkinds = [None] * len(self.allsegs)
829-
830-
# Each entry in (allsegs, allkinds) is a list of (segs, kinds) which
831-
# specifies a list of Paths: segs is a list of (N, 2) arrays of xy
832-
# coordinates, kinds is a list of arrays of corresponding pathcodes.
833-
# However, kinds can also be None; in which case all paths in that list
834-
# are codeless.
835-
allpaths = [
836-
[*map(mpath.Path,
837-
segs,
838-
kinds if kinds is not None else itertools.repeat(None))]
839-
for segs, kinds in zip(self.allsegs, self.allkinds)]
826+
allpaths = self._get_allpaths()
840827

841828
if self.filled:
842829
if self.linewidths is not None:
@@ -857,7 +844,7 @@ def __init__(self, ax, *args,
857844
for level, level_upper, paths
858845
in zip(lowers, uppers, allpaths)]
859846
else:
860-
self.tlinewidths = tlinewidths = self._process_linewidths()
847+
tlinewidths = self._process_linewidths()
861848
tlinestyles = self._process_linestyles()
862849
aa = self.antialiased
863850
if aa is not None:
@@ -895,6 +882,15 @@ def __init__(self, ax, *args,
895882
", ".join(map(repr, kwargs))
896883
)
897884

885+
allsegs = _api.deprecated("3.8")(property(lambda self: [
886+
p.vertices for c in self.collections for p in c.get_paths()]))
887+
allkinds = _api.deprecated("3.8")(property(lambda self: [
888+
p.codes for c in self.collections for p in c.get_paths()]))
889+
tcolors = _api.deprecated("3.8")(property(lambda self: [
890+
(tuple(rgba),) for rgba in self.to_rgba(self.cvalues, self.alpha)]))
891+
tlinewidths = _api.deprecated("3.8")(
892+
property(lambda self: self._process_linewidths()))
893+
898894
def get_transform(self):
899895
"""Return the `.Transform` instance used by this ContourSet."""
900896
if self._transform is None:
@@ -979,51 +975,60 @@ def _process_args(self, *args, **kwargs):
979975
Must set self.levels, self.zmin and self.zmax, and update axes limits.
980976
"""
981977
self.levels = args[0]
982-
self.allsegs = args[1]
983-
self.allkinds = args[2] if len(args) > 2 else None
978+
allsegs = args[1]
979+
allkinds = args[2] if len(args) > 2 else None
984980
self.zmax = np.max(self.levels)
985981
self.zmin = np.min(self.levels)
986982

983+
if allkinds is None:
984+
allkinds = [[None] * len(segs) for segs in allsegs]
985+
987986
# Check lengths of levels and allsegs.
988987
if self.filled:
989-
if len(self.allsegs) != len(self.levels) - 1:
988+
if len(allsegs) != len(self.levels) - 1:
990989
raise ValueError('must be one less number of segments as '
991990
'levels')
992991
else:
993-
if len(self.allsegs) != len(self.levels):
992+
if len(allsegs) != len(self.levels):
994993
raise ValueError('must be same number of segments as levels')
995994

996995
# Check length of allkinds.
997-
if (self.allkinds is not None and
998-
len(self.allkinds) != len(self.allsegs)):
996+
if len(allkinds) != len(allsegs):
999997
raise ValueError('allkinds has different length to allsegs')
1000998

1001999
# Determine x, y bounds and update axes data limits.
1002-
flatseglist = [s for seg in self.allsegs for s in seg]
1000+
flatseglist = [s for seg in allsegs for s in seg]
10031001
points = np.concatenate(flatseglist, axis=0)
10041002
self._mins = points.min(axis=0)
10051003
self._maxs = points.max(axis=0)
10061004

1005+
# Each entry in (allsegs, allkinds) is a list of (segs, kinds) which
1006+
# specifies a list of Paths: segs is a list of (N, 2) arrays of xy
1007+
# coordinates, kinds is a list of arrays of corresponding pathcodes.
1008+
# However, kinds can also be None; in which case all paths in that list
1009+
# are codeless (this case is normalized above).
1010+
self._allpaths = [[*map(mpath.Path, segs, kinds)]
1011+
for segs, kinds in zip(allsegs, allkinds)]
1012+
10071013
return kwargs
10081014

1009-
def _get_allsegs_and_allkinds(self):
1010-
"""Compute ``allsegs`` and ``allkinds`` using C extension."""
1011-
allsegs = []
1012-
allkinds = []
1015+
def _get_allpaths(self):
1016+
"""Compute ``allpaths`` using C extension."""
1017+
if self._allpaths is not None:
1018+
return self._allpaths
1019+
allpaths = []
10131020
if self.filled:
10141021
lowers, uppers = self._get_lowers_and_uppers()
10151022
for level, level_upper in zip(lowers, uppers):
10161023
vertices, kinds = \
10171024
self._contour_generator.create_filled_contour(
10181025
level, level_upper)
1019-
allsegs.append(vertices)
1020-
allkinds.append(kinds)
1026+
allpaths.append([*map(mpath.Path, vertices, kinds)])
10211027
else:
10221028
for level in self.levels:
10231029
vertices, kinds = self._contour_generator.create_contour(level)
1024-
allsegs.append(vertices)
1025-
allkinds.append(kinds)
1026-
return allsegs, allkinds
1030+
allpaths.append([*map(mpath.Path, vertices, kinds)])
1031+
return allpaths
10271032

10281033
def _get_lowers_and_uppers(self):
10291034
"""
@@ -1052,7 +1057,6 @@ def changed(self):
10521057
self.norm.autoscale_None(self.levels)
10531058
tcolors = [(tuple(rgba),)
10541059
for rgba in self.to_rgba(self.cvalues, alpha=self.alpha)]
1055-
self.tcolors = tcolors
10561060
hatches = self.hatches * len(tcolors)
10571061
for color, hatch, collection in zip(tcolors, hatches,
10581062
self.collections):

lib/matplotlib/tests/test_contour.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ def test_contour_linewidth(
365365
fig, ax = plt.subplots()
366366
X = np.arange(4*3).reshape(4, 3)
367367
cs = ax.contour(X, linewidths=call_linewidths)
368-
assert cs.tlinewidths[0][0] == expected
368+
assert cs.collections[0].get_linewidths()[0] == expected
369369

370370

371371
@pytest.mark.backend("pdf")

0 commit comments

Comments
 (0)