Dear Allin,
thanks again for your examples. These are nice illustrations and I
wasn't aware of some of the capabilities of gnuplot.
In order to handle different time frequencies more flexible, I thought
it could of an advantage to exploit the $obsdate series which actually
contains all necessary information. In the attached example, I transform
the int values of $obsdate into an array of strings and use these string
values (separating year, month, day) as xtics in a flexible manner. This
also allows the user to define different options on how to present
dates, as you will see below.
Btw, there is a weird thing for large matrices with my obs. as used
below. In order to generate a proper graph one needs to write:
<hansl>
printf "set style fill solid border -2\n" # "border -1" doesn't
work for
long data!
</hansl>
Best,
Artur
<hansl>
set verbose off
function void stackplot1AT (matrix mat,
series obsdate[null] "$obsdate",
int dateform[0:4:1] "Output format of xtics [see asdate()]",
int nstep[1::4] "Print only n-th value on xaxis",
string fname,
int height[240::480], int width[240::640]))
if exists(obsdate)
# re-define obsdate as array of strings
strings S = s2a(obsdate)
strings Date = asdate(S,dateform)
endif
tmpfile = sprintf("%s/stackedbar.gp", $dotdir)
outfile @tmpfile --write
printf "set encoding utf8\n"
printf "set terminal pngcairo size %d,%d enhanced font
'Verdana,12'\n", width,height
printf "set nokey\n"
printf "set style data histogram \n"
printf "set style histogram rowstacked\n"
printf "set style fill solid border -2\n" # "border -1"
doesn't
work for long data!
printf "set style fill solid 0.35\n"
printf "set xtics border in scale 0,0 nomirror rotate by -45
autojustify\n"
# write data block
printf "$data <<EOF\n"
loop i=1..rows(mat) -q
loop j=1..cols(mat) -q
printf "%g ", mat[i,j]
endloop
if exists(obsdate)
if i % nstep == 0
printf "%s", Date[i]
else
printf "-1"
endif
endif
printf "\n"
endloop
printf "EOF\n"
# write plot specification
printf "plot \\\n"
loop j=1..cols(mat) -q
if j == 1 && exists(obsdate)
k = cols(mat) + 1
printf "$data using 1:xtic($%d < 0. ? \"\" :
stringcolumn(%d))", k, k
else
printf "$data using %d", j
endif
printf(j == cols(mat) ? "\n" : ", \\\n")
endloop
outfile --close
gnuplot --input="@tmpfile" --output=@fname
end function
function strings s2a (series y)
# put numerical values into an array of strings
n = nobs(y)
strings S=array(n)
loop i=1..n -q
sprintf s "%d", y[i]
S[i] = "@s"
endloop
return S
end function
function strings asdate (strings S "stringified $obsdate array",
int dform[0:4:1] "0=Y/M/D, 1=y/M/D, 2=Y/M, 3=y/M, 4=M/D")
n=nelem(S)
strings D = array(n)
loop i=1..n -q
string s = S[i]
string y = substr(s,1,4) # year
string m = substr(s,5,6) # month
string d = substr(s,7,8) # day
if dform==0
D[i] = sprintf("%s/%s/%s",y,m,d)
elif dform==1
y = substr(y,3,4)
D[i] = sprintf("%s/%s/%s",y,m,d)
elif dform==2
D[i] = sprintf("%s/%s",y,m)
elif dform==3
y = substr(y,3,4)
D[i] = sprintf("%s/%s",y,m)
elif dform==4
D[i] = sprintf("%s/%s",m,d)
endif
endloop
return D
end function
# Example using daily data
open djclose -q
rename djclose dj
series date = $obsdate
series dj2 = dj
matrix M = {dj}~{dj2}
dateform = 4 # option for xtics format
xskip = 150
stackplot1AT(M, date, 4, xskip, "display", 320,720)
</hansl>