Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork7.9k
Description
Bug summary
Noted while investigating#21917 (comment):Collection.draw
callsCollection._prepare_points
, and in some cases (ifnot self.get_transform().is_affine and len(paths) == len(self.get_transforms()) == len(facecolors) == ... == 1 and ...
, the latter being the check for single-path-optimization) this results in the paths being transformed in the following order:
- first by the non-affine part of self.get_transform() (in
_prepare_points
) - then by
transforms.Affine2D(trans[0]) + transform
, i.e.- by
self.get_transforms()[0]
(which is always affine) (in the single-path-optimization check) - by the affine part of self.get_transform() (also in the single-path optimization check)
- by
i.e.self.get_transforms()[0]
gets inserted in the middle ofself.get_transform()
, between the affine and non-affine parts, which seems wrong (in the general case it doesn't commute with either).
Probably this doesn't cause problems in practice because we never(?) set bothself.get_transform()
ANDself.get_transforms()
, so one of them is identity, but still, this seems wrong from a spec PoV.
From looking at the implementation of RendererBase.draw_path_collection (and associated helpers) it seems like the intent is to first transform byself.get_transforms()[0]
and then byself.get_transform()
(cftransform + master_transform
in_iter_collection_raw_paths
.
Code for reproduction
Abitartificial,but...frommatplotlibimportpyplotaspltfrommatplotlib.transformsimport*# Like an affine transform, but pretend that the affine part is actually not affine.classPseudoNonAffineTransform(Transform):is_affine=Falsedef__init__(self,mtx):self._mtx=mtxdeftransform_non_affine(self,values):returnAffine2D(self._mtx).transform_affine(values)ax=plt.figure().add_subplot()ax.grid()ax.margins(.5)pc1=ax.scatter([0,1], [0,1])pc1.set_transform(Affine2D().translate(20,20))pc2=ax.scatter([0,1], [0,1])pc2.set_transform(PseudoNonAffineTransform(Affine2D().translate(20,20).get_matrix()))plt.show()
Actual outcome
Expected outcome
Both scatter plots should be the same.
Additional information
Probably long-standing misspec?
Operating system
No response
Matplotlib Version
3.5.1+
Matplotlib Backend
agg
Python version
39
Jupyter version
no
Installation
git checkout