/
legends.ncl
322 lines (284 loc) · 9.64 KB
/
legends.ncl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
; #############################################################################
; ROUTINES FOR CREATING LEGENDS AS SEPARATE PLOTS
; #############################################################################
; Please consider using or extending existing routines before adding new ones.
; Check the header of each routine for documentation.
;
; Contents:
;
; function legend_lines
; function legend_markers
;
; #############################################################################
load "$diag_scripts/../interface_scripts/constants.ncl"
load "$diag_scripts/../interface_scripts/logging.ncl"
; #############################################################################
undef("legend_lines")
function legend_lines(wks_in[1],
source,
varname[1]:string)
;
; Arguments
; wks_in: workstation ("graphic" object or default will be used)
; source: data to be plotted, either passed directly or via netCDF file
; legend styles and strings are passed as attributes data@
; varname: variable name, needed for netCDF files with multiple variables
;
; The following attributes of the input data are evaluated:
; source@diag_script: name(s) of the calling script(s)
; source@colors: vector of colors
; source@thicks: vector of line thicknesses
; source@dashes: vector of dash styles
; source@annots: vector of label strings
; source@nrow: number of rows (optional)
; source@ncol: number of columns (optional)
;
; Return value
; wks: workstation with legend
;
; Description
; Creates an extra plot with a legend, specified by labels and line styles.
; It will be saved in the outfile directory and returned as a workstation
;
; Modification history
; 20140326-gottschaldt_klaus-dirk: written based on code by
; winterstein_franziska
;
local data, defaults, var, diag_script, colors, annots, dashes, thicks
begin
funcname = "legend_lines"
scriptname = "diag_scripts/shared/plot/legends.ncl"
enter_msg(scriptname, funcname)
; Get data, either directly or via netCDF file
if (typeof(source) .eq. "string") then
; Function in ~/interface_scripts/auxiliary.ncl
data = ncdf_read(source, varname) ; can deal with defaults
else
data = source
copy_VarMeta(source, data)
end if
; Retrieve basic metadata from data
defaults = (/"default", "dummy", "dummy_for_var", "Default", "Dummy"/)
if(any(varname .eq. defaults)) then ; Use default
var = att2var(data, "var") ; interface_scripts/auxiliary.ncl
else ; Use explicitely given name
var = varname
end if
diag_script = att2var(data, "diag_script")
colors = att2var(data, "colors")
thicks = att2var(data, "thicks")
dashes = att2var(data, "dashes")
annots = att2var(data, "annots")
; Attributes for polyline and text
gsres = True
txres = True
copy_VarAtt_sel(data, txres, (/"tx"/))
; txres@txAngleF = -90.0
; Determine dimensions of plot
dim_LAB = dimsizes(annots)
; Columns & rows
if (isatt(data, "ncol") .and. isatt(data, "nrow")) then
col = data@ncol
row = data@nrow
else if (isatt(data, "ncol") .and. .not.isatt(data, "nrow")) then
col = data@ncol
row = dim_LAB / col
if (row.lt.tofloat(dim_LAB) / tofloat(col)) then
row = row + 1
end if
else if(.not. isatt(data, "ncol") .and. isatt(data, "nrow")) then
row = data@nrow
col = dim_LAB / row
if (col.lt.tofloat(dim_LAB) / tofloat(row)) then
col = col + 1
end if
else ; default
col = 3
row = dim_LAB / col
if (row.lt.tofloat(dim_LAB) / tofloat(col)) then
row = row + 1
end if
end if
end if
end if
; Determines anchor points of lines and labels
xleg = new((/col/), float)
yleg = new((/row/), float)
xleg(0) = 1. / (1.1 * col)
do j = 1, col - 1
xleg(j) = xleg(j - 1) + 1. / col
end do
yleg(0) = 1 - 1. / (2 * row)
do j = 1, row - 1
yleg(j) = yleg(j - 1) - 1. / row
end do
; Attributes of workstation
; file_type = True
; file_type@wkOrientation = "portrait"
; file_type@wkPaperHeightF = 4. * col
; file_type@wkPaperWidthF = 1.5 * row
; file_type = "default"
; absFontH = 0.3 ; absolute Font Height
; txres@txFontHeightF = absFontH / file_type@wkPaperWidthF
; txres@txFontHeightF = absFontH / (1.5 * row)
; txres@txFontAspectF = 12. * (1. / row)
; Check if a valid wks has been provided, otherwise invoke default
; attributes of file_type will be used by get_wks
wks_legend = get_wks(wks_in, diag_script, var+"_legend")
; Loop over rows (nrow) and columns (col) to draw lines and text
i = 0
do r = 0, row - 1
do c = 0, col - 1
if i.lt.(dim_LAB) then
; Set line color and other optional styles
gsres@gsLineColor = colors(i)
gsres@gsLineDashPattern = dashes(i)
gsres@gsLineThicknessF = thicks(i)
; Draw line and add text
gsn_polyline_ndc(wks_legend, (/yleg(r), yleg(r)/), \
(/xleg(c), xleg(c) - 0.05/), gsres)
gsn_text_ndc(wks_legend, annots(i), yleg(r), \
xleg(c)-0.17, txres)
i = i + 1
end if
end do
end do
; Advance frame
frame(wks_legend)
; Outfile name
; if (isatt(wks_legend, "fullname")) then
; plot@outfile = wks_legend@fullname
; else
; plot@outfile = wks_legend@name
; log_debug("warning: wks@fullname missing, consider to use " +\
; "get_wks to open wks")
; end if
; log_info(" Wrote " + plot@outfile)
log_info(" Wrote " + wks_legend@fullname)
leave_msg(scriptname, funcname)
return(wks_legend)
end
; #############################################################################
undef("legend_markers")
function legend_markers(wks_in[1],
source,
varname[1]:string)
;
; Arguments
; wks: workstation ("graphic" object or default will be used)
; source: data to be plotted, either passed directly or via netCDF file
; legend styles and strings are passed as attributes data@
; varname: variable name, needed for netCDF files with multiple variables
;
; The following attributes of the input data are evaluated:
; source@diag_script: name(s) of the calling script(s)
; source@colors: vector of colors
; source@annots: vector of label strings
; source@nrow: number of rows (optional)
; source@ncol: number of columns (optional)
;
; Return value
; wks: workstation with legend
;
; Description
; Creates an extra plot with a legend, specified by labels and line styles.
; It will be saved in the outfile directory and returned as a workstation
;
; Modification history
; 20140326-wenzel_sabrina: written based on legend_lines.
;
local data, defaults, var, diag_script, colors, annots, dashes, thicks
begin
funcname = "legend_markers"
scriptname = "diag_scripts/shared/plot/legends.ncl"
enter_msg(scriptname, funcname)
; Get data, either directly or via netCDF file
if (typeof(source) .eq. "string") then
; Function in ~/interface_scripts/auxiliary.ncl
data = ncdf_read(source, varname) ; can deal with defaults
else
data = source
copy_VarMeta(source, data)
end if
; Retrieve basic metadata from data
defaults = (/"default", "dummy", "dummy_for_var", "Default", "Dummy"/)
if(any(varname .eq. defaults)) then
var = att2var(data, "var")
else
var = varname
end if
diag_script = att2var(data, "diag_script")
colors = att2var(data, "colors")
thicks = att2var(data, "thicks")
annots = att2var(data, "annots")
; Attributes for polyline and text
gsres = True
txres = True
copy_VarAtt_sel(data, txres, (/"tx"/))
; txres@txAngleF = -90.0
; Determine dimensions of plot
dim_LAB = dimsizes(annots)
; Columns & rows
if (isatt(data, "ncol") .and. isatt(data, "nrow")) then
col = data@ncol
row = data@nrow
else if (isatt(data, "ncol") .and. .not.isatt(data, "nrow")) then
col = data@ncol
row = dim_LAB / col
if (row.lt.tofloat(dim_LAB) / tofloat(col)) then
row = row + 1
end if
else if(.not. isatt(data, "ncol") .and. isatt(data, "nrow")) then
row = data@nrow
col = dim_LAB / row
if (col.lt.tofloat(dim_LAB) / tofloat(row)) then
col = col + 1
end if
else ; default
col = 3
row = dim_LAB / col
if (row.lt.tofloat(dim_LAB) / tofloat(col)) then
row = row + 1
end if
end if
end if
end if
; Determines anchor points of lines and labels
xleg = new((/col/), float)
yleg = new((/row/), float)
xleg(0) = 1. / (1.1 * col)
do j = 1, col - 1
xleg(j) = xleg(j - 1) + 1. / col
end do
yleg(0) = 1 - 1. / (2 * row)
do j = 1, row - 1
yleg(j) = yleg(j - 1) - 1. / row
end do
; Check if a valid wks has been provided, otherwise invoke default
; attributes of file_type will be used by get_wks
wks_legend = get_wks(wks_in, diag_script, var+"_legend")
; Loop over rows (nrow) and columns (col) to draw lines and text
i = 0
do r = 0, row - 1
do c = 0, col - 1
if i.lt.(dim_LAB) then
; Set marker color and other optional styles
gsres@gsMarkerColor = colors(i)
gsres@gsMarkerIndex = thicks(i)
gsres@gsMarkerSizeF = 0.015
gsres@gsMarkerThicknessF = 2
; Draw marker and add text
gsn_polymarker_ndc(wks_legend, (/yleg(r), yleg(r)/), \
(/xleg(c), xleg(c) - 0.05/), gsres)
gsn_text_ndc(wks_legend, annots(i), yleg(r), \
xleg(c)-0.17, txres)
i = i + 1
end if
end do
end do
; Advance frame
frame(wks_legend)
; log_info(" Wrote " + wks_legend@fullname)
leave_msg(scriptname, funcname)
return(wks_legend)
end