I wish I had a simple example to illustrate the following problem, but I can't seem to find one. The app I'm seeing this problem with is a big bunch of commands and data. There are actually a couple problems which I will summarize at the end.
Basically, I'm using multiaxes that utilize data and when zooming too closely one of the axes has no data within it's borders. So, it produces the following error message:
line 2824: Can't plot with an empty x2 range!
But after the other axes plots just fine, the mouse is stuck showing a coordinate and from there doesn't behave as it should. Rather, if I click the left mouse button, gnuplot attempts to plot again and displays the message above once again.
Here's the hunk of code where I think the problem arises:
/* check that xmin -> xmax is not too small */
axis_checked_extend_empty_range(FIRST_X_AXIS, "x range is invalid");
if (axis_array[SECOND_X_AXIS].linked_to_primary) {
clone_linked_axes(axis_array[SECOND_X_AXIS].linked_to_primary, &axis_array[SECOND_X_AXIS]);
/* FIXME: This obsoletes OUTRANGE/INRANGE for secondary axis data */
} else if (uses_axis[SECOND_X_AXIS] & USES_AXIS_FOR_DATA) {
/* check that x2min -> x2max is not too small */
axis_checked_extend_empty_range(SECOND_X_AXIS, "x2 range is invalid");
} else if (axis_array[SECOND_X_AXIS].autoscale) {
The error happens in axis.c function axis_checked_extend_empty_range:
if (dmax - dmin == 0.0) {
/* empty range */
if (this_axis->autoscale) {
/* range came from autoscaling ==> widen it */
double widen = (dmax == 0.0) ?
FIXUP_RANGE__WIDEN_ZERO_ABS
: FIXUP_RANGE__WIDEN_NONZERO_REL * fabs(dmax);
if (!(axis == FIRST_Z_AXIS && !mesg)) /* set view map */
fprintf(stderr, "Warning: empty %s range [%g:%g], ",
axis_name(axis), dmin, dmax);
/* HBB 20010525: correctly handle single-ended
* autoscaling, too: */
if (this_axis->autoscale & AUTOSCALE_MIN)
this_axis->min -= widen;
if (this_axis->autoscale & AUTOSCALE_MAX)
this_axis->max += widen;
if (!(axis == FIRST_Z_AXIS && !mesg)) /* set view map */
fprintf(stderr, "adjusting to [%g:%g]\n",
this_axis->min, this_axis->max);
} else {
/* user has explicitly set the range (to something empty)
==> we're in trouble */
int_error(NO_CARET, "Can't plot with an empty %s range!",
axis_name(axis));
}
and I'm using no autoscale...the second alternative above. It must be that at the point of this error, the mouse hasn't yet had its icon changed back to the normal pointer.
So, that's one error. The second error concerns why gnuplot can't figure out the proper scaling regardless of whether there is any data within the border as a result of zooming when I've used "set x2range"?
So that's
1) Mouse state stuck at coordinate when the "int_error" path is followed during a plot.
2) Gnuplot should be able to figure out the scaling easy enough even though no data is within the border.
Regarding #2, perhaps I'm not understanding the way this works, as I see in the code this
if (axis_array[SECOND_X_AXIS].linked_to_primary) {
case. I'll look through the documentation about whether I can do that in this case, because all I really want is to have the same data but the axis scale represented differently.
The x11 terminal mouse cursor reverts back to the normal cross (even though Qt terminal doesn't). So, the restoration takes place before the plot:
However, the x11 terminal also gets in a state for which conventional mouse behavior is lost. I think the issue there is that Qt doesn't restore the mouse cursor immediately because of it's event loop construct.
Anyway, the way I see it, if a command line generates a proper plot, gnuplot should be set up that no matter what it does to replot via the mouse it can't cause an error. Either the error should be disallowed or perhaps the data needs to be set up correctly.
In static mouse.c is this routine apply_zoom(). It seems to makes sense. The mouse code figures out what the new zoom boundary should be, and in apply_zoom is:
So, zooming always has no autoscale... so why the error about no value x2 range? (And what is quandry in the comment of the code above?)
Here's an example of another warning that does appear upon issuing the command, but after doing a zoom, the pressing 'u' the message "warning: x axis range undefined or overflow" appears:
Again, as I see it, mouse actions shouldn't cause any warnings/errors regarding plot range.
dunno about the rest of it, but this bit seems dubious:
"Mouse state stuck at coordinate when the "int_error" path is followed during a plot"
You're using the x11 terminal, right? So the mousing is controlled by a separate process. int_error() in the main process cannot affect it. Heck you can kill the main process with "killall gnuplot" and the x11 window will still do mousing. So I think you may have misdiagnosed this.
Both Qt and x11 get stuck in the coordinate state. I'm not referring to the mouse cursor getting stuck at one position, as in freeze. I'm referring to the appearance of the mouse cursor and its subsequent behavior. The cursor goes from a cross-hair state to a coordinate state with a box outlining where the new border should be. It's when doing the second mouse botton click to select the second corner then gnuplot int_error when drawing results in Qt mouse cursor still having coordinates displayed next to the icon.
Anyway, it is sort of a moot issue because there shouldn't be any int_error as a result of zooming or panning. I've explored that in one of the posts just before this one (chronologically...may be lower in the list visibly). Having made a small change so there are no int_error, it has uncovered more bugs as to the presensce and formatting of time data in the x2 tic annotation.
OK, I think I'm getting closer now. First, I don't necessarily agree with this conditional test:
Why should that be a problem? FIRST_X_AXIS doesn't behave that way. (Maybe it did at one time and nobody thought to change the behavior for SECOND_X_AXIS and SECOND_Y_AXIS.) For example:
works fine.
But it turns out that via the mouse, the above code isn't run. Instead, it goes through
then
and that route doesn't seem to have the same sorts of logic tests:
This refresh_bounds() routine is used only one other place I see, which is the cumulative average family of plots.
Anyway, when the mouse is setting the x1,y1,x2,y2 boundaries for the plot, there is no reason to call refresh_bounds(). How should we go about addressing this? Something like:
or something like the diff file I'm attaching? The patch I attached works for me, but whether it breaks the cumulative average family of features, I don't know. Beyond that, with the attached patch--though the plot for both axes now works fine--when I zoom the plot or move the mouse wheel the time tic annotation disappears on the x2 axis. Also, there's a big space between the time tic annotation and top border crowding out the title. There's too many issues here to make this functional, so I think I'm going to drop the dual-scale plot idea.
I've managed my original goal by plotting a function 1/0 on one of the axes. So, you can mark this one "won't fix", if you think the zooming code with data is too fragile. I turns out that the tic annotation behavior isn't related to the int_error, so I'm going to post a different bug report for that.