Skip to content
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

write matplotlib surfaceplot to stl file #19

Closed
jkokorian opened this issue Jan 6, 2016 · 7 comments
Closed

write matplotlib surfaceplot to stl file #19

jkokorian opened this issue Jan 6, 2016 · 7 comments

Comments

@jkokorian
Copy link

Would it be possible to write a matplotlib trisurf plot to an stl file? (I was hoping to print my graphs on a 3d printer)

I've been messing around with the Poly3dCollection object that is returned by the trisurf command, but I do not understand how you can get the actual vectors out of it. I also do not completely understand what sort of data the Mesh constructor expects.

# %load http://matplotlib.org/mpl_examples/mplot3d/trisurf3d_demo2.py
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.tri as mtri

# u, v are parameterisation variables
u = (np.linspace(0, 2.0 * np.pi, endpoint=True, num=50) * np.ones((10, 1))).flatten()
v = np.repeat(np.linspace(-0.5, 0.5, endpoint=True, num=10), repeats=50).flatten()

# This is the Mobius mapping, taking a u, v pair and returning an x, y, z
# triple
x = (1 + 0.5 * v * np.cos(u / 2.0)) * np.cos(u)
y = (1 + 0.5 * v * np.cos(u / 2.0)) * np.sin(u)
z = 0.5 * v * np.sin(u / 2.0)

# Triangulate parameter space to determine the triangles
tri = mtri.Triangulation(u, v)

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1, projection='3d')

# The triangles in parameter space determine which x, y, z points are
# connected by an edge
mobius_polycollection = ax.plot_trisurf(x, y, z, triangles=tri.triangles, cmap=plt.cm.Spectral)


# now convert mobius_polycollection to mesh
import stl

mobius_mesh = #I have no idea...

mobius_mesh.save('mobius.stl')
@jkokorian
Copy link
Author

I'm hoping this is trivial for you, but if it's not, could you give me some pointers?

@wolph
Copy link
Owner

wolph commented Jan 6, 2016

It took me a bit of experimenting as well, but this seems to do it:

from stl import mesh

data = np.zeros(len(tri.triangles), dtype=mesh.Mesh.dtype)
mobius_mesh = mesh.Mesh(data, remove_empty_areas=False)
mobius_mesh.x[:] = x[tri.triangles]
mobius_mesh.y[:] = y[tri.triangles]
mobius_mesh.z[:] = z[tri.triangles]
mobius_mesh.save('mobius.stl')

@wolph
Copy link
Owner

wolph commented Jan 6, 2016

And the result of the rendered strip using the example from the README.rst

image

@jkokorian
Copy link
Author

Can you do it purely based on what you get from the mobius_polycollection variable? In most cases one would just create a surface plot from some x,y,z data without explicitly defining the triangles. Sorry I didn't make that clear in the first place, I should have taken a simpler example.

@jkokorian
Copy link
Author

Just to be completely clear: what I'm after is to be able to 3d-print any 3d surface plot that I make based on some x,y,z data. I'll come up with a better example soon.

@wolph
Copy link
Owner

wolph commented Jan 10, 2016

The problem is that for STL files you need to have triangulated data, luckily Matplotlib has several solutions for that: http://matplotlib.org/api/tri_api.html

It seems that mobius_polycollection._vec might contain the needed data but Matplotlib appears to have very little useful documentation about these properties: http://matplotlib.org/mpl_toolkits/mplot3d/api.html?highlight=poly3dcollection#mpl_toolkits.mplot3d.art3d.Poly3DCollection
And I'm too strapped for time to look through the source right now.

@wolph
Copy link
Owner

wolph commented Apr 5, 2016

Closing this since it's not really related to this library.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants