Skip to content

Commit

Permalink
restore pre-5.2 logscale tic increment interpretation
Browse files Browse the repository at this point in the history
  • Loading branch information
sfeam committed Sep 23, 2017
1 parent 425ad08 commit fe9c29c
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 27 deletions.
12 changes: 12 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
2017-09-23 Ethan A Merritt <[email protected]>

* src/axis.c (gen_tics) docs/gnuplot.doc demo/nonlinear6.dem:
Revise documentation of "set xtics" to include examples and description
of logscale keyword. Restore pre-5.2 behaviour that for log-scaled axes
the increment in "set xtics {start,} incr {,end}" is interpreted as a
multiplicative factor rather than a constant interval. However this is
only true if the "logscale" attribute is set for axis tics.
New demo nonlinear6.dem exercises this feature and also shows the use of
"set tics rangelimit" with log-scaled axes.
Bug #1971

2017-09-21 Ethan A Merritt <[email protected]>

* term/cairo.trm (cairotrm_reset): Still trying to get this right.
Expand Down
3 changes: 2 additions & 1 deletion demo/all.dem
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# $Id: all.dem,v 1.79 2017-01-11 04:13:58 sfeam Exp $
# $Id: all.dem,v 1.80 2017-09-23 04:48:03 sfeam Exp $
#
# Executes all demos (OK, MOST demos) in this directory.
# This serves as a series of unit tests for non-interactive capabilities.
Expand Down Expand Up @@ -390,6 +390,7 @@ load "nonlinear2.dem"
load "nonlinear3.dem"
load "nonlinear4.dem"
load "nonlinear5.dem"
load "nonlinear6.dem"
reset

print "********************** file transparent.dem *********************"
Expand Down
21 changes: 21 additions & 0 deletions demo/nonlinear6.dem
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#
# Logscale axis tic placement has always been problematic.
# This demo exercises both automatic tic placement and
# user-specified tic series.
#
set log y
set log y2
set tics nomirror
set border 11
set key center title "rangelimited tics" samplen -1

set xrange [1:15000]

set ytics 10 logscale rangelimit
set y2tics auto rangelimit

plot sample [x=2:14000] x axes x1y1 title "set ytics 10", \
[x=2:14000] x axes x1y2 title "set y2tics auto"

pause -1 "<cr> to continue"
reset
81 changes: 61 additions & 20 deletions docs/gnuplot.doc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
C RCS $Id: gnuplot.doc,v 1.1109 2017-09-19 18:38:01 sfeam Exp $
C RCS $Id: gnuplot.doc,v 1.1110 2017-09-23 04:48:04 sfeam Exp $
C
C Copyright (C) 1986 - 1993, 1998, 1999, 2000, 2001, 2004 Thomas Williams, Colin Kelley et al.
C
Expand Down Expand Up @@ -13910,6 +13910,7 @@ Ffigure_multiple_keys
| ({"<label>"} <pos> {<level>} {,{"<label>"}...) }
{format "formatstring"} {font "name{,<size>}"} {{no}enhanced}
{ numeric | timedate | geographic }
{{no}logscale}
{ rangelimited }
{ textcolor <colorspec> }
unset xtics
Expand Down Expand Up @@ -13963,10 +13964,32 @@ Ffigure_multiple_keys
being displayed; otherwise it has no effect. Any previously specified tic
frequency or position {and labels} are retained.

Positions of the tics are calculated automatically by default or if the
`autofreq` option is given; otherwise they may be specified in either of
two forms:
Tic positions are calculated automatically by default or if the `autofreq`
option is given.

A series of tic positions can be specified by giving either a tic interval
alone, or a start point, interval, and end point (see `xtics series`).

Individual tic positions can be specified individually by providing an
eplicit list of positions, where each position may have an associated
text label. See `xtics list`.

However they are specified, tics will only be plotted when in range.

Format (or omission) of the tic labels is controlled by `set format`, unless
the explicit text of a label is included in the `set xtics ("<label>")` form.

Minor (unlabeled) tics can be added automatically by the `set mxtics`
command, or at explicit positions by the `set xtics ("" <pos> 1, ...)` form.

The appearance of the tics (line style, line width etc.) is determined by the
border line (see `set border`), even if the tics are drawn at the axes.
4 xtics series
?set xtics series
?xtics series
Syntax
set xtics <incr>
set xtics <start>, <incr>, <end>
The implicit <start>, <incr>, <end> form specifies that a series of tics will
be plotted on the axis between the values <start> and <end> with an increment
of <incr>. If <end> is not given, it is assumed to be infinity. The
Expand Down Expand Up @@ -14003,13 +14026,22 @@ Ffigure_multiple_keys
Make tics at 1, 100, 1e4, 1e6, 1e8.
set logscale x; set xtics 1,100,1e8

The explicit ("<label>" <pos> <level>, ...) form allows arbitrary tic
4 xtics list
?set xtics list
?set xtics add
?xtics list
?xtics add
Syntax
set xtics {add} ("label1" <pos1> <level1>, "label2" <pos2> <level2>, ...)

The explicit ("label" <pos> <level>, ...) form allows arbitrary tic
positions or non-numeric tic labels. In this form, the tics do not
need to be listed in numerical order. Each tic has a
position, optionally with a label. Note that the label is
a string enclosed by quotes. It may be a constant string, such as
"hello", may contain formatting information for converting the
position into its label, such as "%3f clients", or may be empty, "".
position, optionally with a label.

The label is a string enclosed by quotes or a string-valued expression.
It may contain formatting information for converting the position into its
label, such as "%3f clients", or it may be the empty string "".
See `set format` for more information. If no string is given, the
default label (numerical) is used.

Expand Down Expand Up @@ -14042,17 +14074,6 @@ Ffigure_multiple_keys

This will automatically generate tic marks every 0.5 along x, but will
also add an explicit labeled tic mark at pi.

However they are specified, tics will only be plotted when in range.

Format (or omission) of the tic labels is controlled by `set format`, unless
the explicit text of a label is included in the `set xtics ("<label>")` form.

Minor (unlabeled) tics can be added automatically by the `set mxtics`
command, or at explicit positions by the `set xtics ("" <pos> 1, ...)` form.

The appearance of the tics (line style, line width etc.) is determined by the
border line (see `set border`), even if the tics are drawn at the axes.
4 xtics timedata
?set xtics timedata
?xtics timedata tics
Expand Down Expand Up @@ -14117,6 +14138,26 @@ Ffigure_multiple_keys
To output degrees/minutes/seconds in a context other than axis tics, such as
placing labels on a map, you can use the relative time format specifiers
%tH %tM %tS for strptime. See `time_specifiers`, `strptime`.
4 xtics logscale
?set xtics logscale
?xtics logscale
=logscale
If the `logscale` attribute is set for a tic series along a log-scaled axis,
the tic interval is interpreted as a multiplicative factor rather than a
constant. For example:
# generate a series of tics at y=20 y=200 y=2000 y=20000
set log y
set ytics 20, 10, 50000 logscale
Note that no tic is placed at y=50000 because it is not in the series 2*10^x.
If the logscale property is disabled, the tic increment will be treated as
an additive constant even for a log-scaled axis. For example:
# generate a series of tics at y=20 y=40 y=60 ... y=200
set log y
set yrange [20:200]
set ytics 20 nologscale
The `logscale` attribute is set automatically by the `set log` command,
so normally you do not need this keyword unless you want to force a
constant tic interval as in the second example above.
4 xtics rangelimited
?set xtics rangelimited
?xtics rangelimited
Expand Down
29 changes: 23 additions & 6 deletions src/axis.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef lint
static char *RCSid() { return RCSid("$Id: axis.c,v 1.245 2017-09-11 03:40:51 sfeam Exp $"); }
static char *RCSid() { return RCSid("$Id: axis.c,v 1.246 2017-09-23 04:48:04 sfeam Exp $"); }
#endif

/* GNUPLOT - axis.c */
Expand Down Expand Up @@ -1106,6 +1106,18 @@ gen_tics(struct axis *this, tic_callback callback)
end = step * ceil(lmax / step);
else
end = def->def.series.end;
if (def->logscaling) {
/* This emulates earlier gnuplot versions in handling
* set log y; set ytics 10
*/
step = eval_link_function(this->linked_to_primary, step);
end = eval_link_function(this->linked_to_primary, end);
start = eval_link_function(this->linked_to_primary, start);
if (!(start > this->linked_to_primary->min))
start = this->linked_to_primary->min;
lmin = this->linked_to_primary->min;
lmax = this->linked_to_primary->max;
}
} else {
start = def->def.series.start;
step = def->def.series.incr;
Expand Down Expand Up @@ -1253,8 +1265,10 @@ gen_tics(struct axis *this, tic_callback callback)
internal = tic;
user = tic;
} else if (nonlinear(this)) {
if (def->type == TIC_COMPUTED)
user = eval_link_function(this->linked_to_primary->linked_to_secondary, tic);
if (def->type == TIC_SERIES && def->logscaling)
user = eval_link_function(this, tic);
else if (def->type == TIC_COMPUTED)
user = eval_link_function(this, tic);
else
user = tic;
internal = tic; /* It isn't really, but this makes the range checks work */
Expand Down Expand Up @@ -1318,7 +1332,9 @@ gen_tics(struct axis *this, tic_callback callback)
}

/* This is where we finally decided to put the tic mark */
if (nonlinear(this) && (def->type == TIC_COMPUTED))
if (nonlinear(this) && (def->type == TIC_SERIES && def->logscaling))
position = user;
else if (nonlinear(this) && (def->type == TIC_COMPUTED))
position = user;
else
position = internal;
Expand Down Expand Up @@ -1351,8 +1367,9 @@ gen_tics(struct axis *this, tic_callback callback)
if (this->tictype == DT_TIMEDATE) {
mtic_user = time_tic_just(this->timelevel - 1, internal + mplace);
mtic_internal = mtic_user;
} else if (nonlinear(this) && (def->type == TIC_COMPUTED)) {
/* FIXME: make up for bad calculation of ministart/ministep/miniend */
} else if ((nonlinear(this) && (def->type == TIC_COMPUTED))
|| (nonlinear(this) && (def->type == TIC_SERIES && def->logscaling))) {
/* Make up for bad calculation of ministart/ministep/miniend */
double this_major = eval_link_function(this, internal);
double next_major = eval_link_function(this, internal+step);
mtic_user = this_major + mplace/miniend * (next_major - this_major);
Expand Down

0 comments on commit fe9c29c

Please sign in to comment.