4

I would like to use a basic data.frame to get three polylines each of different colours

I am currently using the below code as an example.

require(leaflet)
df <- data.frame(lat=c(rnorm(20,50),rnorm(40,0),rnorm(40,-30)),
                 lon=rnorm(100),
                 group=rep(c("a","b","c"),times=c(20,40,40)),
                 col=rep(rainbow(3,alpha=NULL),times=c(20,40,40)))
leaflet(df) %>% addTiles() %>% addPolylines(lng=~lon,lat=~lat,color=~col)

But I get one continous line and and not the three separate lines for each group.

I can separate the lines but doing an very inelegant trick of:

df_a <- rbind(df[df$group=="a",],data.frame(lat=NA,lon=NA,group="a",col=NA))
df_b <- rbind(df[df$group=="b",],data.frame(lat=NA,lon=NA,group="b",col=NA))
df_c <- rbind(df[df$group=="c",],data.frame(lat=NA,lon=NA,group="c",col=NA))
df <- rbind(df_a,df_b)
df <- rbind(df,df_c) 

before the leaflet function, but it still does not solve the colour problem.

Any help to get the three polylines different colours would be much appreciated.

tospig
  • 7,762
  • 14
  • 40
  • 79
h.l.m
  • 13,015
  • 22
  • 82
  • 169

2 Answers2

3

Here is a way to automate for each group in your dataset:

map <-  leaflet(df)
map <- addTiles(map)
for( group in levels(df$group)){
        map <- addPolylines(map, lng=~lon,lat=~lat,data=df[df$group==group,], color=~col)
        }
map
HubertL
  • 19,246
  • 3
  • 32
  • 51
0

Have a look at mapview which is based on leaflet (at least for small datasets) and has been designed for such particular tasks. The fundamental difference is that you are required to convert df to an object of class SpatialLines* before you can pass the data on to mapview. Here is a short code snippet based on your sample data.

## load packages
library(sp)
library(mapview)

## sample data
set.seed(10)
df <- data.frame(lat = c(rnorm(20, 50), rnorm(40, 0), rnorm(40, -30)),
                 lon = rnorm(100),
                 group = rep(letters[1:3], times = c(20, 40, 40)),
                 col = rep(rainbow(3, alpha = NULL), times = c(20, 40, 40)), 
                 stringsAsFactors = FALSE)

## 'Lines' list
lst_lns <- lapply(letters[1:3], function(i) {
  df_sub <- subset(df, group == i)
  ln <- Line(df_sub[, 2:1])
  Lines(list(ln), ID = i)
})

## to 'SpatialLines'
sln <- SpatialLines(lst_lns, proj4string = CRS("+init=epsg:4326"))

## to 'SpatialLinesDataFrame'
slndf <- SpatialLinesDataFrame(sln, match.ID = FALSE, 
                               data = unique(df[, c("group", "col")]))

## display data
mapview(slndf, zcol = "group", color = slndf@data$col)

grouped_lines

fdetsch
  • 5,239
  • 3
  • 30
  • 58