From 2f24148eaf4d2cdd0ec39f37014d753f2dbcb5cc Mon Sep 17 00:00:00 2001 From: Fabien Maussion Date: Sun, 11 Feb 2024 14:27:15 +0000 Subject: [PATCH] fix docs --- .gitignore | 1 + ci/requirements-py310-all.yml | 1 - ci/requirements-py311-min.yml | 1 - ci/requirements-py311-xr.yml | 1 - ci/requirements-py312-all.yml | 1 - docs/conf.py | 47 +++++++++++++++++------------------ docs/examples.rst | 16 ++++++------ docs/faq.rst | 4 +-- docs/gis.rst | 2 +- docs/installing.rst | 5 ++-- docs/plotting.rst | 6 ++--- docs/wrf.rst | 4 +-- salem/gis.py | 9 ++----- salem/graphics.py | 15 ++++++----- salem/tests/__init__.py | 5 ++-- salem/utils.py | 10 ++++---- setup.cfg | 1 - 17 files changed, 59 insertions(+), 70 deletions(-) diff --git a/.gitignore b/.gitignore index 5d4d4c8..998a561 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ *.py[cod] __pycache__ +.vscode # PyCharm stuffs .idea/ diff --git a/ci/requirements-py310-all.yml b/ci/requirements-py310-all.yml index e57a998..4792bc5 100644 --- a/ci/requirements-py310-all.yml +++ b/ci/requirements-py310-all.yml @@ -3,7 +3,6 @@ channels: - conda-forge dependencies: - python=3.10 - - six - numpy - scipy - pyproj diff --git a/ci/requirements-py311-min.yml b/ci/requirements-py311-min.yml index 9232777..1a55a21 100644 --- a/ci/requirements-py311-min.yml +++ b/ci/requirements-py311-min.yml @@ -3,7 +3,6 @@ channels: - conda-forge dependencies: - python=3.11 - - six - numpy - scipy - pyproj diff --git a/ci/requirements-py311-xr.yml b/ci/requirements-py311-xr.yml index 95b8be5..02fa7fe 100644 --- a/ci/requirements-py311-xr.yml +++ b/ci/requirements-py311-xr.yml @@ -3,7 +3,6 @@ channels: - conda-forge dependencies: - python=3.11 - - six - numpy - scipy - pyproj diff --git a/ci/requirements-py312-all.yml b/ci/requirements-py312-all.yml index dddab56..cb700e0 100644 --- a/ci/requirements-py312-all.yml +++ b/ci/requirements-py312-all.yml @@ -3,7 +3,6 @@ channels: - conda-forge dependencies: - python=3.12 - - six - numpy - scipy - pyproj diff --git a/docs/conf.py b/docs/conf.py index 595df30..a355ebb 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -100,7 +100,7 @@ # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' +# needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom @@ -119,8 +119,8 @@ 'sphinx_gallery.gen_gallery', ] -extlinks = {'issue': ('https://github.com/fmaussion/salem/issues/%s', 'GH'), - 'pull': ('https://github.com/fmaussion/salem/pull/%s', 'PR'), +extlinks = {'issue': ('https://github.com/fmaussion/salem/issues/%s', 'GH%s'), + 'pull': ('https://github.com/fmaussion/salem/pull/%s', 'PR%s'), } sphinx_gallery_conf = { @@ -147,7 +147,7 @@ source_suffix = '.rst' # The encoding of source files. -#source_encoding = 'utf-8-sig' +# source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' @@ -162,7 +162,7 @@ # built documents. # # The short X.Y version. -version = salem.version.short_version +version = salem.__version__.split('+')[0] # The full version, including alpha/beta/rc tags. release = salem.__version__ @@ -175,9 +175,9 @@ # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: -#today = '' +# today = '' # Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' +# today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. @@ -185,14 +185,14 @@ # The reST default role (used for this markup: `text`) to use for all # documents. -#default_role = None +# default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True +# add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). -#add_module_names = True +# add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. @@ -205,7 +205,7 @@ #modindex_common_prefix = [] # If true, keep warnings as "system message" paragraphs in the built documents. -#keep_warnings = False +# keep_warnings = False # If true, `todo` and `todoList` produce output, else they produce nothing. # todo_include_todos = True @@ -337,29 +337,28 @@ # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, 'salem.tex', 'salem Documentation', - 'salem Developers', 'manual'), + (master_doc, 'salem.tex', 'salem Documentation', 'salem Developers', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. -#latex_logo = None +# latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. -#latex_use_parts = False +# latex_use_parts = False # If true, show page references after internal links. -#latex_show_pagerefs = False +# latex_show_pagerefs = False # If true, show URL addresses after external links. -#latex_show_urls = False +# latex_show_urls = False # Documents to append as an appendix to all manuals. -#latex_appendices = [] +# latex_appendices = [] # If false, no module index is generated. -#latex_domain_indices = True +# latex_domain_indices = True # -- Options for manual page output --------------------------------------- @@ -379,7 +378,7 @@ # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, -# dir menu entry, description, category) +# dir menu entry, description, category) texinfo_documents = [ (master_doc, 'salem', 'salem Documentation', author, 'salem', 'Geoscientific data analysis and map projections.', @@ -387,16 +386,16 @@ ] # Documents to append as an appendix to all manuals. -#texinfo_appendices = [] +# texinfo_appendices = [] # If false, no module index is generated. -#texinfo_domain_indices = True +# texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' +# texinfo_show_urls = 'footnote' # If true, do not generate a @detailmenu in the "Top" node's menu. -#texinfo_no_detailmenu = False +# texinfo_no_detailmenu = False # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = { diff --git a/docs/examples.rst b/docs/examples.rst index f810844..1e2ff71 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -23,7 +23,7 @@ Let's take a time slice of the variable ``T2`` for a start: t2 = ds.T2.isel(Time=2) @savefig plot_wrf_t2.png width=80% - t2.salem.quick_map() + t2.salem.quick_map(); Although we are on a Lambert Conformal projection, it's possible to subset the file using longitudes and latitudes: @@ -33,7 +33,7 @@ the file using longitudes and latitudes: t2_sub = t2.salem.subset(corners=((77., 20.), (97., 35.)), crs=salem.wgs84) @savefig plot_wrf_t2_corner_sub.png width=80% - t2_sub.salem.quick_map() + t2_sub.salem.quick_map(); It's also possible to use geometries or shapefiles to subset your data: @@ -45,7 +45,7 @@ It's also possible to use geometries or shapefiles to subset your data: t2_sub = t2_sub.salem.subset(shape=shdf, margin=2) # add 2 grid points @savefig plot_wrf_t2_country_sub.png width=80% - t2_sub.salem.quick_map() + t2_sub.salem.quick_map(); Based on the same principle, one can mask out the useless grid points: @@ -54,7 +54,7 @@ Based on the same principle, one can mask out the useless grid points: t2_roi = t2_sub.salem.roi(shape=shdf) @savefig plot_wrf_t2_roi.png width=80% - t2_roi.salem.quick_map() + t2_roi.salem.quick_map(); Plotting @@ -72,7 +72,7 @@ and more: smap.set_text(91.2, 29.7, 'Lhasa', fontsize=17) @savefig plot_wrf_t2_topo.png width=80% - smap.visualize() + smap.visualize(); Maps are persistent, which is useful when you have many plots to do. Plotting further data on them is possible, as long @@ -86,7 +86,7 @@ Celsius so we have to set it explicitly): smap.set_data(ds.T2.isel(Time=1)-273.15, crs=ds.salem.grid) @savefig plot_wrf_t2_transform.png width=80% - smap.visualize(title='2m temp - large domain', cbar_title='C') + smap.visualize(title='2m temp - large domain', cbar_title='C'); Reprojecting data @@ -100,7 +100,7 @@ Salem can also transform data from one grid to another: t2_era_reproj = ds.salem.transform(dse.t2m) assert t2_era_reproj.salem.grid == ds.salem.grid @savefig plot_era_repr_nn.png width=80% - t2_era_reproj.isel(time=0).salem.quick_map() + t2_era_reproj.isel(time=0).salem.quick_map(); @@ -108,4 +108,4 @@ Salem can also transform data from one grid to another: t2_era_reproj = ds.salem.transform(dse.t2m, interp='spline') @savefig plot_era_repr_spline.png width=80% - t2_era_reproj.isel(time=0).salem.quick_map() + t2_era_reproj.isel(time=0).salem.quick_map(); diff --git a/docs/faq.rst b/docs/faq.rst index 2309098..a51cef0 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -6,8 +6,8 @@ Frequently Asked Questions What is the development status of the salem library? ---------------------------------------------------- -As of today (August 2021), salem is used by several people (number unknown) -and is used by at least one downstream larger project +As of today (February 2024), salem is used by several people (number unknown) +and is used by at least one larger project important to me (`OGGM `_). I plan to continue to maintain salem in the future, but cannot spend much time and energy in new, larger features that the community might need. These larger features (mostly: improved support diff --git a/docs/gis.rst b/docs/gis.rst index d64ec56..f845bc8 100644 --- a/docs/gis.rst +++ b/docs/gis.rst @@ -68,7 +68,7 @@ The default is to define the grids according to the pixels center point: smap.set_points(lon.flatten(), lat.flatten()) @savefig plot_example_grid.png width=80% - smap.visualize(addcbar=False) + smap.visualize(addcbar=False); But with the ``pixel_ref`` keyword you can use another convention. For Salem, the two conventions are identical: diff --git a/docs/installing.rst b/docs/installing.rst index 86aeb2d..ba0a07e 100644 --- a/docs/installing.rst +++ b/docs/installing.rst @@ -8,15 +8,14 @@ Salem is a pure python package, but it has several non-trivial dependencies. Required dependencies --------------------- -- Python 2.7 or 3+ (Py3 `recommended `__) +- Python 3+ - `numpy `__ (of course) - `scipy `__: for its interpolation tools, among other things - `pyproj `__: for map projections transformations - `netCDF4 `__: to read most geoscientific files - `pandas `__: working with labeled data -- `xarray `__ (0.8 or later): pandas in N-dimensions +- `xarray `__ : pandas in N-dimensions - `joblib `__: for it's `Memory`_ class -- `six `__: for Py2 compatibility .. _Memory: https://pythonhosted.org/joblib/memory.html diff --git a/docs/plotting.rst b/docs/plotting.rst index 4a5b3a8..e45a160 100644 --- a/docs/plotting.rst +++ b/docs/plotting.rst @@ -57,7 +57,7 @@ nice looking regional maps: .. ipython:: python @savefig salem_quickmap.png width=80% - ds.T2C.isel(time=1).salem.quick_map() + ds.T2C.isel(time=1).salem.quick_map(); Salem maps are different from cartopy's in that they don't change the matplotlib axes' projection. The map background is always going to be a @@ -79,7 +79,7 @@ call to `imshow()`_, with an image size decided at instanciation: smap.grid.nx, smap.grid.ny # size of the "image", and thus of the axes @savefig map_central_europe.png width=100% - smap.visualize(addcbar=False) + smap.visualize(addcbar=False); The map has it's own grid, wich is used internally in order to transform the data that has to be plotted on it: @@ -89,7 +89,7 @@ the data that has to be plotted on it: ds = open_xr_dataset(get_demo_file('histalp_avg_1961-1990.nc')) smap.set_data(ds.prcp) # histalp is a lon/lat dataset @savefig map_histalp.png width=100% - smap.visualize() + smap.visualize(); Refer to :ref:`recipes` for more examples on how to use salem's maps. diff --git a/docs/wrf.rst b/docs/wrf.rst index 8c716f6..76ba18b 100644 --- a/docs/wrf.rst +++ b/docs/wrf.rst @@ -88,7 +88,7 @@ accumulated fields). For a list of diagnostic variables (and TODOs!), refer to .. ipython:: python @savefig plot_wrf_diag.png width=80% - ds.PRCP.isel(time=-1).salem.quick_map(cmap='Purples', vmax=5) + ds.PRCP.isel(time=-1).salem.quick_map(cmap='Purples', vmax=5); Vertical interpolation @@ -147,4 +147,4 @@ file and parse it: maps[0].set_rgb(natural_earth='lr') # add a background image @savefig plot_geo_simu.png width=100% - maps[0].visualize(title='Domains 1 to 4') + maps[0].visualize(title='Domains 1 to 4'); diff --git a/salem/gis.py b/salem/gis.py index b554bb7..16b32c3 100644 --- a/salem/gis.py +++ b/salem/gis.py @@ -3,7 +3,6 @@ """ # Python 2 stuff from __future__ import division -from six import string_types # Builtins import copy @@ -55,18 +54,14 @@ def check_crs(crs, raise_on_error=False): except: pass - if isinstance(crs, string_types): - # necessary for python 2 - crs = str(crs) - err1, err2 = None, None if isinstance(crs, pyproj.Proj) or isinstance(crs, Grid): out = crs elif isinstance(crs, crs_type): out = pyproj.Proj(crs.to_wkt(), preserve_units=True) - elif isinstance(crs, dict) or isinstance(crs, string_types): - if isinstance(crs, string_types): + elif isinstance(crs, dict) or isinstance(crs, str): + if isinstance(crs, str): # quick fix for https://github.com/pyproj4/pyproj/issues/345 crs = crs.replace(' ', '').replace('+', ' +') diff --git a/salem/graphics.py b/salem/graphics.py index 2a33b7b..fa512ad 100644 --- a/salem/graphics.py +++ b/salem/graphics.py @@ -2,7 +2,6 @@ Color handling and maps. """ from __future__ import division -import six # Builtins import warnings @@ -148,9 +147,9 @@ def update(self, d): Update the properties of :class:`DataLevels` from the dictionary *d*. """ - for k, v in six.iteritems(d): + for k, v in d.items(): func = getattr(self, 'set_' + k, None) - if func is None or not six.callable(func): + if func is None or not callable(func): raise AttributeError('Unknown property %s' % k) func(v) @@ -179,10 +178,12 @@ def set_vmax(self, val=None): def set_cmap(self, cm=None): """Set a colormap.""" - self.cmap = get_cmap(cm or 'viridis' ) + self.cmap = get_cmap(cm or 'viridis') def set_norm(self, norm=None): - """Set a normalization function. Related parameters will be ignored if set (e.g., vmin and vmax will be ignored if using LogNorm)""" + """Set a normalization function. Related parameters will be ignored if set. + + (e.g., vmin and vmax will be ignored if using LogNorm)""" self._norm = norm def set_extend(self, extend=None): @@ -576,7 +577,6 @@ def set_contourf(self, data=None, crs=None, interp='nearest', **kwargs): kwargs: anything accepted by contourf """ - # Check input if data is None: self._contourf_data = None @@ -598,7 +598,6 @@ def set_contour(self, data=None, crs=None, interp='nearest', **kwargs): kwargs: anything accepted by contour """ - # Check input if data is None: self._contour_data = None @@ -921,7 +920,7 @@ def set_topography(self, topo=None, crs=None, relief_factor=0.7, **kwargs): kwargs.setdefault('interp', 'spline') - if isinstance(topo, six.string_types): + if isinstance(topo, str): _, ext = os.path.splitext(topo) if ext.lower() == '.tif': g = GeoTiff(topo) diff --git a/salem/tests/__init__.py b/salem/tests/__init__.py index 8a6dba6..5a9a393 100644 --- a/salem/tests/__init__.py +++ b/salem/tests/__init__.py @@ -3,8 +3,8 @@ from packaging.version import Version import os from salem import python_version -from six.moves.urllib.request import urlopen -from six.moves.urllib.error import URLError +from urllib.request import urlopen +from urllib.error import URLError on_travis = False if os.environ.get('TRAVIS') is not None: @@ -20,6 +20,7 @@ def has_internet(): pass return False + try: import shapely has_shapely = True diff --git a/salem/utils.py b/salem/utils.py index 5466b44..e0ec917 100644 --- a/salem/utils.py +++ b/salem/utils.py @@ -13,7 +13,7 @@ from joblib import Memory from salem import (cache_dir, sample_data_dir, sample_data_gh_commit, download_dir, python_version) -from six.moves.urllib.request import urlretrieve, urlopen +from urllib.request import urlretrieve, urlopen def _hash_cache_dir(): @@ -99,9 +99,9 @@ def _hash_cache_dir(): 'phony_dim_0', 'eastings', 'easting', 'nlon', 'nlong', 'grid_longitude_t'] valid_names['y_dim'] = ['south_north', 'lat', 'latitude', 'latitudes', 'lats', - 'xlat', 'xlat_m', 'dimlat', 'y','lat_3', 'phony_dim_1', + 'xlat', 'xlat_m', 'dimlat', 'y', 'lat_3', 'phony_dim_1', 'northings', 'northing', 'nlat', 'grid_latitude_t'] -valid_names['z_dim'] = ['levelist','level', 'pressure', 'press', 'zlevel', 'z', +valid_names['z_dim'] = ['levelist', 'level', 'pressure', 'press', 'zlevel', 'z', 'bottom_top'] valid_names['t_dim'] = ['time', 'times', 'xtime'] @@ -254,7 +254,7 @@ def get_natural_earth_file(res='lr'): urlpath = nearth_base + '8192/textures/2_no_clouds_8k.jpg' elif res == 'hr': urlpath = nearth_base + '16200/textures/2_no_clouds_16k.jpg' - ofile = os.path.join(download_dir, 'natural_earth_' + res+ '.jpg') + ofile = os.path.join(download_dir, 'natural_earth_' + res + '.jpg') # download only if necessary if not os.path.exists(ofile): @@ -309,7 +309,7 @@ def nice_scale(mapextent, maxlen=0.15): """ d = np.array([1, 2, 5]) e = (np.ones(12) * 10) ** (np.arange(12)-5) - candidates = np.matmul(e[:, None], d[None, :]).flatten() + candidates = np.matmul(e[:, None], d[None, :]).flatten() return np.max(candidates[candidates / mapextent <= maxlen]) diff --git a/setup.cfg b/setup.cfg index 7b85995..875ccd0 100644 --- a/setup.cfg +++ b/setup.cfg @@ -34,7 +34,6 @@ setup_requires = install_requires = numpy scipy - six pyproj joblib netCDF4