[GRASS-dev] d.legend: labels on smooth legends
Ivan Shmakov
ivan at theory.asu.ru
Tue Jan 8 03:44:11 EST 2008
One more problem with d.legend is that it labels both ends of
the scale (and places intermediate labels at equal distances.)
However, it may be more appropriate not to label one or both
ends.
Consider, e. g., raster having the range -13 .. 123. With
d.legend placing, say, 7 labels they would be: -13, 10, 32, 55,
78, 100, 123. While it may be preferred to have 0, 20, 40, 60,
80, 100, 120 labelled instead (like Gnuplot would put the tics
on the axes by default.)
Apparently, the current labelling algorithm is implemented with
the following:
$ nl -ba display/d.legend/main.c
605 for(k = 0; k < steps; k++) {
606 if(!fp) {
607 if(!flip)
608 tcell = min_ind + k * (double)(max_ind - min_ind)/(steps-1);
609 else
610 tcell = max_ind - k * (double)(max_ind - min_ind)/(steps-1);
...
627 }
628 else { /* ie FP map */
629 if(hide_catnum)
630 buff[0] = 0; /* no text */
631 else {
632 if(!flip)
633 val = dmin + k * (dmax - dmin)/(steps-1);
634 else
635 val = dmax - k * (dmax - dmin)/(steps-1);
...
639 }
...
689 } /*for*/
$
Any chances of making the Gnuplot-like algorithm available as an
option?
FWIW, here is the script I've used as a workaround to generate
Gnuplot-like legends. (It depends on `gnuplot', `fig2dev' and
`convert' being in "$PATH".)
#!/bin/bash
### r.colorbox.sh --- Color boxes for GRASS rasters -*- sh -*-
### Configuration
: ${CONVERT:=convert}
: ${D_LEGEND:=d.legend}
: ${D_MON:=d.mon}
: ${FIG2DEV:=fig2dev}
: ${GNUPLOT:=gnuplot}
: ${R_INFO:=r.info}
## FIXME: allow command line options here?
out_sfx=.eps
### Globals
name="$(basename "$0")"
verbose=yes
### Auxiliary functions
make_color_scale () {
## FIXME: d.mon should allow /dev/stdout as a target file
local png="$(mktemp -t "${name}-$$.png")"
local map="$1" out="$2"
local prev_mon=$(${D_MON} -p \
| sed -e '/.*:[[:blank:]]*/!d; s///')
GRASS_WIDTH=$[256 + 3] GRASS_HEIGHT=$[5 + 3] GRASS_TRUECOLOR=TRUE \
GRASS_PNGFILE="$png" ${D_MON} start=PNG \
&& ${D_LEGEND} -vcs map="$map" at=0,100,0,100 \
&& ${D_MON} stop=PNG \
|| return 1
[ -n "$prev_mon" ] && ${D_MON} select="$prev_mon"
## FIXME: a hack
sleep .1s
${CONVERT} -crop 256x1+2+4 "$png" "$out"
rm -f -- "$png"
}
make_gp () {
local min="$1" max="$2"
cat <<EOF
set terminal postscript eps
set size 1, .15
set xtics nomirror
unset ytics
unset key
set xrange [${min} : ${max}]
set yrange [2 : 3]
plot 1
EOF
}
make_fig () {
local frame="$1"
local grayscale="$2"
cat <<EOF
#FIG 3.2 Produced by xfig version 3.2.5-alpha5
Portrait
Flush left
Metric
A4
100.00
Single
-2
1200 2
2 5 0 1 0 -1 50 -1 20 0.000 0 0 -1 0 0 5
0 ${frame}
225 225 5940 225 5940 812 225 812 225 225
2 5 0 1 0 -1 60 -1 -1 0.000 0 0 -1 0 0 5
0 ${grayscale}
405 338 5760 338 5760 585 405 585 405 338
EOF
}
raster_min_max () {
local raster="$1"
## NB: a hack
$R_INFO -r map="$raster" \
| sed -e 's/.*=//' \
| sort -g \
| tr \\n ' '
echo
}
### Code:
if [ "$#" -lt 2 ]; then
echo "Usage: $name PREFIX [RASTER]..." >&2
exit 1
fi
prefix="$1"
shift
## FIXME: improve error handling
set -e
for raster in "$@"; do
out="${prefix}${raster}${out_sfx}"
test "$verbose" = yes \
&& echo "* Producing ${out}..." >&2
read min max < <(raster_min_max "$raster")
if [ "$min" = nan -o "$max" = nan ]; then
echo "${name}: ${raster}: Invalid data range; ignored"
continue
fi
frameeps="$(mktemp -t "$name".eps-XXXXXX)"
fig="$(mktemp -t "$name".fig-XXXXXX)"
color_scale="$(mktemp -t "$name".ppm-XXXXXX)"
make_color_scale "$raster" \
"ppm:${color_scale}"
make_gp "$min" "$max" \
| $GNUPLOT > "$frameeps"
make_fig "$frameeps" "$color_scale" \
| $FIG2DEV -L eps \
> "$out"
rm -f -- "$color_scale" "$frameeps" "$fig"
done
### r.colorbox.sh ends here
[...]
More information about the grass-dev
mailing list