Skip to content

Commit

Permalink
Add warning when size is too small (#88)
Browse files Browse the repository at this point in the history
* Add warning when size is too small

* Update vignette and add projection example

* Update R/geom_phylopic.R

Co-authored-by: Lewis A. Jones <[email protected]>

---------

Co-authored-by: Lewis A. Jones <[email protected]>
  • Loading branch information
willgearty and LewisAJones authored Nov 15, 2023
1 parent 54b78f9 commit 9537b39
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 27 deletions.
3 changes: 2 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ Suggests:
ape,
deeptime,
palmerpenguins,
maps
maps,
sf
Config/testthat/edition: 3
URL: https://rphylopic.palaeoverse.org,
https://github.com/palaeoverse-community/rphylopic,
Expand Down
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# rphylopic (development version)

* updated citation
* added warning when specified size is more than 1000 times smaller than the y-axis range (mostly useful for when making maps with coord_sf) (#86)

# rphylopic 1.2.2

Expand Down
15 changes: 11 additions & 4 deletions R/geom_phylopic.R
Original file line number Diff line number Diff line change
Expand Up @@ -232,14 +232,21 @@ GeomPhylopic <- ggproto("GeomPhylopic", Geom,
# Calculate height as percentage of y limits
# (or r limits for polar coordinates)
if ("y.range" %in% names(panel_params)) {
heights <- data$size / diff(panel_params$y.range)
y_diff <- diff(panel_params$y.range)
} else if ("y_range" %in% names(panel_params)) { # exclusive to coord_sf
heights <- data$size / diff(panel_params$y_range)
y_diff <- diff(panel_params$y_range)
} else if ("r.range" %in% names(panel_params)) { # exclusive to coord_polar
heights <- data$size / diff(panel_params$r.range)
y_diff <- diff(panel_params$r.range)
} else {
heights <- data$size
y_diff <- 1
}
if (any(data$size < (y_diff / 1000))) {
warning(paste("Your specified silhouette `size`(s) are more than 1000",
"times smaller than your y-axis range. You probably want",
"to use a larger `size`."), call. = FALSE)
}
heights <- data$size / y_diff

# Hack to make silhouettes the full height of the plot
heights[is.infinite(heights)] <- 1

Expand Down
3 changes: 3 additions & 0 deletions tests/testthat/test-geom_phylopic.R
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ test_that("geom_phylopic works", {
gg <- ggplot(df) +
geom_phylopic(aes(x = x, y = y), uuid = "asdfghjkl")
expect_warning(plot(gg))
gg <- ggplot(df) +
geom_phylopic(aes(x = x, y = y, uuid = uuid), size = 1E-6)
expect_warning(plot(gg))
})

test_that("phylopic_key_glyph works", {
Expand Down
42 changes: 31 additions & 11 deletions vignettes/b-advanced-ggplot.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ ggplot(penguins_subset) +
Now that's a nice figure!

# Geographic distribution
In much the same way as generic x-y plotting, the **rphylopic** package can be used in combination with `{ggplot2}` to plot organism silhouettes on a map. That is, to plot data points (e.g., species occurrences) as silhouettes. We provide an example here of how this might be achieved. For this application, we use the example occurrence dataset of early (Carboniferous to Early Triassic) tetrapods from the `{palaeoverse}` R package to visualize the geographic distribution of *Mesosaurus* fossils.
In much the same way as generic x-y plotting, the **rphylopic** package can be used in combination with `{ggplot2}` to plot organism silhouettes on a map. That is, to plot data points (e.g., species occurrences) as silhouettes. We provide an example here of how this might be achieved. For this application, we use the example occurrence dataset of early (Carboniferous to Early Triassic) tetrapods from the `{palaeoverse}` R package to visualize the geographic distribution of *Diplocaulus* fossils.

First, let's load our libraries and the tetrapod data:

Expand All @@ -184,28 +184,30 @@ First, let's load our libraries and the tetrapod data:
library(rphylopic)
library(ggplot2)
library(palaeoverse)
library(sf)
library(maps)
# Get occurrence data
data(tetrapods)
```

Then we'll subset our occurrences to only those for *Mesosaurus*:
Then we'll subset our occurrences to only those for *Diplocaulus*:


```r
# Subset to desired group
tetrapods <- subset(tetrapods, genus == "Mesosaurus")
tetrapods <- subset(tetrapods, genus == "Diplocaulus")
```

Now, let's plot those occurrences on a world map. `{ggplot2}` and it's built-in function `map_data()` make this a breeze. Note that we use `alpha = 0.75` in case there are multiple occurrences in the same place. That way, the darker the color, the more occurrences in that geographic location.


```r
# Get map data
world <- map_data(map = "world")
world <- st_as_sf(map("world", fill = TRUE, plot = FALSE))
world <- st_wrap_dateline(world)
# Make map
ggplot() +
geom_polygon(data = world, aes(x = long, y = lat, group = group),
fill = "lightgray", color = "darkgrey", linewidth = 0.1) +
ggplot(world) +
geom_sf(fill = "lightgray", color = "darkgrey", linewidth = 0.1) +
geom_point(data = tetrapods, aes(x = lng, y = lat),
size = 4, alpha = 0.75, color = "blue") +
theme_void() +
Expand All @@ -221,9 +223,8 @@ Now, as with the penguin figure above, we can easily replace those points with s


```r
ggplot() +
geom_polygon(data = world, aes(x = long, y = lat, group = group),
fill = "lightgray", color = "darkgrey", linewidth = 0.1) +
ggplot(world) +
geom_sf(fill = "lightgray", color = "darkgrey", linewidth = 0.1) +
geom_phylopic(data = tetrapods, aes(x = lng, y = lat, name = genus),
size = 4, alpha = 0.75, color = "blue") +
theme_void() +
Expand All @@ -237,10 +238,29 @@ ggplot() +

Snazzy!

Note that while we used the genus name as the `name` aesthetic here, we easily could have done `name = "Mesosaurus"` outside of the `aes()` call instead. However, if we were plotting occurrences of multiple genera, we'd definitely want to plot them as different silhouettes using `name = genus` within the `aes()` call.
Note that while we used the genus name as the `name` aesthetic here, we easily could have done `name = "Diplocaulus"` outside of the `aes()` call instead. However, if we were plotting occurrences of multiple genera, we'd definitely want to plot them as different silhouettes using `name = genus` within the `aes()` call.

Also, note that we could change the projection of the map and data using the `crs` and `default_crs` arguments in `coord_sf()`. When projecting data, note that the y-axis limits will change to projected limits. For example, in the Robinson projection, the y-axis limits are roughly -8,600,000 and 8,600,000 in projected coordinates. Therefore, you may need to adjust the `size` argument/aesthetic accordingly when projecting maps and data.


```r
# Set up a bounding box
bbox <- st_graticule(crs = st_crs("ESRI:54030"),
lat = c(-89.9, 89.9), lon = c(-179.9, 179.9))
ggplot(world) +
geom_sf(fill = "lightgray", color = "darkgrey", linewidth = 0.1) +
geom_phylopic(data = tetrapods, aes(x = lng, y = lat, name = genus),
size = 4E5, alpha = 0.75, color = "blue") +
geom_sf(data = bbox) +
theme_void() +
coord_sf(default_crs = st_crs(4326), crs = st_crs("ESRI:54030"))
```

<div class="figure">
<img src="ggplot-geog-plot-3-1.png" alt="plot of chunk ggplot-geog-plot-3" width="100%" />
<p class="caption">plot of chunk ggplot-geog-plot-3</p>
</div>

# Phylogenetics
Another common use case of PhyloPic silhouettes is to represent taxonomic information. In this example, we demonstrate how to use silhouettes within a phylogenetic framework. In this case, the phylogeny, taken from the `{phytools}` package, includes taxa across all vertebrates. Even many taxonomic experts are unlikely to know the scientific names of these 11 disparate taxa, so we'll replace the names with PhyloPic silhouettes. First, let's load our libraries and data:

Expand Down
36 changes: 25 additions & 11 deletions vignettes/b-advanced-ggplot.Rmd.orig
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ ggplot(penguins_subset) +
Now that's a nice figure!

# Geographic distribution
In much the same way as generic x-y plotting, the **rphylopic** package can be used in combination with `{ggplot2}` to plot organism silhouettes on a map. That is, to plot data points (e.g., species occurrences) as silhouettes. We provide an example here of how this might be achieved. For this application, we use the example occurrence dataset of early (Carboniferous to Early Triassic) tetrapods from the `{palaeoverse}` R package to visualize the geographic distribution of *Mesosaurus* fossils.
In much the same way as generic x-y plotting, the **rphylopic** package can be used in combination with `{ggplot2}` to plot organism silhouettes on a map. That is, to plot data points (e.g., species occurrences) as silhouettes. We provide an example here of how this might be achieved. For this application, we use the example occurrence dataset of early (Carboniferous to Early Triassic) tetrapods from the `{palaeoverse}` R package to visualize the geographic distribution of *Diplocaulus* fossils.

First, let's load our libraries and the tetrapod data:

Expand All @@ -150,26 +150,28 @@ First, let's load our libraries and the tetrapod data:
library(rphylopic)
library(ggplot2)
library(palaeoverse)
library(sf)
library(maps)
# Get occurrence data
data(tetrapods)
```

Then we'll subset our occurrences to only those for *Mesosaurus*:
Then we'll subset our occurrences to only those for *Diplocaulus*:

```{r}
# Subset to desired group
tetrapods <- subset(tetrapods, genus == "Mesosaurus")
tetrapods <- subset(tetrapods, genus == "Diplocaulus")
```

Now, let's plot those occurrences on a world map. `{ggplot2}` and it's built-in function `map_data()` make this a breeze. Note that we use `alpha = 0.75` in case there are multiple occurrences in the same place. That way, the darker the color, the more occurrences in that geographic location.

```{r ggplot-geog-plot-1, fig.height = 3.5}
# Get map data
world <- map_data(map = "world")
world <- st_as_sf(map("world", fill = TRUE, plot = FALSE))
world <- st_wrap_dateline(world)
# Make map
ggplot() +
geom_polygon(data = world, aes(x = long, y = lat, group = group),
fill = "lightgray", color = "darkgrey", linewidth = 0.1) +
ggplot(world) +
geom_sf(fill = "lightgray", color = "darkgrey", linewidth = 0.1) +
geom_point(data = tetrapods, aes(x = lng, y = lat),
size = 4, alpha = 0.75, color = "blue") +
theme_void() +
Expand All @@ -179,9 +181,8 @@ ggplot() +
Now, as with the penguin figure above, we can easily replace those points with silhouettes.

```{r ggplot-geog-plot-2, fig.height = 3.5, warning = FALSE}
ggplot() +
geom_polygon(data = world, aes(x = long, y = lat, group = group),
fill = "lightgray", color = "darkgrey", linewidth = 0.1) +
ggplot(world) +
geom_sf(fill = "lightgray", color = "darkgrey", linewidth = 0.1) +
geom_phylopic(data = tetrapods, aes(x = lng, y = lat, name = genus),
size = 4, alpha = 0.75, color = "blue") +
theme_void() +
Expand All @@ -190,10 +191,23 @@ ggplot() +

Snazzy!

Note that while we used the genus name as the `name` aesthetic here, we easily could have done `name = "Mesosaurus"` outside of the `aes()` call instead. However, if we were plotting occurrences of multiple genera, we'd definitely want to plot them as different silhouettes using `name = genus` within the `aes()` call.
Note that while we used the genus name as the `name` aesthetic here, we easily could have done `name = "Diplocaulus"` outside of the `aes()` call instead. However, if we were plotting occurrences of multiple genera, we'd definitely want to plot them as different silhouettes using `name = genus` within the `aes()` call.

Also, note that we could change the projection of the map and data using the `crs` and `default_crs` arguments in `coord_sf()`. When projecting data, note that the y-axis limits will change to projected limits. For example, in the Robinson projection, the y-axis limits are roughly -8,600,000 and 8,600,000 in projected coordinates. Therefore, you may need to adjust the `size` argument/aesthetic accordingly when projecting maps and data.

```{r ggplot-geog-plot-3, fig.height = 3.5, warning = FALSE}
# Set up a bounding box
bbox <- st_graticule(crs = st_crs("ESRI:54030"),
lat = c(-89.9, 89.9), lon = c(-179.9, 179.9))
ggplot(world) +
geom_sf(fill = "lightgray", color = "darkgrey", linewidth = 0.1) +
geom_phylopic(data = tetrapods, aes(x = lng, y = lat, name = genus),
size = 4E5, alpha = 0.75, color = "blue") +
geom_sf(data = bbox) +
theme_void() +
coord_sf(default_crs = st_crs(4326), crs = st_crs("ESRI:54030"))
```

# Phylogenetics
Another common use case of PhyloPic silhouettes is to represent taxonomic information. In this example, we demonstrate how to use silhouettes within a phylogenetic framework. In this case, the phylogeny, taken from the `{phytools}` package, includes taxa across all vertebrates. Even many taxonomic experts are unlikely to know the scientific names of these 11 disparate taxa, so we'll replace the names with PhyloPic silhouettes. First, let's load our libraries and data:

Expand Down
Binary file modified vignettes/ggplot-geog-plot-1-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified vignettes/ggplot-geog-plot-2-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added vignettes/ggplot-geog-plot-3-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 9537b39

Please sign in to comment.