0

I'm plotting scatter data together with a surface of best fit using ax.plot_surface():

fig = plt.figure(figsize = (7,5))
ax = fig.add_subplot(111, projection='3d')

ax.plot_surface(X, Y, Z, cmap=plt.cm.coolwarm, alpha=0.25, edgecolor='black', linewidth=.25, zorder=-1)
ax.scatter(x_filtered, y_filtered, z_filtered, alpha=0.25, lw=0, color='black', zorder=10)

ax.axes.set_xlim3d(left=0, right=20) 
ax.axes.set_ylim3d(top=0, bottom=250000) 
ax.axes.set_zlim3d(bottom=0, top=40000) 

x_start, x_end = ax.get_xlim()
z_start, z_end = ax.get_zlim()
ax.xaxis.set_ticks(np.arange(x_start, x_end, 5))
ax.zaxis.set_ticks(np.arange(z_start, z_end, 10000))

ax.set_xlabel('\nAge (y)')
ax.set_ylabel('\nMileage (k)')
ax.set_zlabel('Price ($k)')

plt.rcParams['axes.unicode_minus'] = False
plt.grid(); ax.grid(color=(.9, .9, .9)); ax.set_axisbelow(True)

import matplotlib.ticker as ticker
ticks = ticker.FuncFormatter(lambda y_filtered, pos: '{0:g}'.format(y_filtered/1000))
ticks = ticker.FuncFormatter(lambda z_filtered, pos: '{0:g}'.format(z_filtered/1000))
ax.yaxis.set_major_formatter(ticks)
ax.zaxis.set_major_formatter(ticks)

ax.view_init(60, -45)
ax.dist = 10.75

plt.show()    

When viewed at 60 degrees from horizontal, the scatter points lying above the surface are correctly displayed:

enter image description here

On the other hand, when viewed at 5 degrees from horizontal, the scatter points look as if they are all underneath the surface:

enter image description here

I prefer the second perspective, but would like the scatter data lying above the surface of best fit to be displayed properly.

As you can see, I've tried forcing the scatter data upwards using zorder but was unsuccessful.

Is there something I need to do to fix the display of scatter points?

Michael Boles
  • 369
  • 5
  • 15
  • See https://stackoverflow.com/questions/51241367/matplotlib-surface-plot-hides-scatter-points-which-should-be-in-front – JohanC Feb 05 '20 at 22:10
  • Thank you. From this answer, it looks like I should add a patch object with my (x,y) scatter data and then point it to the z-values. I tried: ```scatter_data = [x_filtered, y_filtered] ax.add_patch(scatter_data) from mpl_toolkits.mplot3d import art3d art3d.pathpatch_2d_to_3d(scatter_data, z=z_filtered, zdir="z")```. Doesn't work -- seems like I'm going to need to dig into the details of creating patches. Is this the only way to correctly display this information? – Michael Boles Feb 05 '20 at 22:35

0 Answers0