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

Skip to content

Make markerfacecolor work for 3d scatterplots #10693

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

Closed
Closed
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
69 changes: 58 additions & 11 deletions lib/mpl_toolkits/mplot3d/art3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,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.:
if dx == 0. and dy == 0.:
# atan2 raises ValueError: math domain error on 0,0
angle = 0.
else:
Expand Down Expand Up @@ -200,7 +200,8 @@ class Line3DCollection(LineCollection):

def __init__(self, segments, *args, **kwargs):
'''
Keyword arguments are passed onto :func:`~matplotlib.collections.LineCollection`.
Keyword arguments are passed onto
:func:`~matplotlib.collections.LineCollection`.
'''
LineCollection.__init__(self, segments, *args, **kwargs)

Expand Down Expand Up @@ -309,7 +310,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 @@ -449,24 +450,70 @@ def set_3d_properties(self, zs, zdir):
self._edgecolor3d = self.get_edgecolor()
self.stale = True

def set_facecolor(self, colors):
'''
Override setter for facecolor so that 3dfacecolor
will be updated as well.
In providing consitentcy in 2dcolor and 3dcolor setter.
Note: will also update edgecolor if it follows facecolor
'''

PathCollection.set_facecolor(self, colors)
self._facecolor3d = PathCollection.get_facecolor(self)
try:
# Will update edge color together if it follows facecolor
if (isinstance(self._edgecolors, six.string_types) and
self._edgecolors == str('face')):
self.set_edgecolor(colors)
except AttributeError:
pass
set_facecolors = set_facecolor

def set_edgecolor(self, colors):
'''
Override setter for edgecolor so that 3dedgecolor
will be updated as well.
In providing consitentcy in 2dcolor and 3dcolor setter.
'''

PathCollection.set_edgecolor(self, colors)
self._edgecolor3d = PathCollection.get_edgecolor(self)
set_edgecolors = set_edgecolor

def _set_facecolor_on_projection(self, color):
'''
A sepearted method that changes edgecolor in drawing
as in this case, we dont change 3d facecolor
'''

super().set_facecolor(color)

def _set_edgecolor_on_projection(self, color):
'''
A sepearted method that changes edgecolor in drawing
as in this case, we dont change 3d edgecolor
'''

super().set_edgecolor(color)

def do_3d_projection(self, renderer):
xs, ys, zs = self._offsets3d
vxs, vys, vzs, vis = proj3d.proj_transform_clip(xs, ys, zs, renderer.M)

fcs = (zalpha(self._facecolor3d, vzs) if self._depthshade else
self._facecolor3d)
fcs = mcolors.to_rgba_array(fcs, self._alpha)
self.set_facecolors(fcs)
self._set_facecolor_on_projection(fcs)

ecs = (zalpha(self._edgecolor3d, vzs) if self._depthshade else
self._edgecolor3d)
ecs = mcolors.to_rgba_array(ecs, self._alpha)
self.set_edgecolors(ecs)
self._set_edgecolor_on_projection(ecs)
PathCollection.set_offsets(self, np.column_stack([vxs, vys]))

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


Expand Down Expand Up @@ -561,7 +608,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 @@ -595,7 +642,7 @@ def set_3d_properties(self):
self._alpha3d = PolyCollection.get_alpha(self)
self.stale = True

def set_sort_zpos(self,val):
def set_sort_zpos(self, val):
'''Set the position to use for z-sorting.'''
self._sort_zpos = val
self.stale = True
Expand Down Expand Up @@ -652,12 +699,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:
return np.nan

def set_facecolor(self, colors):
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
52 changes: 42 additions & 10 deletions lib/mpl_toolkits/tests/test_mplot3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,32 @@ def test_scatter3d_color():
color='b', marker='s')


@image_comparison(baseline_images=['scatter_face_color_change'],
remove_text=True, extensions=['png'])
def test_scatter_face_color_change():
# Take the test data from above
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
scat = ax.scatter(np.arange(10), np.arange(10), np.arange(10),
facecolors="red")
# changes facecolor, it should also change edgecolor when displayed
scat.set_facecolors("green")


@image_comparison(baseline_images=['scatter_edgecolor_nochange'],
remove_text=True, extensions=['png'])
def test_scatter_edgecolor_nochange():
# test to ensure edge color is not updated with facecolor if it
# is set at the beginning
# Take the test data from above
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
scat = ax.scatter(np.arange(10), np.arange(10), np.arange(10),
facecolors="red", edgecolors="blue")
# changes facecolor, it should not change edgecolor when displayed
scat.set_edgecolors("green")


@image_comparison(baseline_images=['surface3d'], remove_text=True)
def test_surface3d():
fig = plt.figure()
Expand Down Expand Up @@ -305,10 +331,11 @@ def test_quiver3d():
u = np.sin(np.pi * x) * np.cos(np.pi * y) * np.cos(np.pi * z)
v = -np.cos(np.pi * x) * np.sin(np.pi * y) * np.cos(np.pi * z)
w = (np.sqrt(2.0 / 3.0) * np.cos(np.pi * x) * np.cos(np.pi * y) *
np.sin(np.pi * z))
np.sin(np.pi * z))

ax.quiver(x, y, z, u, v, w, length=0.1, pivot='tip', normalize=True)


@image_comparison(baseline_images=['quiver3d_empty'], remove_text=True)
def test_quiver3d_empty():
fig = plt.figure()
Expand All @@ -319,10 +346,11 @@ def test_quiver3d_empty():
u = np.sin(np.pi * x) * np.cos(np.pi * y) * np.cos(np.pi * z)
v = -np.cos(np.pi * x) * np.sin(np.pi * y) * np.cos(np.pi * z)
w = (np.sqrt(2.0 / 3.0) * np.cos(np.pi * x) * np.cos(np.pi * y) *
np.sin(np.pi * z))
np.sin(np.pi * z))

ax.quiver(x, y, z, u, v, w, length=0.1, pivot='tip', normalize=True)


@image_comparison(baseline_images=['quiver3d_masked'], remove_text=True)
def test_quiver3d_masked():
fig = plt.figure()
Expand All @@ -335,12 +363,13 @@ def test_quiver3d_masked():
u = np.sin(np.pi * x) * np.cos(np.pi * y) * np.cos(np.pi * z)
v = -np.cos(np.pi * x) * np.sin(np.pi * y) * np.cos(np.pi * z)
w = (np.sqrt(2.0 / 3.0) * np.cos(np.pi * x) * np.cos(np.pi * y) *
np.sin(np.pi * z))
np.sin(np.pi * z))
u = np.ma.masked_where((-0.4 < x) & (x < 0.1), u, copy=False)
v = np.ma.masked_where((0.1 < y) & (y < 0.7), v, copy=False)

ax.quiver(x, y, z, u, v, w, length=0.1, pivot='tip', normalize=True)


@image_comparison(baseline_images=['quiver3d_pivot_middle'], remove_text=True,
extensions=['png'])
def test_quiver3d_pivot_middle():
Expand All @@ -352,10 +381,11 @@ def test_quiver3d_pivot_middle():
u = np.sin(np.pi * x) * np.cos(np.pi * y) * np.cos(np.pi * z)
v = -np.cos(np.pi * x) * np.sin(np.pi * y) * np.cos(np.pi * z)
w = (np.sqrt(2.0 / 3.0) * np.cos(np.pi * x) * np.cos(np.pi * y) *
np.sin(np.pi * z))
np.sin(np.pi * z))

ax.quiver(x, y, z, u, v, w, length=0.1, pivot='middle', normalize=True)


@image_comparison(baseline_images=['quiver3d_pivot_tail'], remove_text=True,
extensions=['png'])
def test_quiver3d_pivot_tail():
Expand All @@ -367,7 +397,7 @@ def test_quiver3d_pivot_tail():
u = np.sin(np.pi * x) * np.cos(np.pi * y) * np.cos(np.pi * z)
v = -np.cos(np.pi * x) * np.sin(np.pi * y) * np.cos(np.pi * z)
w = (np.sqrt(2.0 / 3.0) * np.cos(np.pi * x) * np.cos(np.pi * y) *
np.sin(np.pi * z))
np.sin(np.pi * z))

ax.quiver(x, y, z, u, v, w, length=0.1, pivot='tail', normalize=True)

Expand Down Expand Up @@ -414,17 +444,18 @@ def test_axes3d_labelpad():
def test_axes3d_cla():
# fixed in pull request 4553
fig = plt.figure()
ax = fig.add_subplot(1,1,1, projection='3d')
ax = fig.add_subplot(1, 1, 1, projection='3d')
ax.set_axis_off()
ax.cla() # make sure the axis displayed is 3D (not 2D)


def test_plotsurface_1d_raises():
x = np.linspace(0.5, 10, num=100)
y = np.linspace(0.5, 10, num=100)
X, Y = np.meshgrid(x, y)
z = np.random.randn(100)

fig = plt.figure(figsize=(14,6))
fig = plt.figure(figsize=(14, 6))
ax = fig.add_subplot(1, 2, 1, projection='3d')
with pytest.raises(ValueError):
ax.plot_surface(X, Y, z)
Expand Down Expand Up @@ -523,6 +554,7 @@ def test_proj_axes_cube_ortho():
ax.set_xlim(-200, 200)
ax.set_ylim(-200, 200)


def test_rot():
V = [1, 0, 0, 1]
rotated_V = proj3d.rot_x(V, np.pi / 6)
Expand Down Expand Up @@ -663,9 +695,9 @@ def test_rgb_data(self):
x, y, z = np.indices((10, 10, 10))
voxels = (x == y) | (y == z)
colors = np.zeros((10, 10, 10, 3))
colors[...,0] = x/9.0
colors[...,1] = y/9.0
colors[...,2] = z/9.0
colors[..., 0] = x/9.0
colors[..., 1] = y/9.0
colors[..., 2] = z/9.0
ax.voxels(voxels, facecolors=colors)

@image_comparison(
Expand Down