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

3D plots shared view angles#25821

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
Merged
Show file tree
Hide file tree
Changes fromall 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
1 change: 1 addition & 0 deletionsdoc/api/toolkits/mplot3d/axes3d.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -209,6 +209,7 @@ Sharing
:nosignatures:

sharez
shareview


Interactive
Expand Down
7 changes: 7 additions & 0 deletionsdoc/users/next_whats_new/3d_plots_shareview.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
3D plots can share view angles
------------------------------

3D plots can now share the same view angles, so that when you rotate one plot
the other plots also rotate. This can be done with the *shareview* keyword
argument when adding an axes, or by using the *ax1.shareview(ax2)* method of
existing 3D axes.
66 changes: 49 additions & 17 deletionslib/mpl_toolkits/mplot3d/axes3d.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -56,6 +56,7 @@ class Axes3D(Axes):

_axis_names = ("x", "y", "z")
Axes._shared_axes["z"] = cbook.Grouper()
Axes._shared_axes["view"] = cbook.Grouper()

vvec = _api.deprecate_privatize_attribute("3.7")
eye = _api.deprecate_privatize_attribute("3.7")
Expand All@@ -66,6 +67,7 @@ def __init__(
self, fig, rect=None, *args,
elev=30, azim=-60, roll=0, sharez=None, proj_type='persp',
box_aspect=None, computed_zorder=True, focal_length=None,
shareview=None,
**kwargs):
"""
Parameters
Expand DownExpand Up@@ -111,6 +113,8 @@ def __init__(
or infinity (numpy.inf). If None, defaults to infinity.
The focal length can be computed from a desired Field Of View via
the equation: focal_length = 1/tan(FOV/2)
shareview : Axes3D, optional
Other Axes to share view angles with.

**kwargs
Other optional keyword arguments:
Expand DownExpand Up@@ -142,6 +146,10 @@ def __init__(
self._shared_axes["z"].join(self, sharez)
self._adjustable = 'datalim'

self._shareview = shareview
if shareview is not None:
self._shared_axes["view"].join(self, shareview)

if kwargs.pop('auto_add_to_figure', False):
raise AttributeError(
'auto_add_to_figure is no longer supported for Axes3D. '
Expand DownExpand Up@@ -757,7 +765,8 @@ def clabel(self, *args, **kwargs):
"""Currently not implemented for 3D axes, and returns *None*."""
return None

def view_init(self, elev=None, azim=None, roll=None, vertical_axis="z"):
def view_init(self, elev=None, azim=None, roll=None, vertical_axis="z",
share=False):
"""
Set the elevation and azimuth of the axes in degrees (not radians).

Expand DownExpand Up@@ -804,29 +813,34 @@ def view_init(self, elev=None, azim=None, roll=None, vertical_axis="z"):
constructor is used.
vertical_axis : {"z", "x", "y"}, default: "z"
The axis to align vertically. *azim* rotates about this axis.
share : bool, default: False
If ``True``, apply the settings to all Axes with shared views.
"""

self._dist = 10 # The camera distance from origin. Behaves like zoom

if elev is None:
self.elev = self.initial_elev
else:
self.elev = elev

elev = self.initial_elev
if azim is None:
self.azim = self.initial_azim
else:
self.azim = azim

azim = self.initial_azim
if roll is None:
self.roll = self.initial_roll
else:
self.roll = roll

self._vertical_axis = _api.check_getitem(
roll = self.initial_roll
vertical_axis = _api.check_getitem(
dict(x=0, y=1, z=2), vertical_axis=vertical_axis
)

if share:
axes = {sibling for sibling
in self._shared_axes['view'].get_siblings(self)}
else:
axes = [self]

for ax in axes:
ax.elev = elev
ax.azim = azim
ax.roll = roll
ax._vertical_axis = vertical_axis

def set_proj_type(self, proj_type, focal_length=None):
"""
Set the projection type.
Expand DownExpand Up@@ -964,7 +978,7 @@ def sharez(self, other):
Axes, and cannot be used if the z-axis is already being shared with
another Axes.
"""
_api.check_isinstance(maxes._base._AxesBase, other=other)
_api.check_isinstance(Axes3D, other=other)
if self._sharez is not None and other is not self._sharez:
raise ValueError("z-axis is already shared")
self._shared_axes["z"].join(self, other)
Expand All@@ -975,6 +989,23 @@ def sharez(self, other):
self.set_zlim(z0, z1, emit=False, auto=other.get_autoscalez_on())
self.zaxis._scale = other.zaxis._scale

def shareview(self, other):
"""
Share the view angles with *other*.

This is equivalent to passing ``shareview=other`` when
constructing the Axes, and cannot be used if the view angles are
already being shared with another Axes.
"""
_api.check_isinstance(Axes3D, other=other)
if self._shareview is not None and other is not self._shareview:
raise ValueError("view angles are already shared")
self._shared_axes["view"].join(self, other)
self._shareview = other
vertical_axis = {0: "x", 1: "y", 2: "z"}[other._vertical_axis]
self.view_init(elev=other.elev, azim=other.azim, roll=other.roll,
vertical_axis=vertical_axis, share=True)

def clear(self):
# docstring inherited.
super().clear()
Expand DownExpand Up@@ -1107,8 +1138,9 @@ def _on_move(self, event):
roll = np.deg2rad(self.roll)
delev = -(dy/h)*180*np.cos(roll) + (dx/w)*180*np.sin(roll)
dazim = -(dy/h)*180*np.sin(roll) - (dx/w)*180*np.cos(roll)
self.elev = self.elev + delev
self.azim = self.azim + dazim
elev = self.elev + delev
azim = self.azim + dazim
self.view_init(elev=elev, azim=azim, roll=roll, share=True)
self.stale = True

elif self.button_pressed in self._pan_btn:
Expand Down
14 changes: 14 additions & 0 deletionslib/mpl_toolkits/mplot3d/tests/test_axes3d.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1689,6 +1689,20 @@ def test_set_zlim():
ax.set_zlim(top=0, zmax=1)


@check_figures_equal(extensions=["png"])
def test_shared_view(fig_test, fig_ref):
elev, azim, roll = 5, 20, 30
ax1 = fig_test.add_subplot(131, projection="3d")
ax2 = fig_test.add_subplot(132, projection="3d", shareview=ax1)
ax3 = fig_test.add_subplot(133, projection="3d")
ax3.shareview(ax1)
ax2.view_init(elev=elev, azim=azim, roll=roll, share=True)

for subplot_num in (131, 132, 133):
ax = fig_ref.add_subplot(subplot_num, projection="3d")
ax.view_init(elev=elev, azim=azim, roll=roll)


def test_shared_axes_retick():
fig = plt.figure()
ax1 = fig.add_subplot(211, projection="3d")
Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp