New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

plotting points with geom_sf (simple features format) #2037

Closed
GreenStat opened this Issue Feb 11, 2017 · 8 comments

Comments

Projects
None yet
3 participants
@GreenStat

GreenStat commented Feb 11, 2017

copied from r-spatial/sf#88

HI, I tried point and line geometry with (the experimental) 'geom_sf' for plotting maps (in simple features format ):

library(sf)
library(maps)
library(ggplot2)

#points
data(meuse,package="sp")
meuse_sf <- st_as_sf(meuse, coords = c("x", "y"), crs = 28992, agr = "constant")

summary(meuse_sf)

meuse_sf %>% ggplot() + geom_sf(aes(size=cadmium))

this gives:
tmp1

I am a bit confused by the behaviour of aes in geom_sf, with aes(size=cadmium) I expected varying size of dots, instead it gives me varying size of line thickness of the circles.
How do I change type and size of dots?

meuse_sf %>% ggplot() + geom_sf(aes(color=cadmium)) gives:
tmp2

line color of the circles changes, I want a fill....

meuse_sf %>% ggplot() + geom_sf(aes(fill=cadmium))
this gives:
tmp3

more confusing, I still want a fill.... :-), how can I do that ?

@hadley

This comment has been minimized.

Show comment
Hide comment
@hadley

hadley Feb 13, 2017

Member

Could you help me about by making a very simple point dataset that I could include in a unit test?

Member

hadley commented Feb 13, 2017

Could you help me about by making a very simple point dataset that I could include in a unit test?

@GreenStat

This comment has been minimized.

Show comment
Hide comment
@GreenStat

GreenStat Feb 13, 2017

sure,
maybe you can give me a pointer to the type of dataset you need. I could tweek the meuse data by adding factor, posix(?), char column, is that the kind of file you need ?

GreenStat commented Feb 13, 2017

sure,
maybe you can give me a pointer to the type of dataset you need. I could tweek the meuse data by adding factor, posix(?), char column, is that the kind of file you need ?

@hadley

This comment has been minimized.

Show comment
Hide comment
@hadley

hadley Feb 13, 2017

Member

It's more the opposite - I need a few lines of code to that create a dataset with ~4 points without any external dependencies

Member

hadley commented Feb 13, 2017

It's more the opposite - I need a few lines of code to that create a dataset with ~4 points without any external dependencies

@GreenStat

This comment has been minimized.

Show comment
Hide comment
@GreenStat

GreenStat Feb 13, 2017

does this works ? (I am not very familiar with dput)

dput(simple.sf)
 
structure(list(names = c("utrecht", "groningen", "amsterdam", 
"munster"), geometry = structure(list(`1` = structure(c(5.1214201, 
52.0907374), class = c("XY", "POINT", "sfg")), `2` = structure(c(6.5665018, 
53.2193835), class = c("XY", "POINT", "sfg")), `3` = structure(c(4.8951679, 
52.3702157), class = c("XY", "POINT", "sfg")), `4` = structure(c(7.6261347, 
51.9606649), class = c("XY", "POINT", "sfg"))), .Names = c("1", 
"2", "3", "4"), n_empty = 0L, precision = 0, crs = structure(list(
    epsg = 4326L, proj4string = "+proj=longlat +datum=WGS84 +no_defs"), .Names = c("epsg", 
"proj4string"), class = "crs"), bbox = structure(c(4.8951679, 
51.9606649, 7.6261347, 53.2193835), .Names = c("xmin", "ymin", 
"xmax", "ymax")), class = c("sfc_POINT", "sfc"))), .Names = c("names", 
"geometry"), row.names = c(NA, -4L), sf_column = "geometry", agr = structure(NA_integer_, class = "factor", .Label = c("constant", 
"aggregate", "identity"), .Names = "names"), class = c("sf", 
"data.frame"))

GreenStat commented Feb 13, 2017

does this works ? (I am not very familiar with dput)

dput(simple.sf)
 
structure(list(names = c("utrecht", "groningen", "amsterdam", 
"munster"), geometry = structure(list(`1` = structure(c(5.1214201, 
52.0907374), class = c("XY", "POINT", "sfg")), `2` = structure(c(6.5665018, 
53.2193835), class = c("XY", "POINT", "sfg")), `3` = structure(c(4.8951679, 
52.3702157), class = c("XY", "POINT", "sfg")), `4` = structure(c(7.6261347, 
51.9606649), class = c("XY", "POINT", "sfg"))), .Names = c("1", 
"2", "3", "4"), n_empty = 0L, precision = 0, crs = structure(list(
    epsg = 4326L, proj4string = "+proj=longlat +datum=WGS84 +no_defs"), .Names = c("epsg", 
"proj4string"), class = "crs"), bbox = structure(c(4.8951679, 
51.9606649, 7.6261347, 53.2193835), .Names = c("xmin", "ymin", 
"xmax", "ymax")), class = c("sfc_POINT", "sfc"))), .Names = c("names", 
"geometry"), row.names = c(NA, -4L), sf_column = "geometry", agr = structure(NA_integer_, class = "factor", .Label = c("constant", 
"aggregate", "identity"), .Names = "names"), class = c("sf", 
"data.frame"))
@GreenStat

This comment has been minimized.

Show comment
Hide comment
@GreenStat

GreenStat Feb 13, 2017

A simple script version:

lon<-c(5.121420, 6.566502, 4.895168, 7.626135)
lat<-c(52.09074, 53.21938, 52.37022, 51.96066)
cities<-c('utrecht','groningen','amsterdam','munster')
size<-c(300,500,1000,50)

xy.cities<-data.frame(lon,lat,cities,size)
simple.sf <- st_as_sf(xy.cities, coords=c('lon','lat'))
st_crs(simple.sf) <- 4326
simple.sf %>% ggplot() + geom_sf(aes(size=size))

GreenStat commented Feb 13, 2017

A simple script version:

lon<-c(5.121420, 6.566502, 4.895168, 7.626135)
lat<-c(52.09074, 53.21938, 52.37022, 51.96066)
cities<-c('utrecht','groningen','amsterdam','munster')
size<-c(300,500,1000,50)

xy.cities<-data.frame(lon,lat,cities,size)
simple.sf <- st_as_sf(xy.cities, coords=c('lon','lat'))
st_crs(simple.sf) <- 4326
simple.sf %>% ggplot() + geom_sf(aes(size=size))
@hadley

This comment has been minimized.

Show comment
Hide comment
@hadley

hadley Feb 13, 2017

Member

Yeah, the script version is much better, thanks.

Member

hadley commented Feb 13, 2017

Yeah, the script version is much better, thanks.

@hadley

This comment has been minimized.

Show comment
Hide comment
@hadley

hadley Feb 18, 2017

Member

Here's a minimal reprex:

cities <- tibble::tribble(
  ~ lon,    ~ lat,    ~ name,      ~ pop,
  5.121420, 52.09074, "Utrecht",   311367,
  6.566502, 53.21938, "Groningen", 189991,
  4.895168, 52.37022, "Amsterdam", 779808 
) %>% sf::st_as_sf(coords = c("lon", "lat"), crs = 4326)

lines_sfc <- sf::st_sfc(list(
  sf::st_linestring(rbind(cities$geometry[[1]], cities$geometry[[2]])),
  sf::st_linestring(rbind(cities$geometry[[2]], cities$geometry[[3]]))
))

lines <- sf::st_sf(
  id = 1:2,
  size = c(10,50),
  geometry = lines_sfc,
  crs = 4326
)

ggplot() + 
  geom_sf(aes(size = pop), data = cities) + 
  geom_sf(aes(colour = size), data = lines)

The problem is that the geom needs to learn what legend to use from the data, but there's currently no way to pass this information between the two function calls. The documentation for Geom notes:

Compared to \code{Stat} and \code{Position}, \code{Geom} is a little
different because the execution of the setup and compute functions is
split up. \code{setup_data} runs before position adjustments, and
\code{draw_layer} is not run until render time, much later. This
means there is no \code{setup_params} because it's hard to communicate
the changes.

Member

hadley commented Feb 18, 2017

Here's a minimal reprex:

cities <- tibble::tribble(
  ~ lon,    ~ lat,    ~ name,      ~ pop,
  5.121420, 52.09074, "Utrecht",   311367,
  6.566502, 53.21938, "Groningen", 189991,
  4.895168, 52.37022, "Amsterdam", 779808 
) %>% sf::st_as_sf(coords = c("lon", "lat"), crs = 4326)

lines_sfc <- sf::st_sfc(list(
  sf::st_linestring(rbind(cities$geometry[[1]], cities$geometry[[2]])),
  sf::st_linestring(rbind(cities$geometry[[2]], cities$geometry[[3]]))
))

lines <- sf::st_sf(
  id = 1:2,
  size = c(10,50),
  geometry = lines_sfc,
  crs = 4326
)

ggplot() + 
  geom_sf(aes(size = pop), data = cities) + 
  geom_sf(aes(colour = size), data = lines)

The problem is that the geom needs to learn what legend to use from the data, but there's currently no way to pass this information between the two function calls. The documentation for Geom notes:

Compared to \code{Stat} and \code{Position}, \code{Geom} is a little
different because the execution of the setup and compute functions is
split up. \code{setup_data} runs before position adjustments, and
\code{draw_layer} is not run until render time, much later. This
means there is no \code{setup_params} because it's hard to communicate
the changes.

@boshek

This comment has been minimized.

Show comment
Hide comment
@boshek

boshek Mar 13, 2017

Some additional context as well. It looks like shape is not currently supported by geom_sf:

> ggplot(cities) + 
+   geom_sf(shape = 5)
Warning: Ignoring unknown parameters: shape

boshek commented Mar 13, 2017

Some additional context as well. It looks like shape is not currently supported by geom_sf:

> ggplot(cities) + 
+   geom_sf(shape = 5)
Warning: Ignoring unknown parameters: shape

@karawoo karawoo marked this as a duplicate of #2211 Jul 18, 2017

@tidyverse tidyverse deleted a comment from jmigueldelgado Oct 30, 2017

@tidyverse tidyverse deleted a comment from woodwards Oct 30, 2017

@hadley hadley closed this in 8113f77 Oct 31, 2017

@Nowosad Nowosad referenced this issue May 30, 2018

Closed

Review 3: responses #244

95 of 95 tasks complete

@lock lock bot locked as resolved and limited conversation to collaborators Jun 18, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.