File: raster_reprojections.py

package info (click to toggle)
python-cartopy 0.25.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 13,152 kB
  • sloc: python: 16,526; makefile: 159; javascript: 66
file content (98 lines) | stat: -rw-r--r-- 2,791 bytes parent folder | download
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
"""
Raster reprojections
====================

When plotting raster data onto a map with `imshow`, we need to first set the
extent of the map so the reprojection is done correctly.

In this example, we have some raster data stored as a numpy array that is
referenced to a rectangular coordinate system (PlateCarree). Cartopy reprojects the
data to match the map's coordinate system based on the currently set map limits.
This means that the map extent/boundary must be set *before* `imshow` is called.

"""

from matplotlib.patches import Rectangle
import matplotlib.pyplot as plt
import numpy as np

import cartopy.crs as ccrs
import cartopy.feature as cf


def main():
    # Generate raster data as a numpy array
    img = np.linspace(0, 1, 10_000).reshape(100, 100)

    # Define the origin and extent of the image following matplotlib's
    # convention `(left, right, bottom, top)`. These are referenced to
    # a rectangular coordinate system.
    img_origin = "lower"
    img_extent = (-87.6, -86.4, 41.4, 42.0)
    img_proj = ccrs.PlateCarree()

    imshow_kwargs = dict(
        extent=img_extent,
        origin=img_origin,
        transform=img_proj,
        cmap="spring",
    )

    # Define extent and projection for the map
    map_extent = (-88.1, -86.1, 41.2, 42.2)
    map_proj = ccrs.RotatedPole(pole_longitude=120.0, pole_latitude=70.0)

    fig, axs = plt.subplots(
        nrows=1,
        ncols=2,
        figsize=(12, 5),
        subplot_kw={"projection": map_proj},
        sharex=True,
        sharey=True,
        layout="constrained",
    )

    # Adding the raster *before* setting the map extent
    ax = axs[0]
    ax.set_title("\u2717 Adding the raster\nBEFORE setting the map extent")

    ax.imshow(img, **imshow_kwargs)
    ax.set_extent(map_extent, crs=img_proj)

    # Adding the raster *after* setting the map extent
    ax = axs[1]
    ax.set_title("\u2713 Adding the raster\nAFTER setting the map extent")

    ax.set_extent(map_extent, crs=img_proj)
    ax.imshow(img, **imshow_kwargs)

    for ax in axs:
        # Add other map features
        ax.add_feature(cf.LAKES, alpha=0.6)
        ax.add_feature(cf.STATES)

        # Highlight raster boundaries
        xy = (img_extent[0], img_extent[2])
        width = img_extent[1] - img_extent[0]
        height = img_extent[3] - img_extent[2]
        ax.add_patch(
            Rectangle(
                xy,
                width,
                height,
                transform=img_proj,
                edgecolor="black",
                facecolor="None",
                linewidth=3,
                label="Raster data bounds",
            )
        )

        ax.legend()
        ax.gridlines(draw_labels=True, x_inline=False, dms=True)

    plt.show()


if __name__ == "__main__":
    main()