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

Skip to content

Style fixes for mplot3d. #12069

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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 14, 2018
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 0 additions & 2 deletions .flake8
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,6 @@ per-file-ignores =
mpl_toolkits/axisartist/clip_path.py: E225, E501
mpl_toolkits/axisartist/floating_axes.py: E225, E402, E501
mpl_toolkits/axisartist/grid_helper_curvelinear.py: E225, E501
mpl_toolkits/mplot3d/art3d.py: E203, E222, E225
mpl_toolkits/mplot3d/axes3d.py: E203, E402, E501
mpl_toolkits/tests/test_axes_grid1.py: E201, E202

doc/conf.py: E402, E501
Expand Down
2 changes: 1 addition & 1 deletion lib/matplotlib/transforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -920,7 +920,7 @@ def update_from_data_xy(self, xy, ignore=None, updatex=True, updatey=True):

path = Path(xy)
self.update_from_path(path, ignore=ignore,
updatex=updatex, updatey=updatey)
updatex=updatex, updatey=updatey)

@BboxBase.x0.setter
def x0(self, val):
Expand Down
19 changes: 6 additions & 13 deletions lib/mpl_toolkits/mplot3d/art3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,7 @@ def draw(self, renderer):
[self._position3d, self._position3d + self._dir_vec], renderer.M)
dx = proj[0][1] - proj[0][0]
dy = proj[1][1] - proj[1][0]
if dx==0. and dy==0.:
# atan2 raises ValueError: math domain error on 0,0
angle = 0.
else:
angle = math.degrees(math.atan2(dy, dx))
angle = math.degrees(math.atan2(dy, dx))
Copy link
Contributor Author

@anntzer anntzer Sep 8, 2018

Choose a reason for hiding this comment

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

math.atan2(0, 0) (or likewise with floats) returns 0 or pi depending on the signedness of the zeros in Py2 and Py3 and that's also mandated by the C standard. norm_text_angle later takes it modulo 180 so we're fine.

self.set_position((proj[0][0], proj[1][0]))
self.set_rotation(norm_text_angle(angle))
mtext.Text.draw(self, renderer)
Expand Down Expand Up @@ -318,7 +314,7 @@ def do_3d_projection(self, renderer):
def get_patch_verts(patch):
"""Return a list of vertices for the path of a patch."""
trans = patch.get_patch_transform()
path = patch.get_path()
path = patch.get_path()
polygons = path.to_polygons(trans)
if len(polygons):
return polygons[0]
Expand Down Expand Up @@ -469,10 +465,7 @@ def do_3d_projection(self, renderer):
self.set_edgecolors(ecs)
PathCollection.set_offsets(self, np.column_stack([vxs, vys]))

if vzs.size > 0 :
return min(vzs)
else :
return np.nan
return np.min(vzs) if vzs.size else np.nan


def patch_collection_2d_to_3d(col, zs=0, zdir='z', depthshade=True):
Expand Down Expand Up @@ -563,7 +556,7 @@ def get_vector(self, segments3d):

if len(segments3d):
xs, ys, zs = zip(*points)
else :
else:
# We need this so that we can skip the bad unpacking from zip()
xs, ys, zs = [], [], []

Expand Down Expand Up @@ -651,12 +644,12 @@ def do_3d_projection(self, renderer):
zvec = np.array([[0], [0], [self._sort_zpos], [1]])
ztrans = proj3d.proj_transform_vec(zvec, renderer.M)
return ztrans[2][0]
elif tzs.size > 0 :
elif tzs.size > 0:
# FIXME: Some results still don't look quite right.
# In particular, examine contourf3d_demo2.py
# with az = -54 and elev = -45.
return np.min(tzs)
else :
else:
Copy link
Member

@timhoffm timhoffm Sep 9, 2018

Choose a reason for hiding this comment

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

else:
    return np.min(tzs) if tzs.size else np.nan

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I see where you're coming from but mixing in a ternary in a if... elif chain looks meh to me.

Copy link
Member

Choose a reason for hiding this comment

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

Actually, I don't think that the three blocks are logically equal. To me, the current form

if self._sort_zpos is not None:
    [use _sort_zpos]
elif tzs.size > 0:
    [use min(tzs)]
else:
    [use fallback]

is logically more like

if self._sort_zpos is not None:
    [use _sort_zpos]
else:
    if tzs.size > 0:
        [use min(tzs)]
    else:
        [use fallback]

Usually tzs are expected to be there and nan is only a fallback if they are not. Thus it would be preferable to

if self._sort_zpos is not None:
    [use _sort_zpos]
else:
    [use min(tzs) with fallback]

However, I agree that depends on the point of view you take. And I won't argue further if you still prefer to leave it as is.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I know (hence the "I see where you're coming from" above), but it still looks not so nice to me. (Really, best would be min(tzs, default=np.nan) but np.min doesn't have that and builtins.min is likely slower.)

return np.nan

def set_facecolor(self, colors):
Expand Down
93 changes: 48 additions & 45 deletions lib/mpl_toolkits/mplot3d/axes3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import matplotlib.collections as mcoll
import matplotlib.colors as mcolors
import matplotlib.docstring as docstring
import matplotlib.projections as proj
import matplotlib.scale as mscale
import matplotlib.transforms as mtransforms
from matplotlib.axes import Axes, rcParams
Expand Down Expand Up @@ -71,7 +72,7 @@ def __init__(
.. versionadded :: 1.2.1
*sharez*

''' % {'scale': ' | '.join([repr(x) for x in mscale.get_scale_names()])}
''' % {'scale': ' | '.join(repr(x) for x in mscale.get_scale_names())}

if rect is None:
rect = [0.0, 0.0, 1.0, 1.0]
Expand Down Expand Up @@ -375,7 +376,7 @@ def set_zmargin(self, m):
.. versionadded :: 1.1.0
This function was added, but not tested. Please report any bugs.
"""
if m < 0 or m > 1 :
if m < 0 or m > 1:
raise ValueError("margin must be in range 0 to 1")
self._zmargin = m
self.stale = True
Expand Down Expand Up @@ -493,7 +494,8 @@ def auto_scale_xyz(self, X, Y, Z=None, had_data=None):
# data.
self.xy_dataLim.update_from_data_xy(np.array([x, y]).T, not had_data)
if z is not None:
self.zz_dataLim.update_from_data_xy(np.array([z, z]).T, not had_data)
self.zz_dataLim.update_from_data_xy(
np.array([z, z]).T, not had_data)

# Let autoscale_view figure out how to use this data.
self.autoscale_view()
Expand Down Expand Up @@ -773,19 +775,19 @@ def get_xlim3d(self):
get_xlim = get_xlim3d
if get_xlim.__doc__ is not None:
get_xlim.__doc__ += """
.. versionchanged :: 1.1.0
This function now correctly refers to the 3D x-limits
"""
.. versionchanged :: 1.1.0
This function now correctly refers to the 3D x-limits
"""

def get_ylim3d(self):
return tuple(self.xy_viewLim.intervaly)
get_ylim3d.__doc__ = maxes.Axes.get_ylim.__doc__
get_ylim = get_ylim3d
if get_ylim.__doc__ is not None:
get_ylim.__doc__ += """
.. versionchanged :: 1.1.0
This function now correctly refers to the 3D y-limits.
"""
.. versionchanged :: 1.1.0
This function now correctly refers to the 3D y-limits.
"""

def get_zlim3d(self):
'''Get 3D z limits.'''
Expand All @@ -809,10 +811,9 @@ def set_xscale(self, value, **kwargs):
self._update_transScale()
if maxes.Axes.set_xscale.__doc__ is not None:
set_xscale.__doc__ = maxes.Axes.set_xscale.__doc__ + """

.. versionadded :: 1.1.0
This function was added, but not tested. Please report any bugs.
"""
.. versionadded :: 1.1.0
This function was added, but not tested. Please report any bugs.
"""

def set_yscale(self, value, **kwargs):
self.yaxis._set_scale(value, **kwargs)
Expand All @@ -821,10 +822,9 @@ def set_yscale(self, value, **kwargs):
self.stale = True
if maxes.Axes.set_yscale.__doc__ is not None:
set_yscale.__doc__ = maxes.Axes.set_yscale.__doc__ + """

.. versionadded :: 1.1.0
This function was added, but not tested. Please report any bugs.
"""
.. versionadded :: 1.1.0
This function was added, but not tested. Please report any bugs.
"""

@docstring.dedent_interpd
def set_zscale(self, value, **kwargs):
Expand Down Expand Up @@ -1340,7 +1340,7 @@ def ticklabel_format(
self.xaxis.major.formatter.set_scientific(sb)
if axis in ['both', 'y']:
self.yaxis.major.formatter.set_scientific(sb)
if axis in ['both', 'z'] :
if axis in ['both', 'z']:
self.zaxis.major.formatter.set_scientific(sb)
if scilimits is not None:
if axis in ['both', 'x']:
Expand Down Expand Up @@ -1413,7 +1413,7 @@ def tick_params(self, axis='both', **kwargs):
This function was added, but not tested. Please report any bugs.
"""
super().tick_params(axis, **kwargs)
if axis in ['z', 'both'] :
if axis in ['z', 'both']:
zkw = dict(kwargs)
zkw.pop('top', None)
zkw.pop('bottom', None)
Expand Down Expand Up @@ -1676,8 +1676,8 @@ def get_normals(polygons):
v1 = np.empty((len(polygons), 3))
v2 = np.empty((len(polygons), 3))
for poly_i, ps in enumerate(polygons):
# pick three points around the polygon at which to find the normal
# doesn't vectorize because polygons is jagged
# pick three points around the polygon at which to find the
# normal doesn't vectorize because polygons is jagged
i1, i2, i3 = 0, len(ps)//3, 2*len(ps)//3
v1[poly_i, :] = ps[i1, :] - ps[i2, :]
v2[poly_i, :] = ps[i2, :] - ps[i3, :]
Expand Down Expand Up @@ -1937,7 +1937,8 @@ def plot_trisurf(self, *args, color=None, norm=None, vmin=None, vmax=None,
cmap = kwargs.get('cmap', None)
shade = kwargs.pop('shade', cmap is None)

tri, args, kwargs = Triangulation.get_from_args_and_kwargs(*args, **kwargs)
tri, args, kwargs = \
Triangulation.get_from_args_and_kwargs(*args, **kwargs)
if 'Z' in kwargs:
z = np.asarray(kwargs.pop('Z'))
else:
Expand Down Expand Up @@ -2027,7 +2028,8 @@ def _3d_extend_contour(self, cset, stride=5):
for col in colls:
self.collections.remove(col)

def add_contour_set(self, cset, extend3d=False, stride=5, zdir='z', offset=None):
def add_contour_set(
self, cset, extend3d=False, stride=5, zdir='z', offset=None):
zdir = '-' + zdir
if extend3d:
self._3d_extend_contour(cset, stride)
Expand All @@ -2040,7 +2042,7 @@ def add_contour_set(self, cset, extend3d=False, stride=5, zdir='z', offset=None)
def add_contourf_set(self, cset, zdir='z', offset=None):
zdir = '-' + zdir
for z, linec in zip(cset.levels, cset.collections):
if offset is not None :
if offset is not None:
z = offset
art3d.poly_collection_2d_to_3d(linec, z, zdir=zdir)
linec.set_sort_zpos(z)
Expand Down Expand Up @@ -2225,10 +2227,8 @@ def add_collection3d(self, col, zs=0, zdir='z'):
- PatchCollection
'''
zvals = np.atleast_1d(zs)
if len(zvals) > 0 :
zsortval = min(zvals)
else :
zsortval = 0 # FIXME: Fairly arbitrary. Is there a better value?
zsortval = (np.min(zvals) if zvals.size
else 0) # FIXME: arbitrary default

# FIXME: use issubclass() (although, then a 3D collection
# object would also pass.) Maybe have a collection3d
Expand Down Expand Up @@ -2345,12 +2345,12 @@ def bar(self, left, height, zs=0, zdir='z', *args, **kwargs):
if 'alpha' in kwargs:
p.set_alpha(kwargs['alpha'])

if len(verts) > 0 :
if len(verts) > 0:
# the following has to be skipped if verts is empty
# NOTE: Bugs could still occur if len(verts) > 0,
# but the "2nd dimension" is empty.
xs, ys = list(zip(*verts))
else :
xs, ys = zip(*verts)
else:
xs, ys = [], []

xs, ys, verts_zs = art3d.juggle_axes(xs, ys, verts_zs, zdir)
Expand Down Expand Up @@ -2485,7 +2485,8 @@ def quiver(self, *args,
length=1, arrow_length_ratio=.3, pivot='tail', normalize=False,
**kwargs):
"""
ax.quiver(X, Y, Z, U, V, W, /, length=1, arrow_length_ratio=.3, pivot='tail', normalize=False, **kwargs)
ax.quiver(X, Y, Z, U, V, W, /, length=1, arrow_length_ratio=.3, \
pivot='tail', normalize=False, **kwargs)
Copy link
Member

Choose a reason for hiding this comment

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

Can this be indented to align with the bracket in the line above?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

not really, that'll look awkward in the actual docstring (the problem is the same as always re: line continuations in rst).

Copy link
Contributor

Choose a reason for hiding this comment

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

I think treating the first line of the docstring as a replacement __signature__ is a sphinx thing, not an rst thing - it's possible it gets handled before the RST parser kicks in.


Plot a 3D field of arrows.

Expand Down Expand Up @@ -2549,7 +2550,8 @@ def calc_arrow(uvw, angle=15):
[-y*s, x*s, c]])
# opposite rotation negates all the sin terms
Rneg = Rpos.copy()
Rneg[[0, 1, 2, 2], [2, 2, 0, 1]] = -Rneg[[0, 1, 2, 2], [2, 2, 0, 1]]
Rneg[[0, 1, 2, 2], [2, 2, 0, 1]] = \
-Rneg[[0, 1, 2, 2], [2, 2, 0, 1]]

# multiply them to get the rotated vector
return Rpos.dot(uvw), Rneg.dot(uvw)
Expand All @@ -2569,7 +2571,8 @@ def calc_arrow(uvw, angle=15):
for k in input_args]

# extract the masks, if any
masks = [k.mask for k in input_args if isinstance(k, np.ma.MaskedArray)]
masks = [k.mask for k in input_args
if isinstance(k, np.ma.MaskedArray)]
# broadcast to match the shape
bcast = np.broadcast_arrays(*(input_args + masks))
input_args = bcast[:argi]
Expand Down Expand Up @@ -2622,9 +2625,9 @@ def calc_arrow(uvw, angle=15):
if len(XYZ) > 0:
# compute the shaft lines all at once with an outer product
shafts = (XYZ - np.multiply.outer(shaft_dt, UVW)).swapaxes(0, 1)
# compute head direction vectors, n heads by 2 sides by 3 dimensions
# compute head direction vectors, n heads x 2 sides x 3 dimensions
head_dirs = np.array([calc_arrow(d) for d in UVW])
# compute all head lines at once, starting from where the shaft ends
# compute all head lines at once, starting from the shaft ends
heads = shafts[:, :1] - np.multiply.outer(arrow_dt, head_dirs)
# stack left and right head lines together
heads.shape = (len(arrow_dt), -1, 3)
Expand Down Expand Up @@ -2669,13 +2672,13 @@ def voxels(self, *args, facecolors=None, edgecolors=None, **kwargs):

x, y, z : 3D np.array, optional
The coordinates of the corners of the voxels. This should broadcast
to a shape one larger in every dimension than the shape of `filled`.
These can be used to plot non-cubic voxels.
to a shape one larger in every dimension than the shape of
`filled`. These can be used to plot non-cubic voxels.

If not specified, defaults to increasing integers along each axis,
like those returned by :func:`~numpy.indices`.
As indicated by the ``/`` in the function signature, these arguments
can only be passed positionally.
As indicated by the ``/`` in the function signature, these
arguments can only be passed positionally.

facecolors, edgecolors : array_like, optional
The color to draw the faces and edges of the voxels. Can only be
Expand Down Expand Up @@ -2758,7 +2761,7 @@ def _broadcast_color_arg(color, name):
# broadcast but no default on edgecolors
edgecolors = _broadcast_color_arg(edgecolors, 'edgecolors')

# always scale to the full array, even if the data is only in the center
# scale to the full array, even if the data is only in the center
self.auto_scale_xyz(x, y, z)

# points lying on corners of a square
Expand All @@ -2778,8 +2781,8 @@ def permutation_matrices(n):
yield mat
mat = np.roll(mat, 1, axis=0)

# iterate over each of the YZ, ZX, and XY orientations, finding faces to
# render
# iterate over each of the YZ, ZX, and XY orientations, finding faces
# to render
for permute in permutation_matrices(3):
# find the set of ranges to iterate over
pc, qc, rc = permute.T.dot(size)
Expand Down Expand Up @@ -2822,7 +2825,8 @@ def permutation_matrices(n):
if filled[ik]:
voxel_faces[ik].append(pk2 + square_rot)

# iterate over the faces, and generate a Poly3DCollection for each voxel
# iterate over the faces, and generate a Poly3DCollection for each
# voxel
polygons = {}
for coord, faces_inds in voxel_faces.items():
# convert indices into 3D positions
Expand Down Expand Up @@ -2871,5 +2875,4 @@ def get_test_data(delta=0.05):
# Register Axes3D as a 'projection' object available
# for use just like any other axes
########################################################
import matplotlib.projections as proj
proj.projection_registry.register(Axes3D)