ASKSAGE: Sage Q&A Forum - RSS feedhttps://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Tue, 27 Sep 2016 17:54:04 +0200Customizing the wireframe / strides of a 3D plothttps://ask.sagemath.org/question/33929/customizing-the-wireframe-strides-of-a-3d-plot/I am experimenting with 3D plotting to see how I can customize the output. In particular, I am trying to obtain something more similar to how *Mathematica* or Wolfram Alpha do things.
For example, I plotted Taubin's heart surface:
$$ \left(x^2+\frac{9 y^2}{4} + z^2 - 1\right)^3-x^2 z^3 - \frac{9 y^2 z^3}{80} = 0 $$
Using the following code:
var("x y z")
f = (x^2 + 2.25*y^2 + z^2 - 1)^3 - (x^2)*(z^3) - 0.1125*(y^2)*(z^3)
xint = (x, -1.5, 1.5)
yint = (y, -1.5, 1.5)
zint = (z, -1.5, 1.5)
my_plot = implicit_plot3d(f, xint, yint, zint, opacity=.7, mesh=2)
my_plot.show()
![](http://i.imgur.com/DbLGA50.png)
The mesh corresponds to the triangulation of points that Sage performs on the data calculated with `implicit_plot3d`. However, Wolfram Alpha gives a different result (https://www.wolframalpha.com/input/?i=heart+surface), because it does not use all the edges of the triangulation:
![](http://i.imgur.com/VZtyWql.gif)
What I *think* they are doing is they are using a high number of points to draw the surface, however they are "slicing" the object with planes parallel to the three axes (at fixed distances) to draw the contours.
**How can I replicate these lines?**
Matplotlib calls them "strides" as documented for `Axes3d.plot_surface` (http://matplotlib.org/mpl_toolkits/mplot3d/tutorial.html#surface-plots). My final goal is exporting 3D vector drawings which I managed to do with Matplotlib thanks to the `numpy-stl` package (https://github.com/WoLpH/numpy-stl):
my_plot.triangulate()
my_plot.save("/tmp/test.stl")
from mpl_toolkits import mplot3d
from matplotlib import pyplot
# Create a new plot
figure = pyplot.figure()
axes = mplot3d.Axes3D(figure)
# Load the STL files and add the vectors to the plot
your_mesh = mesh.Mesh.from_file('/tmp/test.stl')
axes.add_collection3d(mplot3d.art3d.Poly3DCollection(your_mesh.vectors))
# Auto scale to the mesh size
scale = your_mesh.points.flatten(-1)
axes.auto_scale_xyz(scale, scale, scale)
# Show the plot to the screen
pyplot.show()
pyplot.savefig("/home/andrea/Scrivania/wow.pdf")
In this case the presence of too much grid lines looks even worse:
![](http://i.imgur.com/s0LniGy.png)Sun, 26 Jun 2016 18:57:57 +0200https://ask.sagemath.org/question/33929/customizing-the-wireframe-strides-of-a-3d-plot/Comment by Lazza for <p>I am experimenting with 3D plotting to see how I can customize the output. In particular, I am trying to obtain something more similar to how <em>Mathematica</em> or Wolfram Alpha do things.</p>
<p>For example, I plotted Taubin's heart surface:</p>
<p>$$ \left(x^2+\frac{9 y^2}{4} + z^2 - 1\right)^3-x^2 z^3 - \frac{9 y^2 z^3}{80} = 0 $$</p>
<p>Using the following code:</p>
<pre><code>var("x y z")
f = (x^2 + 2.25*y^2 + z^2 - 1)^3 - (x^2)*(z^3) - 0.1125*(y^2)*(z^3)
xint = (x, -1.5, 1.5)
yint = (y, -1.5, 1.5)
zint = (z, -1.5, 1.5)
my_plot = implicit_plot3d(f, xint, yint, zint, opacity=.7, mesh=2)
my_plot.show()
</code></pre>
<p><img alt="" src="http://i.imgur.com/DbLGA50.png"></p>
<p>The mesh corresponds to the triangulation of points that Sage performs on the data calculated with <code>implicit_plot3d</code>. However, Wolfram Alpha gives a different result (<a href="https://www.wolframalpha.com/input/?i=heart+surface">https://www.wolframalpha.com/input/?i...</a>), because it does not use all the edges of the triangulation:</p>
<p><img alt="" src="http://i.imgur.com/VZtyWql.gif"></p>
<p>What I <em>think</em> they are doing is they are using a high number of points to draw the surface, however they are "slicing" the object with planes parallel to the three axes (at fixed distances) to draw the contours.</p>
<p><strong>How can I replicate these lines?</strong></p>
<p>Matplotlib calls them "strides" as documented for <code>Axes3d.plot_surface</code>(<a href="http://matplotlib.org/mpl_toolkits/mplot3d/tutorial.html#surface-plots">http://matplotlib.org/mpl_toolkits/mp...</a>). My final goal is exporting 3D vector drawings which I managed to do with Matplotlib thanks to the <code>numpy-stl</code>package (<a href="https://github.com/WoLpH/numpy-stl">https://github.com/WoLpH/numpy-stl</a>):</p>
<pre><code>my_plot.triangulate()
my_plot.save("/tmp/test.stl")
from mpl_toolkits import mplot3d
from matplotlib import pyplot
# Create a new plot
figure = pyplot.figure()
axes = mplot3d.Axes3D(figure)
# Load the STL files and add the vectors to the plot
your_mesh = mesh.Mesh.from_file('/tmp/test.stl')
axes.add_collection3d(mplot3d.art3d.Poly3DCollection(your_mesh.vectors))
# Auto scale to the mesh size
scale = your_mesh.points.flatten(-1)
axes.auto_scale_xyz(scale, scale, scale)
# Show the plot to the screen
pyplot.show()
pyplot.savefig("/home/andrea/Scrivania/wow.pdf")
</code></pre>
<p>In this case the presence of too much grid lines looks even worse:</p>
<p><img alt="" src="http://i.imgur.com/s0LniGy.png"></p>
https://ask.sagemath.org/question/33929/customizing-the-wireframe-strides-of-a-3d-plot/?comment=33930#post-id-33930Sorry for the ugly formatting but the website wouldn't allow me to post the Q until I dropped all links. Someone with enough rep please fix the links and images. Thank you.Sun, 26 Jun 2016 18:58:39 +0200https://ask.sagemath.org/question/33929/customizing-the-wireframe-strides-of-a-3d-plot/?comment=33930#post-id-33930Answer by paulmasson for <p>I am experimenting with 3D plotting to see how I can customize the output. In particular, I am trying to obtain something more similar to how <em>Mathematica</em> or Wolfram Alpha do things.</p>
<p>For example, I plotted Taubin's heart surface:</p>
<p>$$ \left(x^2+\frac{9 y^2}{4} + z^2 - 1\right)^3-x^2 z^3 - \frac{9 y^2 z^3}{80} = 0 $$</p>
<p>Using the following code:</p>
<pre><code>var("x y z")
f = (x^2 + 2.25*y^2 + z^2 - 1)^3 - (x^2)*(z^3) - 0.1125*(y^2)*(z^3)
xint = (x, -1.5, 1.5)
yint = (y, -1.5, 1.5)
zint = (z, -1.5, 1.5)
my_plot = implicit_plot3d(f, xint, yint, zint, opacity=.7, mesh=2)
my_plot.show()
</code></pre>
<p><img alt="" src="http://i.imgur.com/DbLGA50.png"></p>
<p>The mesh corresponds to the triangulation of points that Sage performs on the data calculated with <code>implicit_plot3d</code>. However, Wolfram Alpha gives a different result (<a href="https://www.wolframalpha.com/input/?i=heart+surface">https://www.wolframalpha.com/input/?i...</a>), because it does not use all the edges of the triangulation:</p>
<p><img alt="" src="http://i.imgur.com/VZtyWql.gif"></p>
<p>What I <em>think</em> they are doing is they are using a high number of points to draw the surface, however they are "slicing" the object with planes parallel to the three axes (at fixed distances) to draw the contours.</p>
<p><strong>How can I replicate these lines?</strong></p>
<p>Matplotlib calls them "strides" as documented for <code>Axes3d.plot_surface</code>(<a href="http://matplotlib.org/mpl_toolkits/mplot3d/tutorial.html#surface-plots">http://matplotlib.org/mpl_toolkits/mp...</a>). My final goal is exporting 3D vector drawings which I managed to do with Matplotlib thanks to the <code>numpy-stl</code>package (<a href="https://github.com/WoLpH/numpy-stl">https://github.com/WoLpH/numpy-stl</a>):</p>
<pre><code>my_plot.triangulate()
my_plot.save("/tmp/test.stl")
from mpl_toolkits import mplot3d
from matplotlib import pyplot
# Create a new plot
figure = pyplot.figure()
axes = mplot3d.Axes3D(figure)
# Load the STL files and add the vectors to the plot
your_mesh = mesh.Mesh.from_file('/tmp/test.stl')
axes.add_collection3d(mplot3d.art3d.Poly3DCollection(your_mesh.vectors))
# Auto scale to the mesh size
scale = your_mesh.points.flatten(-1)
axes.auto_scale_xyz(scale, scale, scale)
# Show the plot to the screen
pyplot.show()
pyplot.savefig("/home/andrea/Scrivania/wow.pdf")
</code></pre>
<p>In this case the presence of too much grid lines looks even worse:</p>
<p><img alt="" src="http://i.imgur.com/s0LniGy.png"></p>
https://ask.sagemath.org/question/33929/customizing-the-wireframe-strides-of-a-3d-plot/?answer=33934#post-id-33934One thing you can do for starters is turn off the mesh with `mesh=false` since that keyword argument is Boolean. You can also improve the smoothness of the surface by setting `plot_points` higher than it's default of 40 in each direction.
If the surface could always be solved for each independent variable, one way to draw contour-like lines would be setting one variable to a constant, solving for the second in terms of the third and using `parametric_plot`. Since you can't do that for this surface, here's a workaround using a series of `implicit_plot3d` for lines with constant y-value:
for i in [ .1*j - .6 for j in range(0,13)]:
g = (x^2 + 2.25*i^2 + z^2 - 1)^3 - (x^2)*(z^3) - 0.1125*(i^2)*(z^3)
my_plot += implicit_plot3d(g, xint, (y,i-.01,i+.01), zint, color='black')
Here's a [link](http://sagecell.sagemath.org/?z=eJyNkcFuhCAQhu8kvMPcBEUimm2TJj5JUzfWqotVMWoa4ek7uOum217K4Yf5ZhjyD1_lzIINLLiAU0JJAzmwrUghglSmp9DuR4cag-JFhptP85C5IuMYJVIprGP2DinZ9LjufQTESp4EoCC2N2wfsbth94gpGex56o3P6WHqdaXXPc4-WCPAvyHA7up2NVOJJTaXzwKGernkTdkvtQB_5zwZrFlylSRXm2YGDXqEV5Aq7NCHfAIPOw_ncmxrlgiV8bcXSgBX-2su-r9z0T_m4hsdpqK_rtrDFU5IxzJRQkeo_DBYmd7MefDel9Xn9bcoWS9zXXcLu_fl32Q5exw=&lang=sage) to a live example. The function `threejs` at the end is a SageMathCell alternative to `show`.Mon, 27 Jun 2016 02:02:04 +0200https://ask.sagemath.org/question/33929/customizing-the-wireframe-strides-of-a-3d-plot/?answer=33934#post-id-33934Comment by slelievre for <p>One thing you can do for starters is turn off the mesh with <code>mesh=false</code> since that keyword argument is Boolean. You can also improve the smoothness of the surface by setting <code>plot_points</code> higher than it's default of 40 in each direction.</p>
<p>If the surface could always be solved for each independent variable, one way to draw contour-like lines would be setting one variable to a constant, solving for the second in terms of the third and using <code>parametric_plot</code>. Since you can't do that for this surface, here's a workaround using a series of <code>implicit_plot3d</code> for lines with constant y-value:</p>
<pre><code>for i in [ .1*j - .6 for j in range(0,13)]:
g = (x^2 + 2.25*i^2 + z^2 - 1)^3 - (x^2)*(z^3) - 0.1125*(i^2)*(z^3)
my_plot += implicit_plot3d(g, xint, (y,i-.01,i+.01), zint, color='black')
</code></pre>
<p>Here's a <a href="http://sagecell.sagemath.org/?z=eJyNkcFuhCAQhu8kvMPcBEUimm2TJj5JUzfWqotVMWoa4ek7uOum217K4Yf5ZhjyD1_lzIINLLiAU0JJAzmwrUghglSmp9DuR4cag-JFhptP85C5IuMYJVIprGP2DinZ9LjufQTESp4EoCC2N2wfsbth94gpGex56o3P6WHqdaXXPc4-WCPAvyHA7up2NVOJJTaXzwKGernkTdkvtQB_5zwZrFlylSRXm2YGDXqEV5Aq7NCHfAIPOw_ncmxrlgiV8bcXSgBX-2su-r9z0T_m4hsdpqK_rtrDFU5IxzJRQkeo_DBYmd7MefDel9Xn9bcoWS9zXXcLu_fl32Q5exw=&lang=sage">link</a> to a live example. The function <code>threejs</code> at the end is a SageMathCell alternative to <code>show</code>.</p>
https://ask.sagemath.org/question/33929/customizing-the-wireframe-strides-of-a-3d-plot/?comment=34975#post-id-34975@Lazza, new users can't upvote but they can accept answers (click the tick mark next to the answer).Tue, 27 Sep 2016 17:54:04 +0200https://ask.sagemath.org/question/33929/customizing-the-wireframe-strides-of-a-3d-plot/?comment=34975#post-id-34975Comment by Lazza for <p>One thing you can do for starters is turn off the mesh with <code>mesh=false</code> since that keyword argument is Boolean. You can also improve the smoothness of the surface by setting <code>plot_points</code> higher than it's default of 40 in each direction.</p>
<p>If the surface could always be solved for each independent variable, one way to draw contour-like lines would be setting one variable to a constant, solving for the second in terms of the third and using <code>parametric_plot</code>. Since you can't do that for this surface, here's a workaround using a series of <code>implicit_plot3d</code> for lines with constant y-value:</p>
<pre><code>for i in [ .1*j - .6 for j in range(0,13)]:
g = (x^2 + 2.25*i^2 + z^2 - 1)^3 - (x^2)*(z^3) - 0.1125*(i^2)*(z^3)
my_plot += implicit_plot3d(g, xint, (y,i-.01,i+.01), zint, color='black')
</code></pre>
<p>Here's a <a href="http://sagecell.sagemath.org/?z=eJyNkcFuhCAQhu8kvMPcBEUimm2TJj5JUzfWqotVMWoa4ek7uOum217K4Yf5ZhjyD1_lzIINLLiAU0JJAzmwrUghglSmp9DuR4cag-JFhptP85C5IuMYJVIprGP2DinZ9LjufQTESp4EoCC2N2wfsbth94gpGex56o3P6WHqdaXXPc4-WCPAvyHA7up2NVOJJTaXzwKGernkTdkvtQB_5zwZrFlylSRXm2YGDXqEV5Aq7NCHfAIPOw_ncmxrlgiV8bcXSgBX-2su-r9z0T_m4hsdpqK_rtrDFU5IxzJRQkeo_DBYmd7MefDel9Xn9bcoWS9zXXcLu_fl32Q5exw=&lang=sage">link</a> to a live example. The function <code>threejs</code> at the end is a SageMathCell alternative to <code>show</code>.</p>
https://ask.sagemath.org/question/33929/customizing-the-wireframe-strides-of-a-3d-plot/?comment=33949#post-id-33949Thanks for your answer! Unfortunately I cannot upvote it yet. I have tweaked it a bit, obtaining this: `sagecell.sagemath.org/?q=jrogwx`. There is still the problem that those are actually "slices" of a 3D object and therefore have one side which is a line and one side which is thick (depending on the width). I will try to figure out how to draw just lines for them.Tue, 28 Jun 2016 15:44:17 +0200https://ask.sagemath.org/question/33929/customizing-the-wireframe-strides-of-a-3d-plot/?comment=33949#post-id-33949