Pamela Allen
2011-Mar-17 22:33 UTC
[R] Help with plotting a line that is multicoloured based on levels of a factor
Hi All, I'm trying to plot data that is a time series of flows that are associated with a specific level, and I would like each level to represent a colour in a line plot. Here is some data that approximates what I'm using: date=c(1:300) flow=sin(2*pi/53*c(1:300)) levels=c(rep(c("high","med","low"),100)) data=cbind.data.frame(date, flow, levels) the "levels" column represents the levels of flow. What I've done so far is to plot this data using coloured points corresponding with each flow level: colour=ifelse(data$levels=="high","red", ifelse(data$levels=="med","green", ifelse(data$levels=="low","blue",""))) plot(date, flow, col=colour) What I would like to do instead is to plot the line of this data, not the points. i.e., plot(date, flow, type="l") But I would like the colour of the line to change with each level, i.e., plot(date, flow, type="l", col=colour) But this doesn't work because the line is continuous and the colours are discrete. I looked into using clipplot, but I'm not sure how I would specify limits that would give different sections of the line correct colours. Does anyone know of a way to draw a line with different colours? One way I thought of was to plot each level of flow separately and then build the plot up, i.e., plot(data$date[data$levels=="high"], data$flow[data$levels=="high"], col="red", type="l") lines(data$date[data$levels=="med"], data$flow[data$levels=="med"], col="green", type="l") lines(data$date[data$levels=="low"], data$flow[data$levels=="low"], col="blue", type="l") But the line fills in data gaps, so this doesn't work. Any help would be much appreciated! Thank you. -Pam Allen pallen at hatfieldgroup.com
Tóth Dénes
2011-Mar-18 00:51 UTC
[R] Help with plotting a line that is multicoloured based on levels of a factor
Hi! Not an elegant solution, but seems to work: date <- c(1:300) flow <- sin(2*pi/53*c(1:300)) levels <- factor(rep(c("high","med","low"),100)) data <- cbind.data.frame(date, flow, levels) colours <- as.numeric(levels)+1 # interpolate resolution <- 0.001 appres <- approx(date,flow,seq(min(date),max(date),resolution)) appres.colour <- rep(colours,each=1/resolution)[1:length(appres[[1]])] # plot plot(appres,col=appres.colour,pch=16,cex=0.5) Of course you should play with the resolution, pch and cex parameters to get a higher quality plot, or might use other function for interpolation. Regards, Denes> > > > > Hi All, > > > > I'm trying to plot data that is a time series of flows that are associated > with a specific level, and I would like each level to represent a colour > in a line plot. Here is some data that approximates what I'm using: > > > > date=c(1:300) > > flow=sin(2*pi/53*c(1:300)) > > levels=c(rep(c("high","med","low"),100)) > > data=cbind.data.frame(date, flow, levels) > > > > the "levels" column represents the levels of flow. What I've done so far > is to plot this data using coloured points corresponding with each flow > level: > > > > colour=ifelse(data$levels=="high","red", > > ifelse(data$levels=="med","green", > > ifelse(data$levels=="low","blue",""))) > > plot(date, flow, col=colour) > > > > What I would like to do instead is to plot the line of this data, not the > points. i.e., > > plot(date, flow, type="l") > > > > But I would like the colour of the line to change with each level, i.e., > > plot(date, flow, type="l", col=colour) > > > > But this doesn't work because the line is continuous and the colours are > discrete. I looked into using clipplot, but I'm not sure how I would > specify limits that would give different sections of the line correct > colours. Does anyone know of a way to draw a line with different colours? > One way I thought of was to plot each level of flow separately and then > build the plot up, i.e., > > plot(data$date[data$levels=="high"], data$flow[data$levels=="high"], > col="red", type="l") > > lines(data$date[data$levels=="med"], data$flow[data$levels=="med"], > col="green", type="l") > > lines(data$date[data$levels=="low"], data$flow[data$levels=="low"], > col="blue", type="l") > > > > But the line fills in data gaps, so this doesn't work. > > > > Any help would be much appreciated! Thank you. > > > > -Pam Allen > > pallen at hatfieldgroup.com > > > > > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide > http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >
baptiste auguie
2011-Mar-18 01:21 UTC
[R] Help with plotting a line that is multicoloured based on levels of a factor
Hi, because each colour is defined on non-consecutive points, you'll probably need to cut the intervals to define segments around each point. One approach might be the following, d = transform(data, start = date - c(0, diff(date)/2), end = date + c(0, diff(date)/2) ) d$start.y = approx(d$date, d$flow, d$start)$y d$end.y = approx(d$date, d$flow, d$end)$y library(ggplot2) ggplot(d) + geom_segment(aes(x=start,y=start.y, xend=end, yend=end.y, colour=levels)) HTH, baptiste On 18 March 2011 11:33, Pamela Allen <pallen at hatfieldgroup.com> wrote:> > > > > Hi All, > > > > I'm trying to plot data that is a time series of flows that are associated > with a specific level, and I would like each level to represent a colour > in a line plot. ?Here is some data that approximates what I'm using: > > > > date=c(1:300) > > flow=sin(2*pi/53*c(1:300)) > > levels=c(rep(c("high","med","low"),100)) > > data=cbind.data.frame(date, flow, levels) > > > > the "levels" column represents the levels of flow. ?What I've done so far > is to plot this data using coloured points corresponding with each flow > level: > > > > colour=ifelse(data$levels=="high","red", > > ? ? ? ? ? ? ? ?ifelse(data$levels=="med","green", > > ? ? ? ? ? ? ? ?ifelse(data$levels=="low","blue",""))) > > plot(date, flow, col=colour) > > > > What I would like to do instead is to plot the line of this data, not the > points. ?i.e., > > plot(date, flow, type="l") > > > > But I would like the colour of the line to change with each level, i.e., > > plot(date, flow, type="l", col=colour) > > > > But this doesn't work because the line is continuous and the colours are > discrete. ?I looked into using clipplot, but I'm not sure how I would > specify limits that would give different sections of the line correct > colours. ?Does anyone know of a way to draw a line with different colours? > One way I thought of was to plot each level of flow separately and then > build the plot up, i.e., > > plot(data$date[data$levels=="high"], data$flow[data$levels=="high"], > col="red", type="l") > > lines(data$date[data$levels=="med"], data$flow[data$levels=="med"], > col="green", type="l") > > lines(data$date[data$levels=="low"], data$flow[data$levels=="low"], > col="blue", type="l") > > > > But the line fills in data gaps, so this doesn't work. > > > > Any help would be much appreciated! ?Thank you. > > > > -Pam Allen > > pallen at hatfieldgroup.com > > > > > > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. > >
David Winsemius
2011-Mar-18 02:22 UTC
[R] Help with plotting a line that is multicoloured based on levels of a factor
On Mar 17, 2011, at 6:33 PM, Pamela Allen wrote:> > Hi All, > I'm trying to plot data that is a time series of flows that are > associated > with a specific level, and I would like each level to represent a > colour > in a line plot. Here is some data that approximates what I'm using: > > date=c(1:300) > flow=sin(2*pi/53*c(1:300)) > levels=c(rep(c("high","med","low"),100)) > data=cbind.data.frame(date, flow, levels) > > the "levels" column represents the levels of flow. What I've done > so far > is to plot this data using coloured points corresponding with each > flow > level: > > colour=ifelse(data$levels=="high","red", > ifelse(data$levels=="med","green", > ifelse(data$levels=="low","blue",""))) > plot(date, flow, col=colour) > > What I would like to do instead is to plot the line of this data, > not the > points. i.e., > > plot(date, flow, type="l") > > But I would like the colour of the line to change with each level, > i.e., > > plot(date, flow, type="l", col=colour) > > But this doesn't work because the line is continuous and the colours > are > discrete. I looked into using clipplot, but I'm not sure how I would > specify limits that would give different sections of the line correct > colours. Does anyone know of a way to draw a line with different > colours? > One way I thought of was to plot each level of flow separately and > then > build the plot up, i.e., > > plot(data$date[data$levels=="high"], data$flow[data$levels=="high"], > col="red", type="l") > > lines(data$date[data$levels=="med"], data$flow[data$levels=="med"], > col="green", type="l") > > lines(data$date[data$levels=="low"], data$flow[data$levels=="low"], > col="blue", type="l") > > > > But the line fills in data gaps, so this doesn't work.I haven't worked through what you have done but it sounds as though you want this function from the plotrix package; color.scale.lines # Display line segments with scaled colors> > > > Any help would be much appreciated! Thank you. > > -Pam Allen > > pallen at hatfieldgroup.com> .David Winsemius, MD West Hartford, CT
Pam Allen
2011-Mar-25 20:19 UTC
[R] Help with plotting a line that is multicoloured based on levels of a factor
Hello again, I wrote an example that better represents my data, since the coloured points are actually consecutive, but with variable lengths: date=as.Date(c(1:300)) flow=sin(2*pi/53*c(1:300)) levels=c(rep(c("high","med","low"),100)) data=cbind.data.frame(date, flow, levels) library(zoo) z <- zoo(data$flow, data$date) zz=cbind.data.frame(date=as.Date(rownames(cbind.data.frame(rollapply(z, 2, align = "right", FUN="+")))),flow.change=(rollapply(z, 2, align "right",FUN="+" ))) names(zz)=c("date","todays.flow","next.day.flow") zzz=cbind.data.frame(zz[,1], (zz[,3]-zz[,2])) names(zzz)=c("date","change.flow") data2=merge(data, zzz) rate=zoo(data2$change.flow,data2$date) x=cbind.data.frame(date=as.Date(rownames(cbind.data.frame(rollapply(rate, 2, align="left", FUN="+")))), sign=rollapply(rate, 2, align="left",FUN="+")) names(x)=c("date","todays.change","next.day.change") xx=cbind.data.frame(x[,1],(x[,3]*x[,2])) names(xx)=c("date","sign") data2=merge(data2, xx) data3=cbind(data2,pass1 ifelse(data2$flow<0, "extreme.low", ifelse(data2$flow>=0.9, "extreme.high","NA"))) data4=cbind(data3, pass2 ifelse(data3$flow<0.8&data3$flow>0&data3$change.flow>=0&data3$change>=0&data3$pass1=="NA","medium" , ifelse(data3$flow<0.7&data3$flow>0&data3$change.flow<0&data3$change<0&data3$pass1=="NA","medium","NA"))) data4$pass1=paste(data4$pass1, data4$pass2) data4$pass1=replace(data4$pass1, data4$pass1=="NA NA", "low") dat=cbind(data4[,1:5], class ifelse(data4$pass1=="extreme.high NA","1.Extreme.High", ifelse(data4$pass1=="NA medium","2.Medium", ifelse(data4$pass1=="low","3.Low", ifelse(data4$pass1=="extreme.low NA","4.Extreme.Low",NA))))) colour=ifelse(dat$class=="1.Extreme.High","red", ifelse(dat$class=="2.Medium","green", ifelse(dat$class=="3.Low","blue", ifelse(dat$class=="4.Extreme.Low","purple","")))) plot(dat$date, dat$flow, col=colour) What I would like to do is to plot this using a line with the correct colours instead of points, i.e.: plot(dat$date, dat$flow, col=colour, type="l") ##Doesn't work, because the line is continuous Any help would be much appreciated. Thank you! -Pam -- View this message in context: http://r.789695.n4.nabble.com/Help-with-plotting-a-line-that-is-multicoloured-based-on-levels-of-a-factor-tp3385857p3406309.html Sent from the R help mailing list archive at Nabble.com.
Seemingly Similar Threads
- How to use the paste function to create an already used variable
- barplot help needed
- [PATCH] inspect: get windows drive letters for GPT disks.
- [PATCHv2] inspect: get windows drive letters for GPT disks.
- missing values are not allowed in subscripted assignments of data frames