mac
mac

Reputation: 3554

r xyplot "steps" centered on data points

the type argument to xyplot() can take "s" for "steps." From help(plot):

The two step types differ in their x-y preference: Going from (x1,y1) to (x2,y2) with x1 < x2, 'type = "s"' moves first horizontal, then vertical, whereas 'type = "S"' moves the other way around.

i.e. if you use type="s", the horizontal part of the step has its left end attached to the data point, while type="S" has its right end attached to the data point.

library(lattice)
set.seed(12345)
num.points <- 10
my.df <- data.frame(x=sort(sample(1:100, num.points)),
                    y=sample(1:40, num.points, replace=TRUE))

xyplot(y~x, data=my.df, type=c("p","s"), col="blue", main='type="s"')
xyplot(y~x, data=my.df, type=c("p","S"), col="red", main='type="S"')

type='s'

type='S'

How could one achieve a "step" plot, where the vertical motion happens between data points points, i.e. at x1 + (x2-x1)/2, so that the horizontal part of the step is centered on the data point?

Edited to include some example code. better late than never I suppose.

Upvotes: 2

Views: 971

Answers (2)

agstudy
agstudy

Reputation: 121588

I am using excellent @nico answer to give its lattice version. Even I am ok with @Dwin because the question don't supply a reproducible example, but customizing lattice panel is sometimes challenging. The idea is to use panel.segments which is the equivalent of segments of base graphics.

library(lattice)
xyplot(y~x,
       panel =function(...){
         ll <- list(...)
         x <- ll$x
         y <- ll$y
         x.start <- x - (c(0, diff(x)/2))
         x.end   <- x + (c(diff(x)/2, 0))
         panel.segments(x.start, y, x.end, y, col="orange", lwd=2)
         panel.segments(x.end[-length(x.end)], y[1:(length(y)-1)], 
                        x.end[-length(x.end)], y[-1], col="orange", lwd=2)
         ## this is optional just to compare with type s
         panel.xyplot(...,type='s')
         ## and type S
         panel.xyplot(...,type='S')
       })

enter image description here

Upvotes: 2

nico
nico

Reputation: 51670

This is a base graphics solution, as I am not too much of an expert in lattice.

Essentially you can use segments to draw first the horizontal, then the vertical steps, passing the shifted coordinates as a vector.

Here is an example:

set.seed(12345)

# Generate some data
num.points <- 10
x <- sort(sample(1:100, num.points))
y <- sample(1:40, num.points, replace=T)


# Plot the data with style = "s" and "S"
par(mfrow=c(1,3))

plot(x, y, "s", col="red", lwd=2, las=1, 
     main="Style: 's'", xlim=c(0, 100))
points(x, y, pch=19, col="red", cex=0.8)

plot(x, y, "S", col="blue", lwd=2, las=1, 
     main="Style: 'S'", xlim=c(0, 100))
points(x, y, pch=19, col="blue", cex=0.8)

# Now plot our points
plot(x, y, pch=19, col="orange", cex=0.8, las=1, 
     main="Centered steps", xlim=c(0, 100))

# Calculate the starting and ending points of the
# horizontal segments, by shifting the x coordinates
# by half the difference with the next point
# Note we leave the first and last point as starting and
# ending points
x.start <- x - (c(0, diff(x)/2))
x.end <- x + (c(diff(x)/2, 0))

# Now draw the horizontal segments
segments(x.start, y, x.end, y, col="orange", lwd=2)
# and the vertical ones (no need to draw the last one)
segments(x.end[-length(x.end)], y[1:(length(y)-1)], 
         x.end[-length(x.end)], y[-1], col="orange", lwd=2)

Here is the result: Step plots

Upvotes: 2

Related Questions