Previous changeset 1:706666d912d5 (2019-10-05) Next changeset 3:988212a7466a (2024-10-01) |
Commit message:
planemo upload for repository https://github.com/NordicESMhub/galaxy-tools/tree/master/tools/psy-maps commit d330adb8ea0000ffb2e1dcc2346fd34409f6618e |
modified:
psy-maps.xml psymap_simple.py test-data/TS.f2000.T31T31.control.cam.h0.0014-12.png test-data/TS.f2000.T31T31.control.cam.h0.0014-12_ortho.png |
added:
test-data/ESACCI-OC-L3S-CHLOR_A-20220601-RESIZED-fv6.0.nc test-data/ESACCI-OC-L3S-CHLOR_A-20220601-RESIZED-fv6.0.png |
b |
diff -r 706666d912d5 -r e6d1e9d6b399 psy-maps.xml --- a/psy-maps.xml Sat Oct 05 17:11:18 2019 -0400 +++ b/psy-maps.xml Thu Sep 26 10:32:08 2024 +0000 |
[ |
@@ -1,16 +1,23 @@ -<tool id="psy_maps" name="map plot" version="1.2.1"> +<tool id="psy_maps" name="map plot" version="1.3.0" profile="23.0"> <description>gridded (lat/lon) netCDF data</description> + <edam_topics> + <edam_topic>topic_3855</edam_topic> + <edam_topic>topic_3318</edam_topic> + </edam_topics> + <edam_operations> + <edam_operation>operation_0573</edam_operation> + </edam_operations> <requirements> <requirement type="package" version="3">python</requirement> - <requirement type="package" version="1.2.1">psyplot</requirement> - <requirement type="package" version="1.2.0">psy-maps</requirement> - <requirement type="package" version="1.2.0">psy-reg</requirement> - <requirement type="package" version="1.4.2">netcdf4</requirement> + <requirement type="package" version="1.4.3">psyplot</requirement> + <requirement type="package" version="1.4.2">psy-maps</requirement> + <requirement type="package" version="1.4.0">psy-reg</requirement> + <requirement type="package" version="1.6.5">netcdf4</requirement> </requirements> <command detect_errors="exit_code"><![CDATA[ - HOME=`pwd` && python3 '$__tool_directory__/psymap_simple.py' '$ifilename' '$variable' + --logscale '$adv.logscale' --proj '$adv.projection' --cmap '$adv.colormap' --output image.png @@ -44,6 +51,10 @@ <param name="title" type="text" value="" label="plot title" /> </when> </conditional> + <param name="logscale" type="select" label="log scale the data"> + <option value="yes">yes</option> + <option value="no" selected="true">no</option> + </param> <param name="projection" type="select"> <option value="" selected="true">PlateCarree</option> <option value="robin">Robinson</option> @@ -155,6 +166,14 @@ <param name="colormap" value="RdBu_r" /> <output name="ofilename" ftype="png" file="TS.f2000.T31T31.control.cam.h0.0014-12_ortho.png" compare="sim_size" delta="500"/> </test> + <test> + <param name="ifilename" value="ESACCI-OC-L3S-CHLOR_A-20220601-RESIZED-fv6.0.nc" /> + <param name="variable" value="chlor_a" /> + <param name="projection" value="" /> + <param name="colormap" value="jet" /> + <param name="logscale" value="yes" /> + <output name="ofilename" ftype="png" file="ESACCI-OC-L3S-CHLOR_A-20220601-RESIZED-fv6.0.png" compare="sim_size" delta="1500"/> + </test> </tests> <help><![CDATA[ @@ -167,15 +186,17 @@ .. class:: infomark The wrappers aims at providing the same functionality as ``psyplot.plot.mapplot`` but it has some limitations. - The input file must be in netCDF format and must contain 2D arrays with geographical coordinatates - (latitudes, longitudes) given in degrees. - TODO: Fill in help. + The input file must be in netCDF format and must contain 2D arrays with geographical coordinatates + (latitudes, longitudes) given in degrees. + The code may fail when the data is significantly different from what has been tested. **What it does** ---------------- This tools creates an image (png format) corresponding to the visualization on a geographical map of a variable extracted from a -netCDF file (input file). By default, the projection is ``PlateCarree`` and colormap is ``jet``. These settings can be changed in *Advanced settings*. +netCDF file (input file). +By default, the projection is ``PlateCarree`` and colormap is ``jet``. +These settings can be changed in *Advanced settings* alongside an option to log scale the plot. **Usage** @@ -183,21 +204,22 @@ :: usage: psymap_simple.py [-h] [--proj PROJ] [--cmap CMAP] [--output OUTPUT] [--time TIME] - [--format FORMAT] [--title TITLE] [--ncol NCOL] [--nrow NROW] [-v] input varname + [--format FORMAT] [--title TITLE] [--ncol NCOL] [--nrow NROW] [-l] [-v] input varname Positional arguments: ~~~~~~~~~~~~~~~~~~~~~ - **input**: input filename with geographical coordinates (netCDF format) -- **varname**: Specify which variable to plot (case sensitive) +- **varname**: specify which variable to plot (case sensitive) Optional arguments: ~~~~~~~~~~~~~~~~~~~~~ -h, --help show this help message and exit - --proj PROJ Specify the projection on which we draw - --cmap CMAP Specify which colormap to use for plotting + -l, --logscale log scale the data + --proj PROJ specify the projection on which we draw + --cmap CMAP specify which colormap to use for plotting --output OUTPUT output filename to store resulting image (png format) -v, --verbose switch on verbose mode --time TIME list of times to plot for multiple plots @@ -211,5 +233,6 @@ ]]></help> <citations> + <citation type="doi">10.21105/joss.00363</citation> </citations> </tool> |
b |
diff -r 706666d912d5 -r e6d1e9d6b399 psymap_simple.py --- a/psymap_simple.py Sat Oct 05 17:11:18 2019 -0400 +++ b/psymap_simple.py Thu Sep 26 10:32:08 2024 +0000 |
[ |
b'@@ -4,6 +4,7 @@\n # usage: psymap_simple.py [-h] [--proj PROJ]\n # [--cmap CMAP]\n # [--output OUTPUT]\n+# [-l]\n # [-v]\n # input varname\n #\n@@ -14,6 +15,7 @@\n #\n # optional arguments:\n # -h, --help show this help message and exit\n+# -l, --logscale log scale the data\n # --proj PROJ Specify the projection on which we draw\n # --cmap CMAP Specify which colormap to use for plotting\n # --output OUTPUT output filename to store resulting image (png format)\n@@ -26,47 +28,63 @@\n #\n \n import argparse\n+import math\n import warnings\n from pathlib import Path\n \n import matplotlib as mpl\n+import psyplot.project as psy # noqa: I202,E402\n+import xarray\n+\n mpl.use(\'Agg\')\n from matplotlib import pyplot # noqa: I202,E402\n-\n-import psyplot.project as psy # noqa: I202,E402\n from psyplot import rcParams # noqa: I202,E402\n \n \n class PsyPlot ():\n- def __init__(self, input, proj, varname, cmap, output, verbose=False,\n- time=[], nrow=1, ncol=1, format="%B %e, %Y",\n- title=""):\n+ def __init__(self, input, varname, output=None, logscale=False, cmap=None,\n+ proj=None, verbose=False, time=None, nrow=None, ncol=None,\n+ format=None, title=None):\n self.input = input\n- self.proj = proj\n self.varname = varname\n- self.cmap = cmap\n- self.time = time\n+ if proj is None or proj == "":\n+ self.proj = "cyl"\n+ else:\n+ self.proj = proj\n+ self.cmap = cmap if cmap is not None else "jet"\n+ self.time = time if time is not None else []\n+ self.ncol = int(ncol) if ncol is not None else int(1)\n+ self.nrow = int(nrow) if nrow is not None else int(1)\n+\n+ # Open dataset\n+ ds = xarray.open_dataset(input)[varname]\n+ minv = math.log2(ds.data.min())\n+ maxv = math.log2(ds.data.max())\n+ if title is not None:\n+ self.title = title\n+ else:\n+ self.title = ds.long_name\n+ if len(self.title) > 60:\n+ self.title = ds.standard_name\n+ del ds\n+\n+ if logscale:\n+ # Check that data range is sufficient for log scaling\n+ if maxv < (minv * (10.0 ** 2.0)):\n+ print("Not possible to log scale, switching to linear scale")\n+ self.bounds = None\n+ else:\n+ self.bounds = [\'log\', 2]\n+ else:\n+ self.bounds = None\n if format is None:\n self.format = ""\n else:\n- self.format = format.replace(\'X\', \'%\')\n- if title is None:\n- self.title = ""\n- else:\n- self.title = title\n- if ncol is None:\n- self.ncol = 1\n- else:\n- self.ncol = int(ncol)\n- if nrow is None:\n- self.nrow = 1\n- else:\n- self.nrow = int(nrow)\n+ self.format = "%B %e, %Y"\n if output is None:\n self.output = Path(input).stem + \'.png\'\n else:\n self.output = output\n- self.verbose = verbose\n if verbose:\n print("input: ", self.input)\n print("proj: ", self.proj)\n@@ -77,37 +95,32 @@\n print("nrow: ", self.nrow)\n print("title: ", self.title)\n print("date format: ", self.format)\n+ print("logscale: ", self.bounds)\n print("output: ", self.output)\n \n def plot(self):\n+ clabel = \'{desc}\'\n if self.title and self.format:\n title = self.title + "\\n" + self.format\n elif not self.title and self.format:\n title = self.format\n elif self.title and not self.format:\n title = self.title\n- else:\n- title = \'%(long_name)s\'\n+ clabel = self.title\n \n- if self.cmap is None and s'..b' psy.plot.mapplot(self.input, name=self.varname,\n+ cmap=self.cmap, bounds=self.bounds,\n+ projection=self.proj,\n+ title=title,\n+ clabel=clabel)\n \n pyplot.savefig(self.output)\n \n@@ -119,32 +132,13 @@\n title = self.format\n else:\n title = self.title + "\\n" + self.format\n+\n mpl.rcParams[\'figure.figsize\'] = [20, 8]\n mpl.rcParams.update({\'font.size\': 8})\n rcParams.update({\'plotter.maps.grid_labelsize\': 8.0})\n- if self.cmap is None and self.proj is None:\n- m = psy.plot.mapplot(self.input, name=self.varname,\n- title=title,\n- ax=(self.nrow, self.ncol),\n- time=self.time, sort=[\'time\'],\n- clabel=\'{desc}\')\n- m.share(keys=\'bounds\')\n- elif self.proj is None or not self.proj:\n- m = psy.plot.mapplot(self.input, name=self.varname,\n- title=title,\n- ax=(self.nrow, self.ncol),\n- time=self.time, sort=[\'time\'],\n- cmap=self.cmap, clabel=\'{desc}\')\n- m.share(keys=\'bounds\')\n- elif self.cmap is None or not self.cmap:\n- m = psy.plot.mapplot(self.input, name=self.varname,\n- projection=self.proj,\n- ax=(self.nrow, self.ncol),\n- time=self.time, sort=[\'time\'],\n- title=title,\n- clabel=\'{desc}\')\n- m.share(keys=\'bounds\')\n- else:\n+\n+ # Plot using options\n+ if self.bounds is None:\n m = psy.plot.mapplot(self.input, name=self.varname,\n cmap=self.cmap,\n projection=self.proj,\n@@ -152,17 +146,27 @@\n time=self.time, sort=[\'time\'],\n title=title,\n clabel=\'{desc}\')\n- m.share(keys=\'bounds\')\n+ else:\n+ m = psy.plot.mapplot(self.input, name=self.varname,\n+ cmap=self.cmap, bounds=self.bounds,\n+ projection=self.proj,\n+ ax=(self.nrow, self.ncol),\n+ time=self.time, sort=[\'time\'],\n+ title=title,\n+ clabel=\'{desc}\')\n+\n+ m.share(keys=\'bounds\')\n \n pyplot.savefig(self.output)\n \n \n-def psymap_plot(input, proj, varname, cmap, output, verbose, time,\n+def psymap_plot(input, proj, varname, logscale, cmap, output, verbose, time,\n nrow, ncol, format, title):\n """Generate plot from input filename"""\n \n- p = PsyPlot(input, proj, varname, cmap, output, verbose, time,\n+ p = PsyPlot(input, varname, output, logscale, cmap, proj, verbose, time,\n nrow, ncol, format, title)\n+\n if len(time) == 0:\n p.plot()\n else:\n@@ -186,6 +190,10 @@\n help=\'Specify which variable to plot (case sensitive)\'\n )\n parser.add_argument(\n+ "--logscale",\n+ help=\'Plot the log scaled data\'\n+ )\n+ parser.add_argument(\n \'--cmap\',\n help=\'Specify which colormap to use for plotting\'\n )\n@@ -223,6 +231,12 @@\n time = []\n else:\n time = list(map(int, args.time.split(",")))\n- psymap_plot(args.input, args.proj, args.varname, args.cmap,\n+\n+ if args.logscale == \'no\':\n+ logscale = False\n+ else:\n+ logscale = True\n+\n+ psymap_plot(args.input, args.proj, args.varname, logscale, args.cmap,\n args.output, args.verbose, time,\n args.nrow, args.ncol, args.format, args.title)\n' |
b |
diff -r 706666d912d5 -r e6d1e9d6b399 test-data/ESACCI-OC-L3S-CHLOR_A-20220601-RESIZED-fv6.0.nc |
b |
Binary file test-data/ESACCI-OC-L3S-CHLOR_A-20220601-RESIZED-fv6.0.nc has changed |
b |
diff -r 706666d912d5 -r e6d1e9d6b399 test-data/ESACCI-OC-L3S-CHLOR_A-20220601-RESIZED-fv6.0.png |
b |
Binary file test-data/ESACCI-OC-L3S-CHLOR_A-20220601-RESIZED-fv6.0.png has changed |
b |
diff -r 706666d912d5 -r e6d1e9d6b399 test-data/TS.f2000.T31T31.control.cam.h0.0014-12.png |
b |
Binary file test-data/TS.f2000.T31T31.control.cam.h0.0014-12.png has changed |
b |
diff -r 706666d912d5 -r e6d1e9d6b399 test-data/TS.f2000.T31T31.control.cam.h0.0014-12_ortho.png |
b |
Binary file test-data/TS.f2000.T31T31.control.cam.h0.0014-12_ortho.png has changed |