From: Dima K. <gn...@di...> - 2019-09-18 17:51:07
|
Hi. I'm trying to make a plot that's not working because I'm running into some assumptions gnuplot is making. Help sought. I want to make a 3D plot that contains contours on the xyplane AND ALSO contains other data (points, say) in the xyz space. The contours are rendered on the z=0 plane, so from the plot viewer's perspective this is unrelated to the z axis in the plot. So I want the data on the z axis to be decoupled from the data used to make the contours. Example. I can make contours from a sinusoid: set contour base set cntrparam levels incremental -1,0.1,1 set samples 100,100 set isosamples 100,100 splot [-5:5][-5:5] '++' using 1:2:(sin($1)*cos($2)) with lines nosurface This works great. It generates a 3D plot with the contours rendered on the z=0 plane only. Let's pretend I have other data plotted also, and for whatever reason I also want to set zrange [0:0.5] This breaks the contours! It looks like the zrange limit is applied to the data before generating the contours, which sounds counter-intuitive to me. Any suggestions about how to decouple this? Can we always use zrange [*:*] for the purposes of contour generation? Should we? Thanks |
From: Ethan M. (UW) <me...@uw...> - 2019-09-18 18:52:56
|
On Wednesday, 18 September 2019 10:37:15 Dima Kogan wrote: > Hi. I'm trying to make a plot that's not working because I'm running > into some assumptions gnuplot is making. Help sought. > > I want to make a 3D plot that contains contours on the xyplane AND ALSO > contains other data (points, say) in the xyz space. The contours are > rendered on the z=0 plane, so from the plot viewer's perspective this is > unrelated to the z axis in the plot. So I want the data on the z axis to > be decoupled from the data used to make the contours. Are you saying that you have two sets of data, each with its own range on z? That is a separate problem I will come back to at the end [*]. For now I assume the two data sets are on the same scale. > > Example. I can make contours from a sinusoid: > > set contour base > set cntrparam levels incremental -1,0.1,1 > set samples 100,100 > set isosamples 100,100 > splot [-5:5][-5:5] '++' using 1:2:(sin($1)*cos($2)) with lines nosurface > > This works great. It generates a 3D plot with the contours rendered on > the z=0 plane only. Let's pretend I have other data plotted also, and > for whatever reason I also want to > > set zrange [0:0.5] > > This breaks the contours! It looks like the zrange limit is applied to > the data before generating the contours, which sounds counter-intuitive > to me. The contour plot is generated by contouring the data. If you restrict the data to the subset in a particular range then you get contours of only that subset. > Any suggestions about how to decouple this? Can we always use > zrange [*:*] for the purposes of contour generation? Should we? I do not understand what you are asking for. If you want to contour all the data then autoscaling z is appropriate. If you want to contour a subset of the data then you have two options: 1) restrict the range of the data set zrange [min:max] 2) keep the full range of data but restrict the range of contours set zrange [*:*] set cntrparam levels incremental min, increment, max If you want to superimpose data points outside the min:max range then option 1 will not work but option 2 does work. [*] If the two data sets are not on the same scale then a different approach is needed. Gnuplot does not currently have a separate z2 axis analogous to x2 or y2. You can, however, introduce a scaling function into the plot command: splot $data1 using 1:2:3 with lines nosurface title "contours", \ $data2 using 1:2:(scale($3)) with points nocontour However the commands as shown would leave you with the wrong labels along z. If you apply the scale to the contoured data instead then the z axis labels would be correct but the contour labels would be wrong. Either way you would have to manually correct the values in the labels. Modifying gnuplot to support a z2 axis would be possible, but we'd have to agree on the desired representation. x2 and y2 are drawn on the opposite side of the plot from x1 and y1 respectively. Would z2 be drawn on a separate [new] vertical line from z1? Or would z2 consist only of a second set of z-axis tic labels, presumably in a distinct color? Ethan |
From: Dima K. <gn...@di...> - 2019-09-18 19:26:06
|
Thanks for the comments. Notes inline Ethan Merritt (UW) <me...@uw...> writes: > On Wednesday, 18 September 2019 10:37:15 Dima Kogan wrote: > > Are you saying that you have two sets of data, each with its own range > on z? That is a separate problem I will come back to at the end [*]. > For now I assume the two data sets are on the same scale. Yes, they're different: the z used for the contours is unrelated in what I want plotted on the z. What I'm REALLY trying to do is to visualize a 4D function that maps (x,y,a) -> b. There's no clear "right" way to do this in any plotting tool. I'd like to do this with several stacked contours, at some preset values of a: a0,a1,a2, .... So in each a = a* slice I'd have a 3D function (x,y) -> b. And for each such slice I want to generate a contour on the xy plane, rendering the contour at z = a*. Multiplot is needed for the multiple contours, but that's a whole other issue. As you can see, the contours are generated by looking at the value of b, while the plot shows values of a on the z axis. Any other suggestions for visualizing such 4D functions welcome. > The contour plot is generated by contouring the data. If you restrict > the data to the subset in a particular range then you get contours of > only that subset. Yes. But the expectation was that zrange restricts the visualization, not the data. So the full set of data would be used in the contouring, and the zrange would only control how stuff is drawn. > [*] If the two data sets are not on the same scale then a different > approach is needed. Gnuplot does not currently have a separate z2 > axis analogous to x2 or y2. You can, however, introduce a scaling > function into the plot command: > > splot $data1 using 1:2:3 with lines nosurface title "contours", \ > $data2 using 1:2:(scale($3)) with points nocontour > > However the commands as shown would leave you with the wrong labels > along z. If you apply the scale to the contoured data instead then > the z axis labels would be correct but the contour labels would be > wrong. Either way you would have to manually correct the values in > the labels. > > Modifying gnuplot to support a z2 axis would be possible, but we'd > have to agree on the desired representation. x2 and y2 are drawn > on the opposite side of the plot from x1 and y1 respectively. > Would z2 be drawn on a separate [new] vertical line from z1? > Or would z2 consist only of a second set of z-axis tic labels, > presumably in a distinct color? Hmmm. A separate z2 axis would solve this, and maybe supporting that eventually would be nice, but for THIS particular issue it feels like a workaround. Presumably in the gnuplot guts we have some for of this logic: 1. ingest data 2. throw away all data outside the xrange, yrange, zrange 3. make contours 4. draw Can it be updated to 1. ingest data 2. make contours 3. throw away all data outside the xrange, yrange, zrange 4. draw Or maybe 1. ingest data 1.5. throw away all data outside the xrange, yrange 2. make contours 3. throw away all data outside the zrange 4. draw Here when looking at contours in step 3, we'd use the z of where the contours are drawn, not the data used to generate them. So for contours on the xyplane we'd use the z coordinate of the xyplane. It's very possible that I'm oversimplifying everything here, and that there're lots of details that make such a change impossible. But it feels a lot more like what I (as a user) thinks zrange should do: act on what I see rendered against the z axis. Thanks |
From: Ethan M. (UW) <me...@uw...> - 2019-09-18 21:52:24
|
On Wednesday, 18 September 2019 12:06:09 Dima Kogan wrote: > Thanks for the comments. Notes inline > > Ethan Merritt (UW) <me...@uw...> writes: > > > On Wednesday, 18 September 2019 10:37:15 Dima Kogan wrote: > > > > Are you saying that you have two sets of data, each with its own range > > on z? That is a separate problem I will come back to at the end [*]. > > For now I assume the two data sets are on the same scale. > > Yes, they're different: the z used for the contours is unrelated in what > I want plotted on the z. > > What I'm REALLY trying to do is to visualize a 4D function that maps > (x,y,a) -> b. There's no clear "right" way to do this in any plotting > tool. I'd like to do this with several stacked contours, at some preset > values of a: a0,a1,a2, .... So in each a = a* slice I'd have a 3D > function (x,y) -> b. And for each such slice I want to generate a > contour on the xy plane, rendering the contour at z = a*. Multiplot is > needed for the multiple contours, but that's a whole other issue. As you > can see, the contours are generated by looking at the value of b, while > the plot shows values of a on the z axis. Any other suggestions for > visualizing such 4D functions welcome. That sounds very close to the new voxel-based options in 5.3. One such visualization is the animation in "voxel.dem" The on-line collection has a static image of the end point, but if you run the demo locally you'll see that it steps through the volumne one plane at a time. http://gnuplot.sourceforge.net/demo_5.3/voxel.html Your description sounds like the same thing with contours rather than a heatmap. I would do it by precalculating the contour slices one by one and then either stepping through them or superimposing them. Something like this: set contour set cntrparam levels increment -1, .1, 1 unset surface f1(x,y) = sin(x)*cos(y) f2(x,y) = sin(x+.1)*cos(y-.1) f3(x,y) = sin(x+.2)*cos(y-.2) set table $slice1 splot [-5:5][-5:5] '++' using 1:2:(f1($1,$2)) with lines set table $slice2 splot [-5:5][-5:5] '++' using 1:2:(f2($1,$2)) with lines set table $slice3 splot [-5:5][-5:5] '++' using 1:2:(f3($1,$2)) with lines unset table unset contour set surface splot $slice1 using 1:2:(0.0):3 with lines lc palette, \ $slice2 using 1:2:(0.1):3 with lines lc palette, \ $slice3 using 1:2:(0.2):3 with lines lc palette There's something odd about one of those contours but you get the idea. > > The contour plot is generated by contouring the data. If you restrict > > the data to the subset in a particular range then you get contours of > > only that subset. > > Yes. But the expectation was that zrange restricts the visualization, > not the data. So the full set of data would be used in the contouring, > and the zrange would only control how stuff is drawn. [shrug] I guess it depends on how you think about it. Consider the 9th plot (3rd from the end) in this demo: http://gnuplot.sourceforge.net/demo_5.2/sampling.html Limiting the axis range of each plot controls which data is plotted where, but the overall axis ranges on x y z for the plot as a whole encompass all the pieces. Ethan |