在气象学的世界里,数据不仅仅是冰冷的数字,它们是自然界中风、云、雨、雪的直观反映。随着技术的发展,我们不仅能够收集到更加详尽的气象数据,而且还能以更加直观的方式分享这些信息。对于气象爱好者和博主来说,能够将复杂的气象模式转换成易于理解且吸引人的视觉内容,是一种既有趣又具挑战性的技能。
今天,我们将探索如何使用Python中的geogif库来创建动态的GIF图像,将一系列静态的气象数据图像串连起来,形成一段段生动的动画。这不仅能帮助我们更好地理解天气的变化过程,还可以作为吸引观众注意力的有力工具。无论你是想要向你的博客读者展示台风的路径,还是想说明季节性温度变化,GIF动画都能提供一种简洁而有力的表达方式。
!pip install geogif -i https://pypi.mirrors.ustc.edu.cn/simple/
Looking in indexes: https://pypi.mirrors.ustc.edu.cn/simple/
Collecting geogif
Downloading https://mirrors.bfsu.edu.cn/pypi/web/packages/0f/49/dfe35363818fd47372897929828f3cc47e951046582171caa78a3a3ef5ad/geogif-0.2-py3-none-any.whl (8.8 kB)
Requirement already satisfied: xarray>=0.18 in /opt/conda/lib/python3.9/site-packages (from geogif) (2024.2.0)
Collecting Pillow<11.0,>=10.1
Downloading https://mirrors.bfsu.edu.cn/pypi/web/packages/bc/a8/8655557c9c7202b8abbd001f61ff36711cefaf750debcaa1c24d154ef602/pillow-10.4.0-cp39-cp39-manylinux_2_28_x86_64.whl (4.5 MB)
[2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m4.5/4.5 MB[0m [31m29.7 MB/s[0m eta [36m0:00:00[0m00:01[0m00:01[0m
[?25hRequirement already satisfied: numpy<2.0.0,>=1.20.2 in /opt/conda/lib/python3.9/site-packages (from geogif) (1.26.4)
Requirement already satisfied: dask[delayed]>=2021.4.1 in /opt/conda/lib/python3.9/site-packages (from geogif) (2024.2.0)
Requirement already satisfied: matplotlib<4.0.0,>=3.4.1 in /opt/conda/lib/python3.9/site-packages (from geogif) (3.8.3)
Requirement already satisfied: partd>=1.2.0 in /opt/conda/lib/python3.9/site-packages (from dask[delayed]>=2021.4.1->geogif) (1.2.0)
Requirement already satisfied: importlib-metadata>=4.13.0 in /opt/conda/lib/python3.9/site-packages (from dask[delayed]>=2021.4.1->geogif) (7.0.1)
Requirement already satisfied: click>=8.1 in /opt/conda/lib/python3.9/site-packages (from dask[delayed]>=2021.4.1->geogif) (8.1.3)
Requirement already satisfied: packaging>=20.0 in /opt/conda/lib/python3.9/site-packages (from dask[delayed]>=2021.4.1->geogif) (23.2)
Requirement already satisfied: fsspec>=2021.09.0 in /opt/conda/lib/python3.9/site-packages (from dask[delayed]>=2021.4.1->geogif) (2022.3.0)
Requirement already satisfied: cloudpickle>=1.5.0 in /opt/conda/lib/python3.9/site-packages (from dask[delayed]>=2021.4.1->geogif) (2.0.0)
Requirement already satisfied: pyyaml>=5.3.1 in /opt/conda/lib/python3.9/site-packages (from dask[delayed]>=2021.4.1->geogif) (5.4.1)
Requirement already satisfied: toolz>=0.10.0 in /opt/conda/lib/python3.9/site-packages (from dask[delayed]>=2021.4.1->geogif) (0.12.1)
Requirement already satisfied: pyparsing>=2.3.1 in /opt/conda/lib/python3.9/site-packages (from matplotlib<4.0.0,>=3.4.1->geogif) (3.0.9)
Requirement already satisfied: importlib-resources>=3.2.0 in /opt/conda/lib/python3.9/site-packages (from matplotlib<4.0.0,>=3.4.1->geogif) (5.7.1)
Requirement already satisfied: kiwisolver>=1.3.1 in /opt/conda/lib/python3.9/site-packages (from matplotlib<4.0.0,>=3.4.1->geogif) (1.4.2)
Requirement already satisfied: contourpy>=1.0.1 in /opt/conda/lib/python3.9/site-packages (from matplotlib<4.0.0,>=3.4.1->geogif) (1.2.0)
Requirement already satisfied: cycler>=0.10 in /opt/conda/lib/python3.9/site-packages (from matplotlib<4.0.0,>=3.4.1->geogif) (0.11.0)
Requirement already satisfied: python-dateutil>=2.7 in /opt/conda/lib/python3.9/site-packages (from matplotlib<4.0.0,>=3.4.1->geogif) (2.8.2)
Requirement already satisfied: fonttools>=4.22.0 in /opt/conda/lib/python3.9/site-packages (from matplotlib<4.0.0,>=3.4.1->geogif) (4.33.3)
Requirement already satisfied: pandas>=1.5 in /opt/conda/lib/python3.9/site-packages (from xarray>=0.18->geogif) (2.0.3)
Requirement already satisfied: zipp>=0.5 in /opt/conda/lib/python3.9/site-packages (from importlib-metadata>=4.13.0->dask[delayed]>=2021.4.1->geogif) (3.8.0)
Requirement already satisfied: pytz>=2020.1 in /opt/conda/lib/python3.9/site-packages (from pandas>=1.5->xarray>=0.18->geogif) (2022.1)
Requirement already satisfied: tzdata>=2022.1 in /opt/conda/lib/python3.9/site-packages (from pandas>=1.5->xarray>=0.18->geogif) (2024.1)
Requirement already satisfied: locket in /opt/conda/lib/python3.9/site-packages (from partd>=1.2.0->dask[delayed]>=2021.4.1->geogif) (1.0.0)
Requirement already satisfied: six>=1.5 in /opt/conda/lib/python3.9/site-packages (from python-dateutil>=2.7->matplotlib<4.0.0,>=3.4.1->geogif) (1.16.0)
Installing collected packages: Pillow, geogif
Attempting uninstall: Pillow
Found existing installation: Pillow 9.4.0
Uninstalling Pillow-9.4.0:
Successfully uninstalled Pillow-9.4.0
[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
s2cloudless 1.7.2 requires opencv-python-headless, which is not installed.
eo-learn 1.5.3 requires opencv-python-headless, which is not installed.
eo-learn-mask 1.4.2 requires opencv-python-headless, which is not installed.
pyninjotiff 0.4.0 requires dask[array]<2022.0.0,>=2021.9.1, but you have dask 2024.2.0 which is incompatible.
pyninjotiff 0.4.0 requires xarray<0.20.0,>=0.19.0, but you have xarray 2024.2.0 which is incompatible.
pycaret 2.2.3 requires scikit-learn==0.23.2, but you have scikit-learn 0.24.2 which is incompatible.
eo-learn 1.5.3 requires rasterio>=1.3.8, but you have rasterio 1.3.6 which is incompatible.
basemap 1.3.6 requires matplotlib<3.7,>=1.5; python_version >= "3.5", but you have matplotlib 3.8.3 which is incompatible.
basemap 1.3.6 requires numpy<1.25,>=1.22; python_version >= "3.8", but you have numpy 1.26.4 which is incompatible.[0m[31m
[0mSuccessfully installed Pillow-10.4.0 geogif-0.2
import xarray as xr
ds = xr.open_dataset('/home/mw/input/cru3546/cru_ts4.07.2021.2022.pre.dat.nc')
<xarray.Dataset> Size: 75MB
Dimensions: (lon: 720, lat: 360, time: 24)
Coordinates:
• lon (lon) float32 3kB -179.8 -179.2 -178.8 -178.2 ... 178.8 179.2 179.8• lat (lat) float32 1kB -89.75 -89.25 -88.75 -88.25 ... 88.75 89.25 89.75• time (time) datetime64[ns] 192B 2021-01-16 2021-02-15 ... 2022-12-16
Data variables:
pre (time, lat, lon) float32 25MB ...
stn (time, lat, lon) float64 50MB ...
Attributes:
Conventions: CF-1.4
title: CRU TS4.07 Precipitation
institution: Data held at British Atmospheric Data Centre, RAL, UK.
source: Run ID = 2304141047. Data generated from:pre.2304141039.dtb
history: Fri 14 Apr 12:49:03 BST 2023 : User f098 : Program makegrid...
references: Information on the data is available at http://badc.nerc.ac...
comment: Access to these data is available to any registered CEDA user.
contact: support@ceda.ac.uk
p = ds.pre
p.plot.imshow(col="time", col_wrap=5, robust=True)
<xarray.plot.facetgrid.FacetGrid at 0x7f103a57b0d0>
help(gif)
Help on function gif in module geogif.gif:
gif(arr: 'xr.DataArray', *, to: 'str | Path | BinaryIO | None' = None, fps: 'int' = 16, robust: 'bool' = True, vmin: 'float | None' = None, vmax: 'float | None' = None, cmap: 'str | matplotlib.colors.Colormap | None' = None, date_format: 'str | None' = '%Y-%m-%d', date_position: "Literal['ul', 'ur', 'll', 'lr']" = 'ul', date_color: 'tuple[int, int, int]' = (255, 255, 255), date_bg: 'tuple[int, int, int] | None' = (0, 0, 0), date_size: 'int | float' = 0.15) -> 'IPython.display.Image | None'
Render a `~xarray.DataArray` timestack (``time``, ``band``, ``y``, ``x``) into a GIF.
If the `~xarray.DataArray` contains a `dask.array.Array`, use `dgif` (delayed-GIF) instead.
The `~xarray.DataArray` must have 1 or 3 bands.
Unless ``date_format=None``, a small timestamp will be printed onto each frame of the animation.
You can control the position and styling of this with the ``date_position``, ``date_color``, and
``date_bg`` arguments.
Parameters
----------
arr:
Time-stacked array to animate. Must have 3 or 4 dimensions, which are assumed to be
in the order ``time``, [optional ``band``], ``y``, ``x``.
to:
Where to write the GIF. If None (default), an `IPython.display.Image` is returned,
which will display the GIF in your Jupyter notebook.
fps:
Frames per second
robust:
Calculate ``vmin`` and ``vmax`` from the 2nd and 98th percentiles of the data
(default True)
vmin:
Value in the data to map to 0 (black). If None (default), it's calculated
from the minimum value of the data or the 2nd percentile, depending on ``robust``.
vmax:
Value in the data to map to 255 (white). If None (default), it's calculated
from the maximum value of the data or the 98nd percentile, depending on ``robust``.
cmap:
Colormap to use for single-band data. Can be a
:doc:`matplotlib colormap name <gallery/color/colormap_reference>` as a string,
or a `~matplotlib.colors.Colormap` object for custom colormapping.
If None (default), the default matplotlib colormap (usually ``viridis``) will automatically
be used for 1-band data. Setting a colormap for multi-band data is an error.
date_format:
Date format string (like ``"%Y-%m-%d"``, the default) used to format the timestamps
written onto each frame of the animation. If the coordinates for axis 0 of the
`~xarray.DataArray` are not timestamps or timedeltas, you must explicitly pass
``date_format=None``.
See the `Python string format doc
<https://docs.python.org/3/library/datetime.html#strftime-strptime-behavior>`__
for details.
date_position:
Where to print the timestamp on each frame.
One of ``"ul"`` (upper-left), ``"ur"`` (upper-right), ``"ll"`` (lower-left),
``"lr"`` (lower-right), default ``"ul"``.
date_color:
Color for the timestamp font, as an RGB 3-tuple. Default: ``(255, 255, 255)``
(white).
date_bg:
Fill color to draw behind the timestamp (for legibility), as an RGB 3-tuple.
Default: ``(0, 0, 0)`` (black). Set to None to disable.
date_size:
If a float, make the label this fraction of the width of the image.
If an int, use this absolute font size for the label.
Default: 0.15 (so the label is 15% of the image width).
Note that if Pillow does not have FreeType support, the font size
cannot be adjusted, and the text will be whatever size Pillow's
default basic font is (usually rather small).
Returns
-------
IPython.display.Image or None
If ``to`` is None, returns an `IPython.display.Image`, which will display the
GIF in a Jupyter Notebook. (You can also get the GIF data as bytes from the Image's
``.data`` attribute.)
Otherwise, returns None, and the GIF data is written to ``to``.
Example
-------
>>> # Generate a GIF and show it in your notebook:
>>> stackstac.gif(arr, date_format="Year: %Y")
>>> # Write the GIF to a file, with no timestamp printed:
>>> stackstac.gif(arr, to="animation.gif", fps=24, date_format=None)
>>> # Show a colormapped GIF of single-band data in your notebook,
>>> # with the timestamp font in black and no background behind it:
>>> stackstac.gif(
... arr.sel(band="ndvi"), cmap="YlGn", date_color=(0, 0, 0), date_bg=None
... )
从参数上看可以调整的东西很多,博主挑几个自认为比较需要的点测试一下
from geogif import gif, dgif
gif(p)
坏了,纬度有问题
不要慌,只需sel取值将其倒着取
pd = p.isel(lat=slice(None, None, -1))
pd
<xarray.DataArray 'pre' (time: 24, lat: 360, lon: 720)> Size: 25MB
array([[[nan, nan, ..., nan, nan],
[nan, nan, ..., nan, nan],
...,
[nan, nan, ..., nan, nan],
[nan, nan, ..., nan, nan]],
[[nan, nan, ..., nan, nan],
[nan, nan, ..., nan, nan],
...,
[nan, nan, ..., nan, nan],
[nan, nan, ..., nan, nan]],
...,
[[nan, nan, ..., nan, nan],
[nan, nan, ..., nan, nan],
...,
[nan, nan, ..., nan, nan],
[nan, nan, ..., nan, nan]],
[[nan, nan, ..., nan, nan],
[nan, nan, ..., nan, nan],
...,
[nan, nan, ..., nan, nan],
[nan, nan, ..., nan, nan]]], dtype=float32)
Coordinates:
或者这样
pd1 = p[:, ::-1, :]
pd1
<xarray.DataArray 'pre' (time: 24, lat: 360, lon: 720)> Size: 25MB
array([[[nan, nan, ..., nan, nan],
[nan, nan, ..., nan, nan],
...,
[nan, nan, ..., nan, nan],
[nan, nan, ..., nan, nan]],
[[nan, nan, ..., nan, nan],
[nan, nan, ..., nan, nan],
...,
[nan, nan, ..., nan, nan],
[nan, nan, ..., nan, nan]],
...,
[[nan, nan, ..., nan, nan],
[nan, nan, ..., nan, nan],
...,
[nan, nan, ..., nan, nan],
[nan, nan, ..., nan, nan]],
[[nan, nan, ..., nan, nan],
[nan, nan, ..., nan, nan],
...,
[nan, nan, ..., nan, nan],
[nan, nan, ..., nan, nan]]], dtype=float32)
Coordinates:
from geogif import gif, dgif
gif(pd,date_format=False)
gif(pd1,fps=5)
gif(pd,fps=5, cmap="Greens")
通过本教程,我们不仅学会了如何利用geogif库将气象数据转化为引人入胜的GIF动画,还体验到了将复杂信息简化并以视觉形式呈现的魔力。GIF动画不仅使我们的气象数据更加生动和直观,也为我们提供了与观众互动的新途径。无论是为了教育目的,还是为了娱乐,这种动态的可视化方法都是一个强大的工具,它能够帮助我们讲述天气故事,激发人们对气象科学的兴趣
ps :如果需要保存到本地只需要在参数里加path即可,注意看以上help的说明