comparison psymap_simple.py @ 2:e6d1e9d6b399 draft

planemo upload for repository https://github.com/NordicESMhub/galaxy-tools/tree/master/tools/psy-maps commit d330adb8ea0000ffb2e1dcc2346fd34409f6618e
author climate
date Thu, 26 Sep 2024 10:32:08 +0000
parents 706666d912d5
children
comparison
equal deleted inserted replaced
1:706666d912d5 2:e6d1e9d6b399
2 # 2 #
3 # 3 #
4 # usage: psymap_simple.py [-h] [--proj PROJ] 4 # usage: psymap_simple.py [-h] [--proj PROJ]
5 # [--cmap CMAP] 5 # [--cmap CMAP]
6 # [--output OUTPUT] 6 # [--output OUTPUT]
7 # [-l]
7 # [-v] 8 # [-v]
8 # input varname 9 # input varname
9 # 10 #
10 # positional arguments: 11 # positional arguments:
11 # input input filename with geographical coordinates (netCDF 12 # input input filename with geographical coordinates (netCDF
12 # format) 13 # format)
13 # varname Specify which variable to plot (case sensitive) 14 # varname Specify which variable to plot (case sensitive)
14 # 15 #
15 # optional arguments: 16 # optional arguments:
16 # -h, --help show this help message and exit 17 # -h, --help show this help message and exit
18 # -l, --logscale log scale the data
17 # --proj PROJ Specify the projection on which we draw 19 # --proj PROJ Specify the projection on which we draw
18 # --cmap CMAP Specify which colormap to use for plotting 20 # --cmap CMAP Specify which colormap to use for plotting
19 # --output OUTPUT output filename to store resulting image (png format) 21 # --output OUTPUT output filename to store resulting image (png format)
20 # --time TIMES time index from the file for multiple plots ("0 1 2 3") 22 # --time TIMES time index from the file for multiple plots ("0 1 2 3")
21 # --nrow NROW number of rows for multiple plot grid 23 # --nrow NROW number of rows for multiple plot grid
24 # --title plot or subplot title 26 # --title plot or subplot title
25 # -v, --verbose switch on verbose mode 27 # -v, --verbose switch on verbose mode
26 # 28 #
27 29
28 import argparse 30 import argparse
31 import math
29 import warnings 32 import warnings
30 from pathlib import Path 33 from pathlib import Path
31 34
32 import matplotlib as mpl 35 import matplotlib as mpl
36 import psyplot.project as psy # noqa: I202,E402
37 import xarray
38
33 mpl.use('Agg') 39 mpl.use('Agg')
34 from matplotlib import pyplot # noqa: I202,E402 40 from matplotlib import pyplot # noqa: I202,E402
35
36 import psyplot.project as psy # noqa: I202,E402
37 from psyplot import rcParams # noqa: I202,E402 41 from psyplot import rcParams # noqa: I202,E402
38 42
39 43
40 class PsyPlot (): 44 class PsyPlot ():
41 def __init__(self, input, proj, varname, cmap, output, verbose=False, 45 def __init__(self, input, varname, output=None, logscale=False, cmap=None,
42 time=[], nrow=1, ncol=1, format="%B %e, %Y", 46 proj=None, verbose=False, time=None, nrow=None, ncol=None,
43 title=""): 47 format=None, title=None):
44 self.input = input 48 self.input = input
45 self.proj = proj
46 self.varname = varname 49 self.varname = varname
47 self.cmap = cmap 50 if proj is None or proj == "":
48 self.time = time 51 self.proj = "cyl"
52 else:
53 self.proj = proj
54 self.cmap = cmap if cmap is not None else "jet"
55 self.time = time if time is not None else []
56 self.ncol = int(ncol) if ncol is not None else int(1)
57 self.nrow = int(nrow) if nrow is not None else int(1)
58
59 # Open dataset
60 ds = xarray.open_dataset(input)[varname]
61 minv = math.log2(ds.data.min())
62 maxv = math.log2(ds.data.max())
63 if title is not None:
64 self.title = title
65 else:
66 self.title = ds.long_name
67 if len(self.title) > 60:
68 self.title = ds.standard_name
69 del ds
70
71 if logscale:
72 # Check that data range is sufficient for log scaling
73 if maxv < (minv * (10.0 ** 2.0)):
74 print("Not possible to log scale, switching to linear scale")
75 self.bounds = None
76 else:
77 self.bounds = ['log', 2]
78 else:
79 self.bounds = None
49 if format is None: 80 if format is None:
50 self.format = "" 81 self.format = ""
51 else: 82 else:
52 self.format = format.replace('X', '%') 83 self.format = "%B %e, %Y"
53 if title is None:
54 self.title = ""
55 else:
56 self.title = title
57 if ncol is None:
58 self.ncol = 1
59 else:
60 self.ncol = int(ncol)
61 if nrow is None:
62 self.nrow = 1
63 else:
64 self.nrow = int(nrow)
65 if output is None: 84 if output is None:
66 self.output = Path(input).stem + '.png' 85 self.output = Path(input).stem + '.png'
67 else: 86 else:
68 self.output = output 87 self.output = output
69 self.verbose = verbose
70 if verbose: 88 if verbose:
71 print("input: ", self.input) 89 print("input: ", self.input)
72 print("proj: ", self.proj) 90 print("proj: ", self.proj)
73 print("varname: ", self.varname) 91 print("varname: ", self.varname)
74 print("cmap: ", self.cmap) 92 print("cmap: ", self.cmap)
75 print("time: ", self.time) 93 print("time: ", self.time)
76 print("ncol: ", self.ncol) 94 print("ncol: ", self.ncol)
77 print("nrow: ", self.nrow) 95 print("nrow: ", self.nrow)
78 print("title: ", self.title) 96 print("title: ", self.title)
79 print("date format: ", self.format) 97 print("date format: ", self.format)
98 print("logscale: ", self.bounds)
80 print("output: ", self.output) 99 print("output: ", self.output)
81 100
82 def plot(self): 101 def plot(self):
102 clabel = '{desc}'
83 if self.title and self.format: 103 if self.title and self.format:
84 title = self.title + "\n" + self.format 104 title = self.title + "\n" + self.format
85 elif not self.title and self.format: 105 elif not self.title and self.format:
86 title = self.format 106 title = self.format
87 elif self.title and not self.format: 107 elif self.title and not self.format:
88 title = self.title 108 title = self.title
89 else: 109 clabel = self.title
90 title = '%(long_name)s' 110
91 111 # Plot with chosen options
92 if self.cmap is None and self.proj is None: 112 if self.bounds is None:
93 psy.plot.mapplot(self.input, name=self.varname,
94 title=title,
95 clabel='{desc}')
96 elif self.proj is None or not self.proj:
97 psy.plot.mapplot(self.input, name=self.varname,
98 title=title,
99 cmap=self.cmap, clabel='{desc}')
100 elif self.cmap is None or not self.cmap:
101 psy.plot.mapplot(self.input, name=self.varname,
102 projection=self.proj,
103 title=title,
104 clabel='{desc}')
105 else:
106 psy.plot.mapplot(self.input, name=self.varname, 113 psy.plot.mapplot(self.input, name=self.varname,
107 cmap=self.cmap, 114 cmap=self.cmap,
108 projection=self.proj, 115 projection=self.proj,
109 title=title, 116 title=title,
110 clabel='{desc}') 117 clabel=clabel)
118 else:
119 psy.plot.mapplot(self.input, name=self.varname,
120 cmap=self.cmap, bounds=self.bounds,
121 projection=self.proj,
122 title=title,
123 clabel=clabel)
111 124
112 pyplot.savefig(self.output) 125 pyplot.savefig(self.output)
113 126
114 def multiple_plot(self): 127 def multiple_plot(self):
115 if not self.format: 128 if not self.format:
117 130
118 if not self.title: 131 if not self.title:
119 title = self.format 132 title = self.format
120 else: 133 else:
121 title = self.title + "\n" + self.format 134 title = self.title + "\n" + self.format
135
122 mpl.rcParams['figure.figsize'] = [20, 8] 136 mpl.rcParams['figure.figsize'] = [20, 8]
123 mpl.rcParams.update({'font.size': 8}) 137 mpl.rcParams.update({'font.size': 8})
124 rcParams.update({'plotter.maps.grid_labelsize': 8.0}) 138 rcParams.update({'plotter.maps.grid_labelsize': 8.0})
125 if self.cmap is None and self.proj is None: 139
126 m = psy.plot.mapplot(self.input, name=self.varname, 140 # Plot using options
127 title=title, 141 if self.bounds is None:
128 ax=(self.nrow, self.ncol),
129 time=self.time, sort=['time'],
130 clabel='{desc}')
131 m.share(keys='bounds')
132 elif self.proj is None or not self.proj:
133 m = psy.plot.mapplot(self.input, name=self.varname,
134 title=title,
135 ax=(self.nrow, self.ncol),
136 time=self.time, sort=['time'],
137 cmap=self.cmap, clabel='{desc}')
138 m.share(keys='bounds')
139 elif self.cmap is None or not self.cmap:
140 m = psy.plot.mapplot(self.input, name=self.varname,
141 projection=self.proj,
142 ax=(self.nrow, self.ncol),
143 time=self.time, sort=['time'],
144 title=title,
145 clabel='{desc}')
146 m.share(keys='bounds')
147 else:
148 m = psy.plot.mapplot(self.input, name=self.varname, 142 m = psy.plot.mapplot(self.input, name=self.varname,
149 cmap=self.cmap, 143 cmap=self.cmap,
150 projection=self.proj, 144 projection=self.proj,
151 ax=(self.nrow, self.ncol), 145 ax=(self.nrow, self.ncol),
152 time=self.time, sort=['time'], 146 time=self.time, sort=['time'],
153 title=title, 147 title=title,
154 clabel='{desc}') 148 clabel='{desc}')
155 m.share(keys='bounds') 149 else:
150 m = psy.plot.mapplot(self.input, name=self.varname,
151 cmap=self.cmap, bounds=self.bounds,
152 projection=self.proj,
153 ax=(self.nrow, self.ncol),
154 time=self.time, sort=['time'],
155 title=title,
156 clabel='{desc}')
157
158 m.share(keys='bounds')
156 159
157 pyplot.savefig(self.output) 160 pyplot.savefig(self.output)
158 161
159 162
160 def psymap_plot(input, proj, varname, cmap, output, verbose, time, 163 def psymap_plot(input, proj, varname, logscale, cmap, output, verbose, time,
161 nrow, ncol, format, title): 164 nrow, ncol, format, title):
162 """Generate plot from input filename""" 165 """Generate plot from input filename"""
163 166
164 p = PsyPlot(input, proj, varname, cmap, output, verbose, time, 167 p = PsyPlot(input, varname, output, logscale, cmap, proj, verbose, time,
165 nrow, ncol, format, title) 168 nrow, ncol, format, title)
169
166 if len(time) == 0: 170 if len(time) == 0:
167 p.plot() 171 p.plot()
168 else: 172 else:
169 p.multiple_plot() 173 p.multiple_plot()
170 174
184 parser.add_argument( 188 parser.add_argument(
185 'varname', 189 'varname',
186 help='Specify which variable to plot (case sensitive)' 190 help='Specify which variable to plot (case sensitive)'
187 ) 191 )
188 parser.add_argument( 192 parser.add_argument(
193 "--logscale",
194 help='Plot the log scaled data'
195 )
196 parser.add_argument(
189 '--cmap', 197 '--cmap',
190 help='Specify which colormap to use for plotting' 198 help='Specify which colormap to use for plotting'
191 ) 199 )
192 parser.add_argument( 200 parser.add_argument(
193 '--output', 201 '--output',
221 229
222 if args.time is None: 230 if args.time is None:
223 time = [] 231 time = []
224 else: 232 else:
225 time = list(map(int, args.time.split(","))) 233 time = list(map(int, args.time.split(",")))
226 psymap_plot(args.input, args.proj, args.varname, args.cmap, 234
235 if args.logscale == 'no':
236 logscale = False
237 else:
238 logscale = True
239
240 psymap_plot(args.input, args.proj, args.varname, logscale, args.cmap,
227 args.output, args.verbose, time, 241 args.output, args.verbose, time,
228 args.nrow, args.ncol, args.format, args.title) 242 args.nrow, args.ncol, args.format, args.title)