Black lines when saving 3D surface to pdf: how can I get rid of them?

I have the following code to render a 3D surface using ax.plot_surface

:

fig = plt.figure()
ax  = fig.gca(projection='3d')
X,Y = np.meshgrid(range(k_mean.shape[0]), range(k_mean.shape[1])) 
Z   = k_mean
surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, linewidth=0., alpha=0.8, cmap=cm.nipy_spectral, antialiased=False, shade=False)
cset = ax.contour(X, Y, Z, zdir='z', offset=0, cmap=cm.nipy_spectral)
cset = ax.contour(X, Y, Z, zdir='x', offset=0, cmap=cm.nipy_spectral)
cset = ax.contour(X, Y, Z, zdir='y', offset=120, cmap=cm.nipy_spectral)

ax.set_xlim(0, 120)
ax.set_ylim(0, 120)
ax.set_zlim(0, 1)

fig.colorbar(surf, shrink=0.5, aspect=5)
plt.show()
plt.savefig('3d.pdf', dpi=500)

      

The plot display in Spyder is "correct", but the PDF seems to be ignoring linewidth=0.

. How can I fix this?

Spyder output: Spyder output

PDF output: PDF output

+3


source to share


2 answers


matplotlib github thinks this is fixed, but that the fix did not make it to v1.4.1 but will be posted to v1.4.3 https://github.com/matplotlib/matplotlib/issues/2247



+3


source


As others have pointed out, this is due to a bug in the pdf file that needs to be resolved in the newest version of matplotlib.

This is a hack / workaround to get slightly better results in older versions too. You can explicitly set the transparency of edgecolor:

surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm,
        linewidth=0, antialiased=True, edgecolor=(0,0,0,0))

      

Results for comparison: enter image description hereenter image description here



EDIT:

As pointed out in the comments, using the keyword alpha

overwrites the alpha value of the edge color. Thus, we must explicitly define the transparency for the complexions. The easiest way I can see is to adapt the color code:

from matplotlib.colors import LinearSegmentedColormap

colors = np.array(cm.coolwarm(np.linspace(0,1,256)))
colors[:,3] = 0.6
cmap = LinearSegmentedColormap.from_list('alpha_cmap', colors.tolist())

surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cmap,
        linewidth=0, antialiased=True, edgecolor=(0,0,0,0))

      

Result: enter image description here

+3


source







All Articles