@@ -23,8 +23,7 @@ source("setup.R")
23
23
::::::::::::::::::::::::::::::::::::::::::::::::::
24
24
25
25
``` {r load-libraries, echo=FALSE, results="hide", message=FALSE}
26
- library(raster)
27
- library(rgdal)
26
+ library(terra)
28
27
library(ggplot2)
29
28
library(dplyr)
30
29
library(reshape)
@@ -35,10 +34,13 @@ library(scales)
35
34
``` {r load-data, echo=FALSE, results="hide"}
36
35
# learners will have this data loaded from the previous episode
37
36
38
- all_NDVI_HARV <- list.files("data/NEON-DS-Landsat-NDVI/HARV/2011/NDVI", full.names = TRUE, pattern = ".tif$")
37
+ all_NDVI_HARV <- list.files("data/NEON-DS-Landsat-NDVI/HARV/2011/NDVI",
38
+ full.names = TRUE, pattern = ".tif$")
39
39
40
40
# Create a time series raster stack
41
- NDVI_HARV_stack <- stack(all_NDVI_HARV)
41
+ NDVI_HARV_stack <- rast(all_NDVI_HARV)
42
+ # NOTE: Fix the bands' names so they don't start with a number!
43
+ names(NDVI_HARV_stack) <- paste0("X", names(NDVI_HARV_stack))
42
44
43
45
# apply scale factor
44
46
NDVI_HARV_stack <- NDVI_HARV_stack/10000
@@ -54,20 +56,22 @@ NDVI_HARV_stack_df <- as.data.frame(NDVI_HARV_stack, xy = TRUE) %>%
54
56
55
57
## Things You'll Need To Complete This Episode
56
58
57
- See the [ lesson homepage] ( . ) for detailed information about the software,
58
- data, and other prerequisites you will need to work through the examples in this episode.
59
+ See the [ lesson homepage] ( . ) for detailed information about the software, data,
60
+ and other prerequisites you will need to work through the examples in this
61
+ episode.
59
62
60
63
61
64
::::::::::::::::::::::::::::::::::::::::::::::::::
62
65
63
- This episode covers how to customize your raster plots using the ` ggplot2 ` package
64
- in R to create publication-quality plots.
66
+ This episode covers how to customize your raster plots using the ` ggplot2 `
67
+ package in R to create publication-quality plots.
65
68
66
69
## Before and After
67
70
68
- In [ the previous episode] ( 12-time-series-raster/ ) , we learned how to plot multi-band
69
- raster data in R using the ` facet_wrap() ` function. This created a separate panel in our plot
70
- for each raster band. The plot we created together is shown below:
71
+ In [ the previous episode] ( 12-time-series-raster/ ) , we learned how to plot
72
+ multi-band raster data in R using the ` facet_wrap() ` function. This created a
73
+ separate panel in our plot for each raster band. The plot we created together
74
+ is shown below:
71
75
72
76
``` {r levelplot-time-series-before, echo=FALSE}
73
77
# code not shown, demonstration only
@@ -77,10 +81,13 @@ ggplot() +
77
81
ggtitle("Landsat NDVI", subtitle = "NEON Harvard Forest")
78
82
```
79
83
80
- Although this plot is informative, it isn't something we would expect to see in a journal publication. The x
81
- and y-axis labels aren't informative. There is a lot of unnecessary gray background and the titles of
82
- each panel don't clearly state that the number refers to the Julian day the data was collected. In this
83
- episode, we will customize this plot above to produce a publication quality graphic. We will go through these steps iteratively. When we're done, we will have created the plot shown below.
84
+ Although this plot is informative, it isn't something we would expect to see in
85
+ a journal publication. The x and y-axis labels aren't informative. There is a
86
+ lot of unnecessary gray background and the titles of each panel don't clearly
87
+ state that the number refers to the Julian day the data was collected. In this
88
+ episode, we will customize this plot above to produce a publication quality
89
+ graphic. We will go through these steps iteratively. When we're done, we will
90
+ have created the plot shown below.
84
91
85
92
``` {r levelplot-time-series-after, echo=FALSE}
86
93
# code not shown, demonstration only
@@ -94,10 +101,12 @@ green_colors <- brewer.pal(9, "YlGn") %>%
94
101
95
102
ggplot() +
96
103
geom_raster(data = NDVI_HARV_stack_df , aes(x = x, y = y, fill = value)) +
97
- facet_wrap(~variable, nrow = 3, ncol = 5, labeller = labeller(variable = labels_names)) +
104
+ facet_wrap(~variable, nrow = 3, ncol = 5,
105
+ labeller = labeller(variable = labels_names)) +
98
106
ggtitle("Landsat NDVI - Julian Days", subtitle = "Harvard Forest 2011") +
99
107
theme_void() +
100
- theme(plot.title = element_text(hjust = 0.5, face = "bold"), plot.subtitle = element_text(hjust = 0.5)) +
108
+ theme(plot.title = element_text(hjust = 0.5, face = "bold"),
109
+ plot.subtitle = element_text(hjust = 0.5)) +
101
110
scale_fill_gradientn(name = "NDVI", colours = green_colors(20))
102
111
103
112
# cleanup
@@ -106,8 +115,9 @@ rm(raster_names, labels_names, green_colors)
106
115
107
116
## Adjust the Plot Theme
108
117
109
- The first thing we will do to our plot remove the x and y-axis labels and axis ticks, as these are
110
- unnecessary and make our plot look messy. We can do this by setting the plot theme to ` void ` .
118
+ The first thing we will do to our plot remove the x and y-axis labels and axis
119
+ ticks, as these are unnecessary and make our plot look messy. We can do this by
120
+ setting the plot theme to ` void ` .
111
121
112
122
``` {r adjust-theme}
113
123
ggplot() +
@@ -117,13 +127,16 @@ ggplot() +
117
127
theme_void()
118
128
```
119
129
120
- Next we will center our plot title and subtitle. We need to do this ** after** the ` theme_void() ` layer,
121
- because R interprets the ` ggplot ` layers in order. If we first tell R to center our plot title,
122
- and then set the theme to ` void ` , any adjustments we've made to the plot theme will be over-written
123
- by the ` theme_void() ` function. So first we make the theme ` void ` and then we center the title.
124
- We center both the title and subtitle by using the ` theme() ` function and setting the ` hjust `
125
- parameter to 0.5. The ` hjust ` parameter stands for "horizontal justification" and takes any value between
126
- 0 and 1. A setting of 0 indicates left justification and a setting of 1 indicates right justification.
130
+ Next we will center our plot title and subtitle. We need to do this ** after**
131
+ the ` theme_void() ` layer, because R interprets the ` ggplot ` layers in order. If
132
+ we first tell R to center our plot title, and then set the theme to ` void ` , any
133
+ adjustments we've made to the plot theme will be over-written by the
134
+ ` theme_void() ` function. So first we make the theme ` void ` and then we center
135
+ the title. We center both the title and subtitle by using the ` theme() `
136
+ function and setting the ` hjust ` parameter to 0.5. The ` hjust ` parameter stands
137
+ for "horizontal justification" and takes any value between 0 and 1. A setting
138
+ of 0 indicates left justification and a setting of 1 indicates right
139
+ justification.
127
140
128
141
``` {r adjust-theme-2}
129
142
ggplot() +
@@ -139,9 +152,9 @@ ggplot() +
139
152
140
153
## Challenge
141
154
142
- Change the plot title (but not the subtitle) to bold font. You can
143
- (and should!) use the help menu in RStudio or any internet resources
144
- to figure out how to change this setting.
155
+ Change the plot title (but not the subtitle) to bold font. You can (and
156
+ should!) use the help menu in RStudio or any internet resources to figure out
157
+ how to change this setting.
145
158
146
159
::::::::::::::: solution
147
160
@@ -170,12 +183,13 @@ ggplot() +
170
183
Next, let's adjust the color ramp used to render the rasters. First, we can
171
184
change the blue color ramp to a green one that is more visually suited to our
172
185
NDVI (greenness) data using the ` colorRampPalette() ` function in combination
173
- with ` colorBrewer ` which requires loading the ` RColorBrewer ` library. Then we use ` scale_fill_gradientn ` to pass the list of
174
- colours (here 20 different colours) to ggplot.
186
+ with ` colorBrewer ` which requires loading the ` RColorBrewer ` library. Then we
187
+ use ` scale_fill_gradientn ` to pass the list of colours (here 20 different
188
+ colours) to ggplot.
175
189
176
- First we need to create a set of colors to use. We will select a set of
177
- nine colors from the "YlGn" (yellow-green) color palette. This returns a
178
- set of hex color codes:
190
+ First we need to create a set of colors to use. We will select a set of nine
191
+ colors from the "YlGn" (yellow-green) color palette. This returns a set of hex
192
+ color codes:
179
193
180
194
``` {r}
181
195
library(RColorBrewer)
@@ -190,9 +204,9 @@ green_colors <- brewer.pal(9, "YlGn") %>%
190
204
colorRampPalette()
191
205
```
192
206
193
- We can
194
- tell the ` colorRampPalette() ` function how many discrete colors within this color range to
195
- create. In our case, we will use 20 colors when we plot our graphic.
207
+ We can tell the ` colorRampPalette() ` function how many discrete colors within
208
+ this color range to create. In our case, we will use 20 colors when we plot our
209
+ graphic.
196
210
197
211
``` {r change-color-ramp}
198
212
ggplot() +
@@ -213,7 +227,8 @@ pixels that are more green have a higher NDVI value.
213
227
214
228
## Data Tip
215
229
216
- For all of the ` brewer.pal ` ramp names see the [ brewerpal page] ( https://www.datavis.ca/sasmac/brewerpal.html ) .
230
+ For all of the ` brewer.pal ` ramp names see the
231
+ [ brewerpal page] ( https://www.datavis.ca/sasmac/brewerpal.html ) .
217
232
218
233
219
234
::::::::::::::::::::::::::::::::::::::::::::::::::
@@ -222,19 +237,19 @@ For all of the `brewer.pal` ramp names see the [brewerpal page](https://www.data
222
237
223
238
## Data Tip
224
239
225
- Cynthia Brewer, the creator of
226
- ColorBrewer, offers an online tool to help choose suitable color ramps, or to
227
- create your own. [ ColorBrewer 2.0; Color Advise for Cartography] ( https://colorbrewer2.org/ )
240
+ Cynthia Brewer, the creator of ColorBrewer, offers an online tool to help
241
+ choose suitable color ramps, or to create your own.
242
+ [ ColorBrewer 2.0; Color Advise for Cartography] ( https://colorbrewer2.org/ )
228
243
229
244
230
245
::::::::::::::::::::::::::::::::::::::::::::::::::
231
246
232
247
## Refine Plot \& Tile Labels
233
248
234
- Next, let's label each panel in our plot with the Julian day that the
235
- raster data for that panel was collected. The current names come from the band
236
- "layer names"" stored in the
237
- ` RasterStack ` and the first part of each name is the Julian day.
249
+ Next, let's label each panel in our plot with the Julian day that the raster
250
+ data for that panel was collected. The current names come from the band "layer
251
+ names"" stored in the ` RasterStack ` and the first part of each name is the
252
+ Julian day.
238
253
239
254
To create a more meaningful label we can remove the "x" and replace it with
240
255
"day" using the ` gsub() ` function in R. The syntax is as follows:
@@ -249,9 +264,9 @@ names(NDVI_HARV_stack)
249
264
```
250
265
251
266
Now we will use the ` gsub() ` function to find the character string
252
- "\_ HARV\_ ndvi\_ crop" and replace it with a blank string (""). We will
253
- assign this output to a new object (` raster_names ` ) and look
254
- at that object to make sure our code is doing what we want it to.
267
+ "\_ HARV\_ ndvi\_ crop" and replace it with a blank string (""). We will assign
268
+ this output to a new object (` raster_names ` ) and look at that object to make
269
+ sure our code is doing what we want it to.
255
270
256
271
``` {r}
257
272
raster_names <- names(NDVI_HARV_stack)
@@ -291,13 +306,14 @@ ggplot() +
291
306
## Change Layout of Panels
292
307
293
308
We can adjust the columns of our plot by setting the number of columns ` ncol `
294
- and the number of rows ` nrow ` in ` facet_wrap ` . Let's make our plot so that
295
- it has a width of five panels.
309
+ and the number of rows ` nrow ` in ` facet_wrap ` . Let's make our plot so that it
310
+ has a width of five panels.
296
311
297
312
``` {r adjust-layout}
298
313
ggplot() +
299
314
geom_raster(data = NDVI_HARV_stack_df , aes(x = x, y = y, fill = value)) +
300
- facet_wrap(~variable, ncol = 5, labeller = labeller(variable = labels_names)) +
315
+ facet_wrap(~variable, ncol = 5,
316
+ labeller = labeller(variable = labels_names)) +
301
317
ggtitle("Landsat NDVI", subtitle = "NEON Harvard Forest") +
302
318
theme_void() +
303
319
theme(plot.title = element_text(hjust = 0.5, face = "bold"),
@@ -311,18 +327,17 @@ Now we have a beautiful, publication quality plot!
311
327
312
328
## Challenge: Divergent Color Ramps
313
329
314
- When we used the ` gsub() ` function to modify the tile labels we replaced the beginning of each
315
- tile title with "Day". A more descriptive name could be "Julian Day". Update the
316
- plot above with the following changes:
330
+ When we used the ` gsub() ` function to modify the tile labels we replaced the
331
+ beginning of each tile title with "Day". A more descriptive name could be
332
+ "Julian Day". Update the plot above with the following changes:
317
333
318
- 1 . Label each tile "Julian Day" with the julian day value
319
- following.
334
+ 1 . Label each tile "Julian Day" with the julian day value following.
320
335
2 . Change the color ramp to a divergent brown to green color ramp.
321
336
322
337
** Questions:**
323
- Does having a divergent color ramp represent the data
324
- better than a sequential color ramp (like "YlGn")? Can you think of other data
325
- sets where a divergent color ramp may be best?
338
+ Does having a divergent color ramp represent the data better than a sequential
339
+ color ramp (like "YlGn")? Can you think of other data sets where a divergent
340
+ color ramp may be best?
326
341
327
342
::::::::::::::: solution
328
343
@@ -345,8 +360,8 @@ ggplot() +
345
360
```
346
361
347
362
For NDVI data, the sequential color ramp is better than the divergent as it is
348
- more akin to the process
349
- of greening up, which starts off at one end and just keeps increasing.
363
+ more akin to the process of greening up, which starts off at one end and just
364
+ keeps increasing.
350
365
351
366
352
367
0 commit comments