Is the following a bug?
gnuplot> splot x*y [looks fine] gnuplot> set lmargin screen 0.4 gnuplot> set tmargin screen 0.6 gnuplot> splot x*y [the lmargin looks to be screen 0.4, while the rmargin seems to have moved screen 0.2 off the plot, similarly the tmargin looks to be screen 0.4 from top, while the bmargin seems to have moved screen 0.2 off the plot] gnuplot> set rmargin screen 0.6 gnuplot> set bmargin screen 0.4 gnuplot> splot x*y [ok, looks as expected again]
Basically, gnuplot seems to be giving precedent to plot width than automatic margin selection.
The 2D case works as I'd expect, keeping the opposite margins on screen:
And neither is the following what I would expect even for all margins being set:
The plot 3D plot is expanded beyond the edges of the screen.
My observation is that the following code is important to the margin/scaling computation:
I placed some print code around the line for which if I comment it out, the 3d plot behavior seems to behave as I expected. I'm using as a test example:
The case of lmargin=0, rmargin=1, bmargin=0, tmargin=1 also seems to look improved after commenting out the yscaler and xscalar re-computations.
I didn't investigate much beyond that because there seems to be the use of global variables here which takes me a bit of extra time to follow. Should it be && instead of || in the screen test? Is there something down stream that now treats that 4/7 scaling different than it once did for the screen/screen margin case? I don't know.
Starting in version 5 the 'set margin' commands try to act on "set view map" 3D plots approximately as they do for normal 2D plots. The result is not a perfect match but closer than it used to be.
True 3D plots (general case of "set view") don't have margins per se so it is not clear what "set margin" is expected to do, exactly. As you point out, they currently have the effect of shifting the plot around on the page rather than changing its size. Remember that unlike 2D plots, 3D plots have a separate pair of scale factors: the 3rd and 4th parameters to "set view".
I experimented with the scale control last night. But I figured so long as it is set at 1, the result should look reasonbly good.
OK, it sounds like this is trying to make the best of a bad situation. So if I were to take what I have that looks too big in a non-map view and rotate that so it becomes map view...yeah, I see now that does happen.
I take it that no matter the initial chosen view, gnuplot doesn't want to change the 3D scale or center point with rotation because that would appear odd when the mouse is used to move the view. Furthermore, this magic number stuff is something to get a reasonable good guess at sizing for 3D plots in general.
I can see that, but at the same time, it really would be beneficial in some cases to have finer control over sizing. In order to do that, it seems that gnuplot should pick a unity scale factor, run the hidden line code and compute the extent of the view. Then take the {}margin target and compute some afine translations for drawing so that the plot comes out with balanced margins. That would get rid of the magic number, correct?
I really have no idea where that magic number 4/7 came from.
The 3D code already works just as you describe. The plot contents are rescaled into a unit cube, and then the view + scale parameters are applied to that unit cube.
Isn't a scale factor sufficient "fine control" of the size?
Last edit: Ethan Merritt 2016-06-01
7/4 is an approximation of sqrt(3.0), which is the factor between a cube's shortest and longest projected extent (edge versus diagonal). That means the graph cube has to be scaled down by 4/7 relative to the square on-screen region to make sure its projected view fits into that window at arbitrary rotations.
Well, as far as scaling, I don't know if setting the scale is fine enough control because it is a bit on the obscure side and perhaps arbitrary just exactly what "scale" represents. I mean, there are three dimensions, so three scalings of an axes, yet there are only two scale factors when maneuvering a 3D plot,
Now, the above may be a complete specification for those three scalings, but not orthogonal in the sense that "scale" controls both the x and y axis, while scale_z is the third. Those, in combination with the view angle are adequate to specify axis projection (i.e., what direction is the x y or z axis pointing in relation to the view?) and units along that axis projection. But the initial relationship between x and y scaling is what's missing. For example, do
and rotate so that the orthographic plane is visible. That aspect ratio is not 1 to 1 so something in gnuplot chose that. Was it inherent in first drawing the plot then looking at it's extent? I'm sure there is a logical reason behind it.
Specifying the margins is something more understandable to the user, I think. It's helpful for laying out things for visual balance, say, when doing a multiplot. Of course, it is just another way of specifying the eventual x, y, z-axis unit scaling with a different set of parameterized values. And it sort of obviates the 4/7 technique. For example, if gnuplot were to have {}margin set, the view angle and axis range would then dictate the x, y, z-axis projections and scalings. From there, things are fixed for mouse rotation (does mouse rotation use "plot" or "replot"?) and rotating might end up with the view going outside of user-specified bounds... that is, until another "plot" is done when the view and {}margin are set. Anyway, what I'm describing is a bit like the new 5-version behavior but rather than the map view being used it's the overall extend being used...and if someone set {}margin along with "set view 0,0" or "set view map" it would behave the same as current version 5.x does.
I just submitted a change to Octave to address an issue it had with rotating something that was set to orthographic view, i.e., "set view map". They apparently wanted that map view, but they also wanted the ability to rotate with the mouse after having set that. So, I changed it to something like:
which works, but as soon as a mouse rotation is done gnuplot goes back to the 4/7 rule and the size of the plot jumps suddenly. That's not awful behavior, but not smooth either.
I'm looking at an alternate drawing toolkit for Octave and it does this some sort of thing by changing the scaling along with rotation so that it always occupies the same visual extent. That actually isn't too bad of behavior. So maybe that is how the {}margin-set mode could be. Just always make the plot extend occupy the same 2D space rather than use it to compute map view and fix scaling from there on. If no {}margin is set, then go back to the 4/7 scaling mode.
BTW, just to note, if I do
z extends pretty far off screen (which is explained in the documentation), but interestingly the center mouse button does nothing to the z-axis even though the z-axis scaling value keeps changing. If in "equal xyz" mode, isn't z_scale tied to the scale? Shouldn't both left-right and up-down mouse movement be able to control scale and z_scale simultaneously in that mode?
Actually, why not simplify things and just add a new rotate mode control option? For example,
In fixedextent mode gnuplot does what I described above, i.e., changes the scale so that the plot fills the whole space specified by {}margin. In fixedscale (default) mode, the 1/sqrt(3) rule is used with a fixed scale.
With that, there is no special behavior dependent up {}margin or odd distinguishing of plot vs. replot with mouse movement. Users will get the max-sized map view by consequence of fixedextent mode. That is, "set view map" would be the same as "set view 0,0 fixedextent". (This brings up another issue I'll put in a different post.)
I sort of like that, as it doesn't sound like too much of a change to make that work from what is already present in the code.
The other thing I just remembered is the annotation of the perpendicular axis in an orthographic view. The current difference between "set view map" and simply rotating a 3D splot so that it has angle 0,0 (or some other orthographic view) is that the former does not plot the tick mark annotation--all those characters just end up on one another and are illegible. I wonder if we can leave off that perpendicular (to view) axis tick mark and annotation whenever the view is set orthogonal in some way, e.g., "set view 0,0" would leave off the blob of characters in the lower left corner.
Sounds reasonable.
That's a one-liner:
Ticket moved from /p/gnuplot/bugs/1802/
Can't be converted: