Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 464dcf6

Browse filesBrowse files
authored
Merge pull request #19033 from anntzer/class-factories
Templatize class factories.
2 parents 401aa2f + 15f3b92 commit 464dcf6
Copy full SHA for 464dcf6

File tree

Expand file treeCollapse file tree

8 files changed

+108
-162
lines changed
Filter options
Expand file treeCollapse file tree

8 files changed

+108
-162
lines changed
+6Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
The private ``matplotlib.axes._subplots._subplot_classes`` dict has been removed
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
4+
Support for passing ``None`` to ``subplot_class_factory`` has been removed
5+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6+
Explicitly pass in the base `~matplotlib.axes.Axes` class instead.

‎doc/missing-references.json

Copy file name to clipboardExpand all lines: doc/missing-references.json
+32-61Lines changed: 32 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
"doc/users/prev_whats_new/whats_new_3.1.0.rst:335"
2121
],
2222
"cbar_axes": [
23-
"lib/mpl_toolkits/axes_grid1/axes_grid.py:docstring of mpl_toolkits.axes_grid1.axes_grid.ImageGrid.__init__:45",
2423
"lib/mpl_toolkits/axes_grid1/axes_grid.py:docstring of mpl_toolkits.axes_grid1.axes_grid.ImageGrid:45",
2524
"lib/mpl_toolkits/axisartist/axes_grid.py:docstring of mpl_toolkits.axisartist.axes_grid.ImageGrid:45"
2625
],
@@ -79,39 +78,35 @@
7978
],
8079
"matplotlib.axes.Axes.lines": [
8180
"doc/tutorials/intermediate/artists.rst:100",
82-
"doc/tutorials/intermediate/artists.rst:440"
81+
"doc/tutorials/intermediate/artists.rst:442"
8382
],
8483
"matplotlib.axes.Axes.patch": [
8584
"doc/api/prev_api_changes/api_changes_0.98.x.rst:89",
86-
"doc/tutorials/intermediate/artists.rst:186",
87-
"doc/tutorials/intermediate/artists.rst:424"
85+
"doc/tutorials/intermediate/artists.rst:187",
86+
"doc/tutorials/intermediate/artists.rst:426"
8887
],
8988
"matplotlib.axes.Axes.patches": [
90-
"doc/tutorials/intermediate/artists.rst:463"
89+
"doc/tutorials/intermediate/artists.rst:465"
9190
],
9291
"matplotlib.axes.Axes.transAxes": [
93-
"lib/mpl_toolkits/axes_grid1/anchored_artists.py:docstring of mpl_toolkits.axes_grid1.anchored_artists.AnchoredDirectionArrows.__init__:8",
9492
"lib/mpl_toolkits/axes_grid1/anchored_artists.py:docstring of mpl_toolkits.axes_grid1.anchored_artists.AnchoredDirectionArrows:8"
9593
],
9694
"matplotlib.axes.Axes.transData": [
97-
"lib/mpl_toolkits/axes_grid1/anchored_artists.py:docstring of mpl_toolkits.axes_grid1.anchored_artists.AnchoredAuxTransformBox.__init__:11",
9895
"lib/mpl_toolkits/axes_grid1/anchored_artists.py:docstring of mpl_toolkits.axes_grid1.anchored_artists.AnchoredAuxTransformBox:11",
99-
"lib/mpl_toolkits/axes_grid1/anchored_artists.py:docstring of mpl_toolkits.axes_grid1.anchored_artists.AnchoredEllipse.__init__:8",
10096
"lib/mpl_toolkits/axes_grid1/anchored_artists.py:docstring of mpl_toolkits.axes_grid1.anchored_artists.AnchoredEllipse:8",
101-
"lib/mpl_toolkits/axes_grid1/anchored_artists.py:docstring of mpl_toolkits.axes_grid1.anchored_artists.AnchoredSizeBar.__init__:8",
10297
"lib/mpl_toolkits/axes_grid1/anchored_artists.py:docstring of mpl_toolkits.axes_grid1.anchored_artists.AnchoredSizeBar:8"
10398
],
10499
"matplotlib.axes.Axes.viewLim": [
105100
"doc/api/prev_api_changes/api_changes_0.99.x.rst:23"
106101
],
107102
"matplotlib.axes.Axes.xaxis": [
108-
"doc/tutorials/intermediate/artists.rst:608"
103+
"doc/tutorials/intermediate/artists.rst:610"
109104
],
110105
"matplotlib.axes.Axes.yaxis": [
111-
"doc/tutorials/intermediate/artists.rst:608"
106+
"doc/tutorials/intermediate/artists.rst:610"
112107
],
113108
"matplotlib.axis.Axis.label": [
114-
"doc/tutorials/intermediate/artists.rst:655"
109+
"doc/tutorials/intermediate/artists.rst:657"
115110
],
116111
"matplotlib.cm.ScalarMappable.callbacksSM": [
117112
"doc/api/prev_api_changes/api_changes_0.98.0.rst:10"
@@ -124,11 +119,11 @@
124119
],
125120
"matplotlib.figure.Figure.patch": [
126121
"doc/api/prev_api_changes/api_changes_0.98.x.rst:89",
127-
"doc/tutorials/intermediate/artists.rst:186",
128-
"doc/tutorials/intermediate/artists.rst:319"
122+
"doc/tutorials/intermediate/artists.rst:187",
123+
"doc/tutorials/intermediate/artists.rst:320"
129124
],
130125
"matplotlib.figure.Figure.transFigure": [
131-
"doc/tutorials/intermediate/artists.rst:368"
126+
"doc/tutorials/intermediate/artists.rst:369"
132127
],
133128
"max": [
134129
"lib/matplotlib/transforms.py:docstring of matplotlib.transforms.Bbox.p1:4"
@@ -256,15 +251,6 @@
256251
"doc/tutorials/intermediate/artists.rst:44",
257252
"doc/tutorials/intermediate/artists.rst:67"
258253
],
259-
"matplotlib.axes._axes.Axes": [
260-
"doc/api/artist_api.rst:189",
261-
"doc/api/axes_api.rst:609",
262-
"lib/matplotlib/projections/geo.py:docstring of matplotlib.projections.geo.GeoAxes:1",
263-
"lib/matplotlib/projections/polar.py:docstring of matplotlib.projections.polar.PolarAxes:1",
264-
"lib/mpl_toolkits/axes_grid1/mpl_axes.py:docstring of mpl_toolkits.axes_grid1.mpl_axes.Axes:1",
265-
"lib/mpl_toolkits/axisartist/axislines.py:docstring of mpl_toolkits.axisartist.axislines.Axes:1",
266-
"lib/mpl_toolkits/mplot3d/axes3d.py:docstring of mpl_toolkits.mplot3d.axes3d.Axes3D:1"
267-
],
268254
"matplotlib.axes._base._AxesBase": [
269255
"doc/api/artist_api.rst:189",
270256
"doc/api/axes_api.rst:609",
@@ -428,16 +414,6 @@
428414
"lib/matplotlib/transforms.py:docstring of matplotlib.transforms.BlendedAffine2D:1",
429415
"lib/matplotlib/transforms.py:docstring of matplotlib.transforms.BlendedGenericTransform:1"
430416
],
431-
"matplotlib.tri.trifinder.TriFinder": [
432-
"lib/matplotlib/tri/trifinder.py:docstring of matplotlib.tri.trifinder.TrapezoidMapTriFinder:1"
433-
],
434-
"matplotlib.tri.triinterpolate.TriInterpolator": [
435-
"lib/matplotlib/tri/triinterpolate.py:docstring of matplotlib.tri.triinterpolate.CubicTriInterpolator:1",
436-
"lib/matplotlib/tri/triinterpolate.py:docstring of matplotlib.tri.triinterpolate.LinearTriInterpolator:1"
437-
],
438-
"matplotlib.tri.trirefine.TriRefiner": [
439-
"lib/matplotlib/tri/trirefine.py:docstring of matplotlib.tri.trirefine.UniformTriRefiner:1"
440-
],
441417
"matplotlib.widgets._SelectorWidget": [
442418
"lib/matplotlib/widgets.py:docstring of matplotlib.widgets.LassoSelector:1",
443419
"lib/matplotlib/widgets.py:docstring of matplotlib.widgets.PolygonSelector:1",
@@ -485,7 +461,7 @@
485461
"lib/mpl_toolkits/axisartist/axislines.py:docstring of mpl_toolkits.axisartist.axislines.AxisArtistHelper.Fixed:1",
486462
"lib/mpl_toolkits/axisartist/axislines.py:docstring of mpl_toolkits.axisartist.axislines.AxisArtistHelper.Floating:1"
487463
],
488-
"mpl_toolkits.axisartist.floating_axes.Floating AxesHostAxes": [
464+
"mpl_toolkits.axisartist.floating_axes.FloatingAxesHostAxes": [
489465
"<unknown>:1",
490466
"doc/api/_as_gen/mpl_toolkits.axisartist.floating_axes.rst:31:<autosummary>:1"
491467
],
@@ -498,11 +474,11 @@
498474
},
499475
"py:data": {
500476
"matplotlib.axes.Axes.transAxes": [
501-
"lib/matplotlib/axes/_axes.py:docstring of matplotlib.axes._axes.Axes.legend:219",
502-
"lib/matplotlib/figure.py:docstring of matplotlib.figure.FigureBase.legend:220",
503-
"lib/matplotlib/legend.py:docstring of matplotlib.legend.Legend:179",
504-
"lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.figlegend:220",
505-
"lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.legend:219"
477+
"lib/matplotlib/axes/_axes.py:docstring of matplotlib.axes._axes.Axes.legend:222",
478+
"lib/matplotlib/figure.py:docstring of matplotlib.figure.FigureBase.legend:223",
479+
"lib/matplotlib/legend.py:docstring of matplotlib.legend.Legend:182",
480+
"lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.figlegend:223",
481+
"lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.legend:222"
506482
]
507483
},
508484
"py:func": {
@@ -541,15 +517,13 @@
541517
],
542518
"_iter_collection": [
543519
"lib/matplotlib/backend_bases.py:docstring of matplotlib.backend_bases.RendererBase.draw_path_collection:12",
544-
"lib/matplotlib/backends/backend_agg.py:docstring of matplotlib.backends.backend_agg.RendererAgg.draw_path_collection:12",
545520
"lib/matplotlib/backends/backend_pdf.py:docstring of matplotlib.backends.backend_pdf.RendererPdf.draw_path_collection:12",
546521
"lib/matplotlib/backends/backend_ps.py:docstring of matplotlib.backends.backend_ps.RendererPS.draw_path_collection:12",
547522
"lib/matplotlib/backends/backend_svg.py:docstring of matplotlib.backends.backend_svg.RendererSVG.draw_path_collection:12",
548523
"lib/matplotlib/patheffects.py:docstring of matplotlib.patheffects.PathEffectRenderer.draw_path_collection:12"
549524
],
550525
"_iter_collection_raw_paths": [
551526
"lib/matplotlib/backend_bases.py:docstring of matplotlib.backend_bases.RendererBase.draw_path_collection:12",
552-
"lib/matplotlib/backends/backend_agg.py:docstring of matplotlib.backends.backend_agg.RendererAgg.draw_path_collection:12",
553527
"lib/matplotlib/backends/backend_pdf.py:docstring of matplotlib.backends.backend_pdf.RendererPdf.draw_path_collection:12",
554528
"lib/matplotlib/backends/backend_ps.py:docstring of matplotlib.backends.backend_ps.RendererPS.draw_path_collection:12",
555529
"lib/matplotlib/backends/backend_svg.py:docstring of matplotlib.backends.backend_svg.RendererSVG.draw_path_collection:12",
@@ -574,24 +548,22 @@
574548
"lib/matplotlib/transforms.py:docstring of matplotlib.transforms.Affine2DBase:13"
575549
],
576550
"matplotlib.collections._CollectionWithSizes.set_sizes": [
577-
"lib/matplotlib/axes/_axes.py:docstring of matplotlib.axes._axes.Axes.barbs:172",
578-
"lib/matplotlib/axes/_axes.py:docstring of matplotlib.axes._axes.Axes.broken_barh:82",
579-
"lib/matplotlib/axes/_axes.py:docstring of matplotlib.axes._axes.Axes.fill_between:112",
580-
"lib/matplotlib/axes/_axes.py:docstring of matplotlib.axes._axes.Axes.fill_betweenx:112",
581-
"lib/matplotlib/axes/_axes.py:docstring of matplotlib.axes._axes.Axes.hexbin:168",
582-
"lib/matplotlib/axes/_axes.py:docstring of matplotlib.axes._axes.Axes.pcolor:165",
583-
"lib/matplotlib/axes/_axes.py:docstring of matplotlib.axes._axes.Axes.quiver:202",
584-
"lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.barbs:172",
585-
"lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.broken_barh:82",
586-
"lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.fill_between:112",
587-
"lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.fill_betweenx:112",
588-
"lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.hexbin:168",
589-
"lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.pcolor:165",
590-
"lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.quiver:202",
591-
"lib/matplotlib/quiver.py:docstring of matplotlib.quiver.Barbs.__init__:176",
592-
"lib/matplotlib/quiver.py:docstring of matplotlib.quiver.Barbs:206",
593-
"lib/matplotlib/quiver.py:docstring of matplotlib.quiver.Quiver.__init__:206",
594-
"lib/matplotlib/quiver.py:docstring of matplotlib.quiver.Quiver:239"
551+
"lib/matplotlib/axes/_axes.py:docstring of matplotlib.axes._axes.Axes.barbs:171",
552+
"lib/matplotlib/axes/_axes.py:docstring of matplotlib.axes._axes.Axes.broken_barh:81",
553+
"lib/matplotlib/axes/_axes.py:docstring of matplotlib.axes._axes.Axes.fill_between:111",
554+
"lib/matplotlib/axes/_axes.py:docstring of matplotlib.axes._axes.Axes.fill_betweenx:111",
555+
"lib/matplotlib/axes/_axes.py:docstring of matplotlib.axes._axes.Axes.hexbin:167",
556+
"lib/matplotlib/axes/_axes.py:docstring of matplotlib.axes._axes.Axes.pcolor:164",
557+
"lib/matplotlib/axes/_axes.py:docstring of matplotlib.axes._axes.Axes.quiver:201",
558+
"lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.barbs:171",
559+
"lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.broken_barh:81",
560+
"lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.fill_between:111",
561+
"lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.fill_betweenx:111",
562+
"lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.hexbin:167",
563+
"lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.pcolor:164",
564+
"lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.quiver:201",
565+
"lib/matplotlib/quiver.py:docstring of matplotlib.quiver.Barbs:205",
566+
"lib/matplotlib/quiver.py:docstring of matplotlib.quiver.Quiver:238"
595567
],
596568
"matplotlib.dates.DateFormatter.__call__": [
597569
"doc/users/prev_whats_new/whats_new_1.5.rst:497"
@@ -727,7 +699,6 @@
727699
"doc/users/event_handling.rst:179"
728700
],
729701
"Size.from_any": [
730-
"lib/mpl_toolkits/axes_grid1/axes_grid.py:docstring of mpl_toolkits.axes_grid1.axes_grid.ImageGrid.__init__:57",
731702
"lib/mpl_toolkits/axes_grid1/axes_grid.py:docstring of mpl_toolkits.axes_grid1.axes_grid.ImageGrid:57",
732703
"lib/mpl_toolkits/axisartist/axes_grid.py:docstring of mpl_toolkits.axisartist.axes_grid.ImageGrid:57"
733704
],

‎lib/matplotlib/axes/_subplots.py

Copy file name to clipboardExpand all lines: lib/matplotlib/axes/_subplots.py
+3-61Lines changed: 3 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import functools
2-
3-
from matplotlib import _api
1+
from matplotlib import _api, cbook
42
from matplotlib.axes._axes import Axes
53
from matplotlib.gridspec import GridSpec, SubplotSpec
64

@@ -36,15 +34,6 @@ def __init__(self, fig, *args, **kwargs):
3634
# This will also update the axes position.
3735
self.set_subplotspec(SubplotSpec._from_subplot_args(fig, args))
3836

39-
def __reduce__(self):
40-
# get the first axes class which does not inherit from a subplotbase
41-
axes_class = next(
42-
c for c in type(self).__mro__
43-
if issubclass(c, Axes) and not issubclass(c, SubplotBase))
44-
return (_picklable_subplot_class_constructor,
45-
(axes_class,),
46-
self.__getstate__())
47-
4837
@_api.deprecated(
4938
"3.4", alternative="get_subplotspec",
5039
addendum="(get_subplotspec returns a SubplotSpec instance.)")
@@ -169,53 +158,6 @@ def _make_twin_axes(self, *args, **kwargs):
169158
return twin
170159

171160

172-
# this here to support cartopy which was using a private part of the
173-
# API to register their Axes subclasses.
174-
175-
# In 3.1 this should be changed to a dict subclass that warns on use
176-
# In 3.3 to a dict subclass that raises a useful exception on use
177-
# In 3.4 should be removed
178-
179-
# The slow timeline is to give cartopy enough time to get several
180-
# release out before we break them.
181-
_subplot_classes = {}
182-
183-
184-
@functools.lru_cache(None)
185-
def subplot_class_factory(axes_class=None):
186-
"""
187-
Make a new class that inherits from `.SubplotBase` and the
188-
given axes_class (which is assumed to be a subclass of `.axes.Axes`).
189-
This is perhaps a little bit roundabout to make a new class on
190-
the fly like this, but it means that a new Subplot class does
191-
not have to be created for every type of Axes.
192-
"""
193-
if axes_class is None:
194-
_api.warn_deprecated(
195-
"3.3", message="Support for passing None to subplot_class_factory "
196-
"is deprecated since %(since)s; explicitly pass the default Axes "
197-
"class instead. This will become an error %(removal)s.")
198-
axes_class = Axes
199-
try:
200-
# Avoid creating two different instances of GeoAxesSubplot...
201-
# Only a temporary backcompat fix. This should be removed in
202-
# 3.4
203-
return next(cls for cls in SubplotBase.__subclasses__()
204-
if cls.__bases__ == (SubplotBase, axes_class))
205-
except StopIteration:
206-
return type("%sSubplot" % axes_class.__name__,
207-
(SubplotBase, axes_class),
208-
{'_axes_class': axes_class})
209-
210-
161+
subplot_class_factory = cbook._make_class_factory(
162+
SubplotBase, "{}Subplot", "_axes_class")
211163
Subplot = subplot_class_factory(Axes) # Provided for backward compatibility.
212-
213-
214-
def _picklable_subplot_class_constructor(axes_class):
215-
"""
216-
Stub factory that returns an empty instance of the appropriate subplot
217-
class when called with an axes class. This is purely to allow pickling of
218-
Axes and Subplots.
219-
"""
220-
subplot_class = subplot_class_factory(axes_class)
221-
return subplot_class.__new__(subplot_class)

‎lib/matplotlib/cbook/__init__.py

Copy file name to clipboardExpand all lines: lib/matplotlib/cbook/__init__.py
+50Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2188,3 +2188,53 @@ def _unikey_or_keysym_to_mplkey(unikey, keysym):
21882188
"next": "pagedown", # Used by tk.
21892189
}.get(key, key)
21902190
return key
2191+
2192+
2193+
@functools.lru_cache(None)
2194+
def _make_class_factory(mixin_class, fmt, attr_name=None):
2195+
"""
2196+
Return a function that creates picklable classes inheriting from a mixin.
2197+
2198+
After ::
2199+
2200+
factory = _make_class_factory(FooMixin, fmt, attr_name)
2201+
FooAxes = factory(Axes)
2202+
2203+
``Foo`` is a class that inherits from ``FooMixin`` and ``Axes`` and **is
2204+
picklable** (picklability is what differentiates this from a plain call to
2205+
`type`). Its ``__name__`` is set to ``fmt.format(Axes.__name__)`` and the
2206+
base class is stored in the ``attr_name`` attribute, if not None.
2207+
2208+
Moreover, the return value of ``factory`` is memoized: calls with the same
2209+
``Axes`` class always return the same subclass.
2210+
"""
2211+
2212+
@functools.lru_cache(None)
2213+
def class_factory(axes_class):
2214+
# The parameter is named "axes_class" for backcompat but is really just
2215+
# a base class; no axes semantics are used.
2216+
base_class = axes_class
2217+
2218+
class subcls(mixin_class, base_class):
2219+
# Better approximation than __module__ = "matplotlib.cbook".
2220+
__module__ = mixin_class.__module__
2221+
2222+
def __reduce__(self):
2223+
return (_picklable_class_constructor,
2224+
(mixin_class, fmt, attr_name, base_class),
2225+
self.__getstate__())
2226+
2227+
subcls.__name__ = subcls.__qualname__ = fmt.format(base_class.__name__)
2228+
if attr_name is not None:
2229+
setattr(subcls, attr_name, base_class)
2230+
return subcls
2231+
2232+
class_factory.__module__ = mixin_class.__module__
2233+
return class_factory
2234+
2235+
2236+
def _picklable_class_constructor(mixin_class, fmt, attr_name, base_class):
2237+
"""Internal helper for _make_class_factory."""
2238+
factory = _make_class_factory(mixin_class, fmt, attr_name)
2239+
cls = factory(base_class)
2240+
return cls.__new__(cls)

‎lib/matplotlib/tests/test_axes.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_axes.py
-15Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6340,21 +6340,6 @@ def test_spines_properbbox_after_zoom():
63406340
np.testing.assert_allclose(bb.get_points(), bb2.get_points(), rtol=1e-6)
63416341

63426342

6343-
def test_cartopy_backcompat():
6344-
6345-
class Dummy(matplotlib.axes.Axes):
6346-
...
6347-
6348-
class DummySubplot(matplotlib.axes.SubplotBase, Dummy):
6349-
_axes_class = Dummy
6350-
6351-
matplotlib.axes._subplots._subplot_classes[Dummy] = DummySubplot
6352-
6353-
FactoryDummySubplot = matplotlib.axes.subplot_class_factory(Dummy)
6354-
6355-
assert DummySubplot is FactoryDummySubplot
6356-
6357-
63586343
def test_gettightbbox_ignore_nan():
63596344
fig, ax = plt.subplots()
63606345
remove_ticks_and_titles(fig)

‎lib/matplotlib/tests/test_pickle.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_pickle.py
+6Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import matplotlib.pyplot as plt
1111
import matplotlib.transforms as mtransforms
1212
import matplotlib.figure as mfigure
13+
from mpl_toolkits.axes_grid1 import parasite_axes
1314

1415

1516
def test_simple():
@@ -212,3 +213,8 @@ def test_unpickle_canvas():
212213
out.seek(0)
213214
fig2 = pickle.load(out)
214215
assert fig2.canvas is not None
216+
217+
218+
def test_mpl_toolkits():
219+
ax = parasite_axes.host_axes([0, 0, 1, 1])
220+
assert type(pickle.loads(pickle.dumps(ax))) == parasite_axes.HostAxes

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.