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

surf(x,y,z,c) function? #264

Closed
BoundaryValueProblems opened this issue Dec 15, 2016 · 5 comments
Closed

surf(x,y,z,c) function? #264

BoundaryValueProblems opened this issue Dec 15, 2016 · 5 comments

Comments

@BoundaryValueProblems
Copy link

I am wondering if we can plot a 3D surface with its surface color shading specified by an input array c. Currently, the surface color is proportional to the height z. Many people want to display the color specified by another array c on top of the 3D surfaces specified by the coordinates x, y, z. Apparently, it is possible to do this using matplotlib directly, but I definitely want to stay with PyPlot level functions rather than directly using matplotlib. Here is the link to the direct use of matplotlib to do surf(x,y,z,c) like MATLAB: http://stackoverflow.com/questions/22175533/what-is-the-equivalent-of-matlabs-surfx-y-z-c-in-matplotlib
Thanks for your help!
BVPs

@stevengj
Copy link
Member

stevengj commented Dec 15, 2016

Have you tried plot_surface(X, Y, Z, rstride=1, cstride=1, facecolors=C, antialiased=True), exactly like in the example you linked? (You don't need to create the axis object manually, although you can if you want; PyPlot will create it for you when you call plot_surface.)

surf in PyPlot is just an alias for Matplotlib's plot_trisurf and doesn't seem to take a facecolors option.

See also #91.

@BoundaryValueProblems
Copy link
Author

Thanks a lot, Steven.
I tried it, but with facecolors=C, it didn't work. It generated the following error:
PyError (:PyObject_Call) <type 'exceptions.ValueError'>
ValueError(u'to_rgba: Invalid rgba arg "1.0"\nto_rgb: Invalid rgb arg "1.0"\ncannot convert argument to rgb sequence',)
...
So, the values of the color spec array C may not be appropriate. To be concrete, here is what I tried to do. I wanted to display z.^3 over the unit disk in the complex plane with the height as real(z.^3) and the surface color as imag(z.^3), which is similar to what MATLAB's cplxmap function does:

m=32
r = (0:m)''/m
theta = reshape(pi*(-m:m)/m, 1, 2*m+1)
z = r * exp(im*theta)
plot_surface(real(z), imag(z), real(z.^3), rstride=1, cstride=1, facecolors=imag(z.^3), antialiased=true)

Just in case, imag(z.^3) is Matrix{Float64} of size 33 x 65, and its value range is between -1.0 and 1.0. If facecolors attribute does not accept the real-valued matrix with this kind of property, how can I convert it to a proper color array? That is not clear to me even after reading #91.
Thanks!
BVPs
Thanks for your further help!

@BoundaryValueProblems
Copy link
Author

Steven:
OK, I further did some experiment and I found out that I have to first get a proper colormap function for example, viri=get_cmap("viridis") and then supply facecolors=viri(imag(z.^3)) in my example. But then a question still remains: how to ensure that the full dynamic range of the colormap is used for the supplied input array, in this case, imag(z.^3)? Do I need to do normalization of image(z.^3) explicitly? Currently, if I supply viri(a+image(z.^3)) with a = 0, 1, 2, ..., for each value of a, it uses the different part of the colormap. The description of #91 about colormap normalization using matplotlib.colors.Normalize() is not clear to me.
Thanks!
BVPs

@BoundaryValueProblems
Copy link
Author

If I normalize the supplied array ranging from 0.0 to 1.0, it seems that the full range of the colormap is used. Am I correct? In my example,

tmp=imag(z.^3); tmp=(tmp-minimum(tmp))/(maximum(tmp)-minimum(tmp))
plot_surface(real(z),imag(z), real(z.^3),rstride=1, cstride=1, facecolors=viri(tmp))

The normalization via matplotlib.colors.Normalize() is supposed to do the same as my explicit normalization as above or does something else?
Best,
BVPs

@stevengj
Copy link
Member

I think that's correct, but you would have to check with matplotlib to be sure.

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