Working with Map Projections#

Interactive Content Ahead! 🚨

This page features interactive content that do not work within the course’s static website. To fully engage with these materials, consider accessing them through environments like CSC/JupyterLab. If you’re viewing this page on the course’s website and wish to load the interactive elements, please use Binder. Look for the Binder icon—a small rocket logo—at the top of the page to get started.

Here, we will explore the concept of map projections through interactive examples of how they affect our maps. Projections are methods for representing the curved surface of the Earth on a flat map. Different projections are used depending on the purpose of the map, as each projection has its own set of advantages and disadvantages, including distortions of area, shape, distance, and direction.

Understanding map projections is crucial for cartographers, geographers, and anyone who works with geographic information systems (GIS). By the end of this activity, you will have a better understanding of how different projections can significantly alter the appearance of geographical features on a map.

[ ]:
# Import the needed libraries
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import ipywidgets as widgets
from IPython.display import display, clear_output
import cartopy
import cartopy.feature as cfeature
import geopandas as gpd

Heads Up! 🚨 As we dive into this activity, we’re going to check out how different projections can twist and turn our maps. Keep in mind, the projections we’re working with include a mix of the good, the bad, and the downright wonky. This is all in the name of learning, of course! When it’s time to get serious and pick a projection for your own mapping ventures, make sure you do a little homework. Choose the best fit that complements the specific needs of your area and nails the goals of your map.

The Importance of Choosing the Right Projection#

Choosing the appropriate map projection is a fundamental aspect of cartography and geographic visualization. Each projection serves a specific purpose:

  • Conformal projections preserve angles locally, making them ideal for navigation and weather maps.

  • Equal-area projections preserve area, making them suitable for demographic and environmental studies.

  • Equidistant projections preserve distances from one or two points to all other points, useful for certain types of analysis or planning.

  • Compromise projections attempt to balance distortion in shape, area, distance, and direction, making them good for general world maps.

No single projection is best for all purposes, and the choice depends on the map’s intended use and the geographic area it represents. Here’s a good article with nice illustrations for different porjection systems.

Below, we will create a global map and see how the choice of a projection affects various aspects of our map. Tissot’s indicatrix is used to demostrate the distortion caused by each projection.

[4]:
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import ipywidgets as widgets
from IPython.display import display, clear_output
import cartopy.feature as cfeature

# Function to plot a global map with the selected projection
def plot_global_map(projection):
    with map_output:
        clear_output(wait=True)  # Clear the previous plot
        plt.figure(figsize=(12, 6))

        if projection in ['PlateCarree', 'Mercator', 'Orthographic', 'Mollweide', 'Robinson',
                          'AzimuthalEquidistant', 'LambertCylindrical', 'EckertIV', 'Gnomonic', 'InterruptedGoodeHomolosine']:
            proj = getattr(ccrs, projection)()
        elif projection == 'Equidistant Cylindrical (Plate Carrée, Equator Centered)':
            proj = ccrs.PlateCarree()
        else:
            proj = ccrs.PlateCarree()  # Default to PlateCarree if something goes wrong

        ax = plt.axes(projection=proj)
        ax.stock_img()  # Add a background image
        ax.coastlines()  # Draw coastlines
        ax.set_global()  # Set the display to a global scale

        # reproject and draw the indicatrix
        ind_grid_proj = ind_grid.to_crs(proj)
        ind_grid_proj.plot(ax=ax, linewidth=0.75, color="#f0f5f5", alpha=0.5)
        ind_caps_proj = ind_caps.to_crs(proj)
        ind_caps_proj.plot(ax=ax)

        title = f"Global Map - {projection} Projection"
        plt.title(title)
        plt.show()

# Dropdown widget for selecting the projection
projection_selector_global = widgets.Dropdown(
    options=[
        'PlateCarree', 'Mercator', 'Orthographic', 'Mollweide', 'Robinson',
        'Equidistant Cylindrical (Plate Carrée, Equator Centered)', 'AzimuthalEquidistant',
        'LambertCylindrical', 'EckertIV', 'Gnomonic', 'InterruptedGoodeHomolosine'
    ],
    value='PlateCarree',
    description='Projection:',
)

# Function to handle projection changes
def on_global_projection_change(change):
    plot_global_map(change['new'])

# load in Tissot's indicatrix caps and graticules as layers
ind_caps = gpd.read_file("data/projection_tissots_indicatrix.gpkg", layer='caps')
ind_grid = gpd.read_file("data/projection_tissots_indicatrix.gpkg", layer='graticule')

# Observe changes in the dropdown selection
projection_selector_global.observe(on_global_projection_change, names='value')

# Output widget to display the plots
map_output = widgets.Output()

# Display the widgets and the initial plot
display(projection_selector_global, map_output)
plot_global_map(projection_selector_global.value)

Now let’s Zoom onto Finland and see how choice of various projections can affect our map of Finland:

[5]:
def plot_finland_map(projection, zone=None):
    with map_output:
        clear_output(wait=True)  # Clear the previous plot
        plt.figure(figsize=(10, 5))

        # Handling EPSG 3067 projection
        if projection == 'EPSG:3067':
            proj = ccrs.epsg('3067')
        elif projection == 'UTM':
            proj = ccrs.UTM(zone=zone, southern_hemisphere=False)
        elif projection == 'Equidistant Cylindrical (Plate Carrée, Equator Centered)':
            # Specifically using Equidistant Cylindrical projection centered on the equator
            proj = ccrs.PlateCarree(central_longitude=0)
        else:
            proj = getattr(ccrs, projection)()

        ax = plt.axes(projection=proj)
        ax.set_extent([20, 32, 59, 71], crs=ccrs.PlateCarree())
        ax.add_feature(cartopy.feature.BORDERS, linestyle=':')
        ax.add_feature(cartopy.feature.LAND, edgecolor='black')
        ax.add_feature(cartopy.feature.COASTLINE)
        ax.add_feature(cartopy.feature.LAKES, alpha=0.5)
        ax.add_feature(cartopy.feature.RIVERS)
        ax.gridlines(draw_labels=True, dms=True, x_inline=False, y_inline=False)

        title = "Map of Finland"
        if projection.startswith('EPSG'):
            title += f" - {projection} Projection"
        elif zone:
            title += f" - UTM Zone {zone} Projection"
        else:
            title += f" - {projection} Projection"
        plt.title(title)
        plt.show()

# Dropdown widget for selecting the projection
projection_selector_finland = widgets.Dropdown(
    options=[
        'PlateCarree', 'Mercator', 'Orthographic', 'Mollweide', 'Robinson', 'UTM',
        'EPSG:3067', 'Equidistant Cylindrical (Plate Carrée, Equator Centered)'
    ],
    value='PlateCarree',
    description='Projection:',
)

def on_projection_change_finland(change):
    if change['new'] == 'UTM':
        plot_finland_map('UTM', zone=35)
    elif change['new'] == 'EPSG:3067':
        plot_finland_map('EPSG:3067')
    elif change['new'] == 'Equidistant Cylindrical (Plate Carrée, Equator Centered)':
        plot_finland_map('Equidistant Cylindrical (Plate Carrée, Equator Centered)')
    else:
        plot_finland_map(change['new'])

projection_selector_finland.observe(on_projection_change_finland, names='value')


projection_selector_finland.observe(on_projection_change_finland, names='value')
map_output = widgets.Output()

display(projection_selector_finland, map_output)
plot_finland_map(projection_selector_finland.value)

Discussion on Projection Choices#

After exploring various map projections, consider the following questions:

  • How do the shapes and sizes of continents change with different projections?

  • Why might a cartographer choose one projection over another for a particular mapping project?

  • What are the implications of projection choice for viewers’ understanding of geographical relationships?