Menu

#323 Normal Vector Coloring using Explicit Pm3d Coloring

open
nobody
None
5
2014-10-31
2012-03-06
Douglas
No

Now that we have explicit color in pm3d, there is one last ingredient to make it easy to color a figure based on the normal vector (this is how Mathematica makes it's beautiful 3d plots and helps convey details like shape and curve more effectively than a height-map). It must be possible for gnuplot to determine the normal vector for each tile it places down for the pm3d plot, which allows us to do something like this...

plot '++' u 1:2:3:(color(nvx($1,$2),nvy($1,$2),nvz($1,$2))) w pm3d lc rgb var

An external routine could compute the functions nvx,nvy,nvz and put them in the fourth, fifth, and sixth data columns, but it would be better to be able to feed in a 3D data set and leave the coloring to gnuplot.

Since I am not a developer, I don't know what hidden conventions this would break, but it seems possible and extraordinarily useful, since now we have a platform for beautiful 2D plots, but have to go into the hideously complicated and difficult-to-adjust Mathematica to get 3D plots that convey shape effectively.

To anyone who takes this up or gives a good reason not to, thank you!

Discussion

<< < 1 2 3 > >> (Page 2 of 3)
  • Douglas

    Douglas - 2012-04-19

    color-by-shading at surface, and color-by-palette at base

     
  • Douglas

    Douglas - 2012-04-19

    The new patch and screenshot show what I'm looking for. Palette-based shading in the base, palette+normal-vector shading on the surface. In my opinion, this suffices as a killer app. This form of display indicates the most to my eye about what exactly is going on here.

     
  • Douglas

    Douglas - 2012-04-19

    A couple updates. The patch now accepts three parameters:

    set pm3d corners2color shade STRENGTH, LONGITUDE, LATTITUDE

    where STRENGTH determines the strength of the shading (default 0.5), and LONGITUDE AND LATTITUDE determine the orientation of the "sun" (defaults zero, pointing from the left).

    I have also attached two pictures which I think provide a good example of why such a tool is needed. The script that generated the pictures is

    set xrange [-3:3]
    set yrange [-3:3]
    set samples 100, 100
    set isosamples 100
    set pm3d corners2color shade
    splot '++' u 1:2:(sqrt(9-$1**2-$2**2)) w pm3d

    Without the color-by-shading, it's nearly impossible to see the rough surface, but with the shading, it's now obvious.

     
  • Douglas

    Douglas - 2012-04-19

    Rough surface with color-by-palette

     
  • Douglas

    Douglas - 2012-04-19

    Rough surface with color-by-shading

     
  • Douglas

    Douglas - 2012-04-19

    Error in the script from the last comment. The plot command is:

    splot '++' u 1:2:(0.1*rand(0)+sqrt(9-$1**2-$2**2)) w pm3d

     
  • Douglas

    Douglas - 2012-04-22

    Updated my patch to include the detection of whether the surface normal points towards the camera or away. This requires the normal vector shading and the realistic shading to reverse when you look at the underside of a surface. I have also attached two examples that I am using in my research. My goal was to show the graphene band structure. Part of the figure (not included) shows a "set view map" of the band structure showing and labeling the six "cones", but I also needed a 3d plot to show that they are actually cones. The normal pm3d version doesn't convey this well at all, while it is crystal clear in the shaded version. This is one of those examples where proper shading of the underbelly is necessary.

    set palette defined (0 0.5 0.0 0.0, \ 1 1.0 0.0 0.0, \ 2 1.0 0.5 0.0, \ 3 1.0 1.0 0.0, \ 4 0.5 1.0 0.5, \ 5 0.0 1.0 1.0, \ 6 0.0 0.5 1.0, \ 7 0.0 0.0 1.0, \ 8 0.0 0.0 0.5, \ 9 0.0 0.0 1.0, \ 10 0.0 0.5 1.0, \ 11 0.0 1.0 1.0, \ 12 0.5 1.0 0.5, \ 13 1.0 1.0 0.0, \ 14 1.0 0.5 0.0, \ 15 1.0 0.0 0.0, \ 16 0.5 0.0 0.0 )

    set view 82, 15

    a=1.0
    t = 2.7
    set cbrange [-3*t:3*t]
    g(x,y) = 2*cos(sqrt(3)*y*a)+4*cos(sqrt(3)/2.0*y*a)*cos(3*x*a/2.0)
    f(x,y) = t*sqrt(3+g(1.0/sqrt(3)*y,1.0/sqrt(3)*(-x)))
    set sample 200
    set isosamples 200
    set xrange [-2*pi/a:2*pi/a]
    set yrange [-2*pi/a:2*pi/a]
    set yrange [-sqrt(3)*pi/a:sqrt(3)*pi/a]
    set pm3d at s
    set ztics 2
    set cbtics 2
    #set zlabel 'Energy' rotate by 90
    #set xlabel 'k_x'
    #set ylabel 'k_y'
    unset zlabel
    unset xlabel
    unset ylabel

    unset xtics
    unset ytics
    unset ztics
    unset colorbox
    unset border

    set hidden3d
    unset key

    set terminal pngcairo transparent size 5*800, 3.5*800
    #set terminal x11
    set size ratio -1
    set output 'graphene.png'
    set pm3d corners2color shade 0.4, 0, 45

    splot -f(x,y) w pm3d, f(x,y) w pm3d

     
  • Douglas

    Douglas - 2012-04-22

    New patch with "set pm3d corners2color shade STRENGTH, LAT, LONG"

     
  • Douglas

    Douglas - 2012-04-22

    Graphene band structure: Old version of pm3d

     
  • Douglas

    Douglas - 2012-04-22

    Graphene band structure: New version with shading and proper identification of underbelly

     
  • Douglas

    Douglas - 2012-04-23

    One last detail: I've learned how to simulate the Mathematica-style normal-shading (see http://reference.wolfram.com/mathematica/howto/ChangeTheLightingOfPlots.html for details). This works perfectly for the spheres I've been testing, but any other surface has the following issue: the normal vector must be "normalized" according to the ranges of each axis. Otherwise the result is dependent upon the ranges being equal and will change if you multiply by a prefactor. The prefactor only affects the labels on the z-axis, but not the overall shape, but in the current implementation, it also affects the normal shading. How do I obtain the ranges for each axis in pm3d.c?

     
  • Ethan Merritt

    Ethan Merritt - 2012-04-23

    axis_array[AXIS].data_min
    axis_array[AXIS].data_max

    I appreciate your enthusiasm for this project, but I still would like to see a real-world example of using this coloring scheme to convey salient information. The png files you have attached to this tracker strike me as being essentially the same as the existing color-by-z default mode (but uglier). Just because the Wolfram programs use this scheme does not really prove anything; for one thing they don't (so far as I know) have an hidden-surface removal option equivalent to gnuplot's hidden3d mode.

     
  • Douglas

    Douglas - 2012-04-30

    Some more updates. The new patch file now uses "normal" to perform Mathematica-style shading, while the "shade" version has the following optional settings:

    set pm3d corners2color shade STRENGTH AMBIENT SPECULAR-STRENGTH SHINYNESS LONGITUDE LATTITUDE

    The idea now is that shade simulates a real light source and reflective object with adjustable specularity. This makes it vastly easier to understand the physical 3d shape of these plots, while the adjustment parameters I settled on I think are intuitive. For instance, the "shinyness" algorithm is normalized so there is the same amount of specular reflected light at all shininess settings, determined solely by SPECULAR-STRENGTH.

    Also, the "normal" style is now an exact replica of the Mathematica style, which gets rid of those hideous greens. The Mathematica style essentially is a stylized normal-vector shading which I find extraordinarily pleasing.

    I have attached two images of both styles using the graphene band structure.

    Ethan -- I now have several individuals who are asking for this patch, so I'll keep developing it as long as I find important details to address. We find it extremely useful that a scripted graphing program like gnuplot can now give us professional results that we were otherwise having to run to Mathematica or Matlab to obtain, so for us this is very valuable.

    One question: how can we get this shading to work with "set pm3d depthorder"?

     
  • Douglas

    Douglas - 2012-04-30

    New version of patch which adds specularity and Mathematica-style shading

     
  • Douglas

    Douglas - 2012-04-30

    Graphene band structure with mathematica-style shading

     
  • Douglas

    Douglas - 2012-04-30

    Improved shading algorithm is more realistic and includes specularity

     
  • Douglas

    Douglas - 2012-05-02

    I've also attached the figure in my thesis for which I wrote this patch. By adding the shading and specularity on top of the normal palette, it's now obvious how the shapes of the two band structures differ from each other while also relating them to the 2d "set view map" graphs next to them.

     
  • Douglas

    Douglas - 2012-05-02

    Figure from thesis, showing comparison between two band structures in pm3d shading AND the flat image

     
  • Douglas

    Douglas - 2012-05-04

    I've also found an interesting application from matplotlib for plotting relief images: http://matplotlib.sourceforge.net/examples/pylab_examples/shading_example.html

    With the new patch, not only can we do this ("set view map"), but our solution is infinitely more flexible!

     
  • Anonymous

    Anonymous - 2012-05-15

    This looks great. I'm excited to use this in my graduate research. Thanks for making this available!

     

    Last edit: Anonymous 2014-09-06
  • Douglas

    Douglas - 2012-05-23

    Updated patch includes option "fixedshade"

     
  • Douglas

    Douglas - 2012-05-23

    The default behavior in matplotlib and matlab is to set the angle of the incoming "light" fixed against the axes, which is useful for reproducibility; while Mathematica tends to set the light according to the view window, not the axes. I have added an option "fixedshade" which fixes the light in relation to the axes; "shade" acts as before, by fixing the light in relation to the view window. In other words, "fixedshade" doesn't change the shading when you rotate the view, but "shade" does.

     
    • arturodonjuan

      arturodonjuan - 2016-04-15

      Is there any further documentation on this that I can get a hold of (e.g. more examples)? When I try to use the "shade" option, the top of the surface comes out completely black and the underbelly completely white, whereas everything works fine with the default "normal" setting.

      By the way, thanks for the amazing patch!

       

      Last edit: arturodonjuan 2016-04-15
      • Ethan Merritt

        Ethan Merritt - 2016-04-15

        The gnuplot development version (5.1) now supports a lighting model based on surface normals.
        See
        http://gnuplot.sourceforge.net/demo_cvs/pm3d_lighting.html

         
  • Lukas Jirkovsky

    Lukas Jirkovsky - 2014-03-17

    Douglas, thank you for this patch, it looks amazing. I've updated it to apply cleanly on gnuplot 4.6.5

    I found the shading very useful, because I needed to visualize various curves along a 3D surface. The surface was required for illustration purposes and I couldn't use line rendering as it was making the plot too messy and pm3d didn't provide a good sense of depth.

    Devs: is there a chance that this or something similar will be accepted?

     
<< < 1 2 3 > >> (Page 2 of 3)

Log in to post a comment.