Movatterモバイル変換


[0]ホーム

URL:


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

Sign up
Appearance settings

FIX: Autoscale support in add_collection3d for Line3DCollection and Poly3DCollection#28403

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged

Conversation

scottshambaugh
Copy link
Contributor

@scottshambaughscottshambaugh commentedJun 16, 2024
edited
Loading

PR summary

Closes#23317
Closes#17130

Code copied in large part from@lganic's work in#25751 (thank you!), which he closed.

I would consider this a bugfix for a missing kwarg, but if we want to consider this an enhancement for 3.10.0 please feel free to shift the milestone.

PR checklist

@scottshambaughscottshambaugh added topic: mplot3d PR: bugfixPull requests that fix identified bugs labelsJun 16, 2024
@scottshambaughscottshambaugh added this to thev3.9.1 milestoneJun 16, 2024
@scottshambaughscottshambaughforce-pushed the3d_collection_autoscaling branch from69ea30c to195a208CompareJune 16, 2024 03:45
Co-authored-by: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com>
@scottshambaughscottshambaughforce-pushed the3d_collection_autoscaling branch from49ee773 to0c7b7dbCompareJune 17, 2024 00:11
@github-actionsgithub-actionsbot added the Documentation: examplesfiles in galleries/examples labelJun 17, 2024
Co-authored-by: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com>
Comment on lines +2786 to +2795
if isinstance(col, art3d.Line3DCollection):
self.auto_scale_xyz(*np.array(col._segments3d).transpose(),
had_data=had_data)
elif isinstance(col, art3d.Poly3DCollection):
self.auto_scale_xyz(*col._vec[:-1], had_data=had_data)
elif isinstance(col, art3d.Patch3DCollection):
pass
# FIXME: Implement auto-scaling function for Patch3DCollection
# Currently unable to do so due to issues with Patch3DCollection
# See https://github.com/matplotlib/matplotlib/issues/14298 for details
Copy link
Member

@timhoffmtimhoffmJun 18, 2024
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

While technically correct, I believe we should move the calculation of data lims down into the artists.

Current logic

Extract all data coordinatesxyz from the artist and feed them intoauto_scale_xyz().

This updates thexy_dataLim,zz_dataLim BBoxes via.Bbox.update_from_data_xy/x/y(), which in turn creates aPath and calls.Bbox.update_from_path().

This is quite a lot data pushing (and maybe copying) just to update dataLim bboxes.

Proposed logic

Separation of concerns: The Artists should have a function to get their data lims. These limits should be used to update the Bbox. Basically someBbox.update_from_box, a kind of an in-placeBbox.union, which we don't seem to have.

This whole block should read something like

if autolim:    self.auto_scale_lim(col.get_data_lims())

Note: "data lim" is intentionally vague as we currently don't have a good structure to describe it (we use two 2D Bboxes,xy_dataLim andzz_dataLim.

The minimal approach - if we don't want to redesign for proper 3d boxes, would be to letget_data_lims() return two BBoxes as well. In that case, I would keep this interface private_get_data_lims() so that we can still change to a single 3D instance later.


Edit: This is basically a generalization ofCollection.get_datalim.

defget_datalim(self,transData):
# Calculate the data limits and return them as a `.Bbox`.
#
# This operation depends on the transforms for the data in the
# collection and whether the collection has offsets:
#
# 1. offsets = None, transform child of transData: use the paths for
# the automatic limits (i.e. for LineCollection in streamline).
# 2. offsets != None: offset_transform is child of transData:
#
# a. transform is child of transData: use the path + offset for
# limits (i.e for bar).
# b. transform is not a child of transData: just use the offsets
# for the limits (i.e. for scatter)
#
# 3. otherwise return a null Bbox.
transform=self.get_transform()
offset_trf=self.get_offset_transform()
ifnot (isinstance(offset_trf,transforms.IdentityTransform)
oroffset_trf.contains_branch(transData)):
# if the offsets are in some coords other than data,
# then don't use them for autoscaling.
returntransforms.Bbox.null()
paths=self.get_paths()
ifnotlen(paths):
# No paths to transform
returntransforms.Bbox.null()
ifnottransform.is_affine:
paths= [transform.transform_path_non_affine(p)forpinpaths]
# Don't convert transform to transform.get_affine() here because
# we may have transform.contains_branch(transData) but not
# transforms.get_affine().contains_branch(transData). But later,
# be careful to only apply the affine part that remains.
offsets=self.get_offsets()
ifany(transform.contains_branch_seperately(transData)):
# collections that are just in data units (like quiver)
# can properly have the axes limits set by their shape +
# offset. LineCollections that have no offsets can
# also use this algorithm (like streamplot).
ifisinstance(offsets,np.ma.MaskedArray):
offsets=offsets.filled(np.nan)
# get_path_collection_extents handles nan but not masked arrays
returnmpath.get_path_collection_extents(
transform.get_affine()-transData,paths,
self.get_transforms(),
offset_trf.transform_non_affine(offsets),
offset_trf.get_affine().frozen())
# NOTE: None is the default case where no offsets were passed in
ifself._offsetsisnotNone:
# this is for collections that have their paths (shapes)
# in physical, axes-relative, or figure-relative units
# (i.e. like scatter). We can't uniquely set limits based on
# those shapes, so we just set the limits based on their
# location.
offsets= (offset_trf-transData).transform(offsets)
# note A-B means A B^{-1}
offsets=np.ma.masked_invalid(offsets)
ifnotoffsets.mask.all():
bbox=transforms.Bbox.null()
bbox.update_from_data_xy(offsets)
returnbbox
returntransforms.Bbox.null()

Rough outline: We may start minimal with rolling a small

class _Bbox3d:    def __init__(self, points):        ((self.xmin, self.xmax),         (self.ymin, self.ymax),         (self.zmin, self.zmax)) = points    def to_bbox_xy(self):        return Bbox(((self.xmin, self.xmax), (self.ymin, self.ymax)))    def to_bbox_zz(self):        # first component contains z, second is unused        return Bbox(((self.zmin, self.zmax), (0, 0)))

and implement_get_datalim3d() -> _Bbox3d on the 3d collections.

Then

def add_collection(col, autolim=True):    ...    if autolim:        self.auto_scale_lim(col.get_datalim3d())

and

def auto_scale_lim(bbox3d):     ...     self.dataLim_xy.update_from_box(bbox3d.to_bbox_xy())     self.dataLim_zz.update_from_box(bbox3d.to_bbox_zz())

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I like this structure, but could we make that refactor its own issue?

timhoffm reacted with thumbs up emoji
@greglucasgreglucas merged commit7ee56ce intomatplotlib:mainJun 24, 2024
41 of 42 checks passed
@lumberbot-appLumberbot (App)
Copy link

Owee, I'm MrMeeseeks, Look at me.

There seem to be a conflict, please backport manually. Here are approximate instructions:

  1. Checkout backport branch and update it.
git checkout v3.9.xgit pull
  1. Cherry pick the first parent branch of the this PR on top of the older branch:
git cherry-pick -x -m1 7ee56ce31f3c2719ee774132ed36f5b1ca549afa
  1. You will likely have some merge/cherry-pick conflict here, fix them and commit:
git commit -am 'Backport PR #28403: FIX: Autoscale support in add_collection3d for Line3DCollection and Poly3DCollection'
  1. Push to a named branch:
git push YOURFORK v3.9.x:auto-backport-of-pr-28403-on-v3.9.x
  1. Create a PR against branch v3.9.x, I would have named this PR:

"Backport PR#28403 on branch v3.9.x (FIX: Autoscale support in add_collection3d for Line3DCollection and Poly3DCollection)"

And apply the correct labels and milestones.

Congratulations — you did some good work! Hopefully your backport PR will be tested by the continuous integration and merged soon!

Remember to remove theStill Needs Manual Backport label once the PR gets merged.

If these instructions are inaccurate, feel free tosuggest an improvement.

scottshambaugh added a commit to scottshambaugh/matplotlib that referenced this pull requestJun 24, 2024
ksunden added a commit that referenced this pull requestJun 24, 2024
…03-on-v3.9.xBackport PR#28403 on branch v3.9.x (FIX: Autoscale support in add_collection3d for Line3DCollection and Poly3DCollection
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@timhoffmtimhoffmtimhoffm approved these changes

@greglucasgreglucasgreglucas approved these changes

Assignees
No one assigned
Labels
Documentation: examplesfiles in galleries/examplesPR: bugfixPull requests that fix identified bugstopic: mplot3d
Projects
None yet
Milestone
v3.9.1
Development

Successfully merging this pull request may close these issues.

[Bug]:add_collection3d does not update view limits autoscale_view is not working with Line3DCollection
4 participants
@scottshambaugh@timhoffm@greglucas@QuLogic

[8]ページ先頭

©2009-2025 Movatter.jp