user3036416
user3036416

Reputation: 1255

Plotting data.frame with different colour according to a column

I have a data frame like this:

> video
id          oldid      year month day   lon    lat    colour
01208513    Continent    1885   1   1   -30.7   -32.65  #FFFFFF
04960001    05890280     1885   1   1   122.72  26.17   #FDFEFF
05520001    CornFMort    1885   1   1   -22.84  48.34   #FBFDFF
06058       06058        1885   1   1   -61.5   36.5    #F9FCFF
06251       06251        1885   1   1   -113.5  -2.5    #F7FBFF
06323        06323       1885   1   1   174.5   -26.5   #F5FAFF
06466       06466        1885   1   1   -115.5  -40.5   #F3F9FF
106323       106323      1885   1   1   177.5   -26.5   #F1F8FF

where I have assigned a colour to every data according to its id

z <- unique(video$id)
range01 <- function(x)(x-min(x))/diff(range(x))
rainbow(7)
cRamp <- function(x){
  cols <- colorRamp(colours())(range01(x))
  apply(cols, 1, function(xt)rgb(xt[1], xt[2], xt[3], maxColorValue=255))
} 
video$col <- as.factor(cRamp(match(video$id,z)))

What I would like to do in fact is to plot the value of lon and lat for every day with the colours distinguishing the different ids but so far it does not seem to work. Can be there any issues related to the class of video$colour or should I assign the colour in a different way?

To plot I dividing the data frame in year/month/day files:

YRMODYlist <- list()
YRMODYlist <- split(video, data.frame(video$yr, video$mo, video$dy))

and then plotting

for (i in 1:length(YRMODYlist)){
    colnames(YRMODYlist[[i]]) <-c("id","oldid","yr","mo","dy","lon","lat","col")
    plot(YRMODYlist[[i]]$lon, YRMODYlist[[i]]$lat, ylim=c(-90,90),xlim=c(-180,180),col = YRMODYlist[[i]]$col)
}

Upvotes: 0

Views: 2012

Answers (2)

Jaap
Jaap

Reputation: 83275

Looking at your data, I suspect that this some kind of geographically oriented dataset (because of the use of the lon and lat variables, which are usually used for identifiing geographic locations) with locations scattered around the world.

Assuming that I'm right, you might tackle this problem as follows:

# reading the data
video <- read.table(header=TRUE, comment.char="",
text="id          oldid      year  month  day   lon    lat    colour
01208513    Continent    1885   1   1   -30.7   -32.65  #FFFFFF
04960001    05890280     1885   1   1   122.72  26.17   #FDFEFF
05520001    CornFMort    1885   1   1   -22.84  48.34   #FBFDFF
06058       06058        1885   1   1   -61.5   36.5    #F9FCFF
06251       06251        1885   1   1   -113.5  -2.5    #F7FBFF
06323        06323       1885   1   1   174.5   -26.5   #F5FAFF
06466       06466        1885   1   1   -115.5  -40.5   #F3F9FF
106323       106323      1885   1   1   177.5   -26.5   #F1F8FF")

# getting the required packages
library(ggmap)
library(ggplot2)

# splitting the dataframe into a list of dataframes by id
video$id <- as.factor(video$id)
idlist <- split(video, video$id)

# creating a map for each location with the corresponding points plotted on it
for (i in 1:length(idlist)){
  x <- get_map(location = c(lon=mean(idlist[[i]]$lon), lat=mean(idlist[[i]]$lat)), zoom=3, maptype="satellite", scale=2)
  p <- ggmap(x) + geom_point(data=idlist[[i]], aes(x=lon, y=lat, fill=as.factor(id)), size = 4, shape = 21, show_guide=FALSE)
  print(p)
}

this will produce a series of plots like this: enter image description here

Upvotes: 2

MrFlick
MrFlick

Reputation: 206536

1) Make sure class(video$color)=="character" It is not a good idea to convert them to factors as you have done. When used as colors, this will fall back to the underlying numeric value of the factor rather than the RGB color you specified. If they are factors, you can run

video$colour <-as.character(video$colour)

or better yet just

video$colour <- as.factor(cRamp(match(video$id,z)))

so they never become factors in the first place

2) Each time you call plot(), what ever was on the graphics device is removed and a new plot is created. If you want to add all the different groups on top of each other, call plot() once, and then call points to add points on top. If you wanted to see multiple different plots, consider using layout() to specify a grid where the plots will be laid out on the graphics device.

3) The colors you have listed in the sample data are incredibly faint, near white. And the default open plotting character is so thin you might not see them at all. Perhaps you have too many ids to assign each a unique, visible color, or you need a better color ramp.

Finally, if it something else that "does not work," be very explicit about what that is.

Upvotes: 2

Related Questions