Skip to content

Commit

Permalink
Merge pull request #178 from geocompx/mapping
Browse files Browse the repository at this point in the history
mapping
  • Loading branch information
michaeldorman authored Jul 20, 2023
2 parents 7a89e38 + 19ad356 commit 9df3b4a
Show file tree
Hide file tree
Showing 10 changed files with 75 additions and 51 deletions.
12 changes: 6 additions & 6 deletions 02-spatial-data.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -603,12 +603,12 @@ In the following two sections, we introduce **rasterio**, which is the raster-re
To work with the **rasterio** package, we first need to import it.
We also import **numpy**, since the underlying raster data are stored in **numpy** arrays.
To effectively work with those, we expose all **numpy** functions.
Finally, we import the `show` function from the `rasterio.plot` sub-module for quick visualization of rasters.
Finally, we import the `rasterio.plot` sub-module for its `show` function for quick visualization of rasters.

```{python}
import numpy as np
import rasterio
from rasterio.plot import show
import rasterio.plot
import subprocess
```

Expand All @@ -633,7 +633,7 @@ src
To get a first impression of the raster values, we can plot the raster using the `show` function:

```{python}
show(src);
rasterio.plot.show(src);
```

The `DatasetReader` contains the raster metadata, that is, all of the information other than the raster values.
Expand Down Expand Up @@ -743,13 +743,13 @@ Note that, confusingly, $delta_{y}$ is defined in `rasterio.transform.from_origi
The raster can now be plotted in its coordinate system, passing the array along with the transformation matrix to `show`:

```{python}
show(elev, transform=new_transform);
rasterio.plot.show(elev, transform=new_transform);
```

The `grain` raster can be plotted the same way, as we are going to use the same transformation matrix for it as well:

```{python}
show(grain, transform=new_transform);
rasterio.plot.show(grain, transform=new_transform);
```

At this point, we can work with the raster using `rasterio`:
Expand Down Expand Up @@ -869,7 +869,7 @@ epsg_codes[:5] ## print first five
pyproj.CRS.from_epsg(4326) ## Printout of WGS84 CRS (EPSG:4326)
```

A quick summary of different projections, their types, properties, and suitability can be found in Map Projections (1993) and at <https://www.geo-projections.com/>.
A quick summary of different projections, their types, properties, and suitability can be found in "Map Projections" (1993) and at <https://www.geo-projections.com/>.
We will expand on CRSs and explain how to project from one CRS to another in Chapter 7.
But, for now, it is sufficient to know:

Expand Down
2 changes: 2 additions & 0 deletions 08-read-write-plot.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -628,4 +628,6 @@ In such cases, the same considerations shown for `int` apply to `float` rasters

## Visual outputs {#sec-visual-outputs}

...

## Exercises
112 changes: 67 additions & 45 deletions 09-mapping.qmd
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
# Making maps with Python {#sec-map-making}

## Introduction

- Geopandas explore has been used in previous chapters.
- When to focus on visualisation? At the end of geographic data processing workflows.

<!-- Input datasets: https://github.com/geocompx/spDatapy -->
<!-- Decision of whether to use static or interactive. -->
<!-- Flow diagram? -->
## Prerequisites

```{python}
#| echo: false
Expand All @@ -25,62 +18,69 @@ else:
z.extractall(".")
```

This chapter requires the following packages:

```{python}
import matplotlib as mpl
import matplotlib.pyplot as plt
import geopandas as gpd
import rasterio
import rasterio.plot
nz = gpd.read_file("data/nz.gpkg")
```

## Static maps

- Focus on matlibplot
- First example: NZ with fill and borders
- Scary matplotlib code here...
Sample data...

```{python}
#| layout-ncol: 3
nz.plot(color="grey");
nz.plot(color="none", edgecolor="blue");
nz.plot(color="grey", edgecolor="blue");
nz = gpd.read_file('data/nz.gpkg')
nz_elev = rasterio.open('data/nz_elev.tif')
```

<!-- # Add fill layer to nz shape
tm_shape(nz) +
tm_fill()
# Add border layer to nz shape
tm_shape(nz) +
tm_borders()
# Add fill and border layers to nz shape
tm_shape(nz) +
tm_fill() +
tm_borders() -->
## Introduction

<!-- - Geopandas explore has been used in previous chapters. -->
<!-- - When to focus on visualisation? At the end of geographic data processing workflows. -->

<!-- Input datasets: https://github.com/geocompx/spDatapy -->

A satisfying and important aspect of geographic research is communicating the results. Map making---the art of cartography---is an ancient skill that involves communication, intuition, and an element of creativity. In addition to being fun and creative, cartography also has important practical applications. A carefully crafted map can be the best way of communicating the results of your work, but poorly designed maps can leave a bad impression. Common design issues include poor placement, size and readability of text and careless selection of colors, as outlined in the style guide of the Journal of Maps. Furthermore, poor map making can hinder the communication of results (Brewer 2015, add citation...):

> Amateur-looking maps can undermine your audience's ability to understand important information and weaken the presentation of a professional data investigation. Maps have been used for several thousand years for a wide variety of purposes. Historic examples include maps of buildings and land ownership in the Old Babylonian dynasty more than 3000 years ago and Ptolemy's world map in his masterpiece Geography nearly 2000 years ago (Talbert 2014, add citation...).
Map making has historically been an activity undertaken only by, or on behalf of, the elite. This has changed with the emergence of open source mapping software such as mapping packages in Python, R, and other languages, and the "print composer" in QGIS which enable anyone to make high-quality maps, enabling "citizen science". Maps are also often the best way to present the findings of geocomputational research in a way that is accessible. Map making is therefore a critical part of geocomputation and its emphasis not only on describing, but also changing the world.

Basic static display of vector layers in Python is done with the `.plot` method or the `rasterio.plot.show` function, for vector layers and rasters, as we saw in Sections @sec-vector-layers and @sec-using-rasterio, respectively. Other, more advaned uses of these methods, were also encountered in later chapters, when demonstrating the various outputs we got. In this chapter, we provide a comprehensive summary of the most useful workflows of these two methods for creating static maps (@sec-static-maps). Then, we move on to elaborate on the `.explore` method for creating interactive maps, which was also briefly introduced earlier (@sec-vector-layers).

## Static maps {#sec-static-maps}

Static maps are the most common type of visual output from geocomputation. Standard formats include `.png` and `.pdf` for raster and vector outputs, respectively. Static maps can be easily shared and viewed (whether digitally or in print), however they can only convey as much information as a static image can. Interactive maps provide much more flexibilty in terms of user experience and amout of information, however they often require more work to design and effectively share.

<!-- Decision of whether to use static or interactive. -->
<!-- Flow diagram? -->

As covered in Chapter 2, you can plot raster datasets as follows:
Let's move on to the basics of static mapping with Python.

A vector layer (`GeoDataFrame`) or a geometry column (`GeoSeries`) can be displayed using their `.plot` method. Most common visual properties include `color`, `edgecolor`, and `markersize` (for points) (@fig-basic-plot):

```{python}
nz_elev = rasterio.open('data/nz_elev.tif')
rasterio.plot.show(nz_elev);
#| label: fig-basic-plot
#| fig-cap: Setting `color` and `edgecolor` in static maps of a vector layer
#| fig-subcap:
#| - Grey fill
#| - No fill, blue edge
#| - Grey fill, blue edge
#| layout-ncol: 3
nz.plot(color='grey');
nz.plot(color='none', edgecolor='blue');
nz.plot(color='grey', edgecolor='blue');
```

<!--
In R:
nz_elev = stars::read_stars("data/nz_elev.tif")
sf::st_crs(nz_elev)
nz = spData::nz
waldo::compare(sf::st_crs(nz), sf::st_crs(nz_elev))
library(sf)
plot(nz)
nz_elev_transformed = sf::st_transform(nz_elev, sf::st_crs(nz))
stars::write_stars(nz_elev_transformed, "data/nz_elev.tif")
nz_transformed = sf::st_transform(nz, sf::st_crs(nz_elev))
sf::st_write(nz_transformed, "nz_transformed.gpkg")
-->
As shown in @sec-using-rasterio, you can plot raster datasets using `rasterio.plot.show`, as follows:

```{python}
rasterio.plot.show(nz_elev);
```

You can combine the raster and vector plotting methods shown above into a single visualisation with multiple layers as follows:
You can combine the raster and vector plotting methods shown above into a single visualisation with multiple layers, which we used to explain masking and cropping (@fig-raster-crop):

<!--
Source:
Expand All @@ -95,10 +95,21 @@ nz.to_crs(nz_elev.crs).plot(ax=ax, facecolor='none', edgecolor='r');


### Palettes

...

### Layers

...

### Faceted maps

...

### Exporting maps as images

...

<!-- ## Animated maps -->

## Interactive maps
Expand Down Expand Up @@ -203,10 +214,21 @@ OUTPUT.to_file('stations.gpkg', driver='GPKG', layer='stations')
- Panel: allows you to create applications/dashboards

### GeoPandas explore

...

### Layers

...

### Publishing interactive maps

...

### Linking geographic and non-geographic visualisations

...

<!-- ## Mapping applications Streamlit? -->

## Exercises
Binary file modified output/world.gpkg
Binary file not shown.
Binary file added output/world_BACKUP_3604277.gpkg
Binary file not shown.
Binary file added output/world_BASE_3604277.gpkg
Binary file not shown.
Binary file added output/world_LOCAL_3604277.gpkg
Binary file not shown.
Binary file added output/world_REMOTE_3604277.gpkg
Binary file not shown.
Binary file modified output/world_many_features.gpkg
Binary file not shown.
Binary file modified output/world_many_layers.gpkg
Binary file not shown.

0 comments on commit 9df3b4a

Please sign in to comment.