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.
Possibly Parallel 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