I would like to overlay two plots:
plot1
t1 <- c(0,1,2,3,4,5,6,7,8,9,10)
d1 <- c(0,2,4,6,8,10,12,14,16,18,20)
plot2
t2 <- c(0,1,2,3,4,5)
d2 <- c(1,3,7,8,8,8)
I tried
plot(d1~t1, col="black", type="l")
par(new=T)
plot(d2~t2, col="black", type="l")
But the problem is: in this way, both x axes also overlay each other while x in plot1 is 1:10 and plot2 1:5
You can use lines for the second plot (instead of plot). Furthermore, we scale the x-axis values of the second plot (t2) with 2 (I(2 * t2)).
plot(d1 ~ t1, col="black", type="l", xlim=c(0,10))
lines(d2 ~ I(2 * t2), col="black", type="l", xlim=c(0,5))
In this way, the x-range of the second plot is identical to the x-range of the first one.
Related
I would like to overlay two plots:
plot1
t1 <- c(0,1,2,3,4,5,6,7,8,9,10)
d1 <- c(0,2,4,6,8,10,12,14,16,18,20)
plot2
t2 <- c(0,1,2,3,4,5)
d2 <- c(1,3,7,8,8,8)
I tried
plot(d1~t1, col="black", type="l")
par(new=T)
plot(d2~t2, col="black", type="l")
But the problem is: in this way, both x axes also overlay each other while x in plot1 is 1:10 and plot2 1:5
You can use lines for the second plot (instead of plot). Furthermore, we scale the x-axis values of the second plot (t2) with 2 (I(2 * t2)).
plot(d1 ~ t1, col="black", type="l", xlim=c(0,10))
lines(d2 ~ I(2 * t2), col="black", type="l", xlim=c(0,5))
In this way, the x-range of the second plot is identical to the x-range of the first one.
I am trying to plot two different graph in one plot. But, the labeling in y axis is overlapping even though is the labeling is same. Here is my data-
data file 1
data file 2
I used the following code-
plot(`2000_svm_movie`,type="o",col="blue",xlab="Training Years",ylab="Performances", axes=FALSE)
axis(1,at=seq(2000,2014,by=1),las=2)
axis(2,at=seq(78,82,by=1),las=1)
par(new = TRUE)
plot(`2000_random_movie`,type="o",col="red",xlab="Training Years",ylab="Performances", axes=FALSE)
axis(1,at=seq(2000,2014,by=1),las=2)
axis(2,at=seq(78,86,by=1),las=1)
I want Y axis will be labeled like (78,79,80,81,82,83,84,85,86). How can I do this?
You have to add your data, but so far I understand you want something like this?
plot(NULL, xlim=c(2007, 2014), ylim=c(78,86), xlab="Training Years", ylab="Performances")
axis(side=2, at=c(78:86), labels=c(78:86))
x1 <- c(2007:2014)
y1 <- runif(8,78,86)
lines(x1, y1, col="blue")
points(x1,y1, col="blue")
y2 <- runif(8,78,86)
lines(x1, y2, col="red")
points(x1,y2, col="red")
The goal is to reproduce this Bid-Rent graph in R:
The challenge is to draw the projected circles. So far I got:
The 2D part is created by the R code below with the traditional graphic system in base R:
#Distance
X <- seq(0,7,1)
#Bid Rent Curves: Commercial, Industrial, Residential
com <- -5*X + 10
ind <- -2*X + 7
res <- -0.75*X + 4
graph <- plot(X, com, type="l", col="green", ylim=c(0,10), xlab="", ylab="", axes=FALSE)
lines(X, ind, col="red")
lines(X, res, col="blue")
abline(v=0, h=0)
segments(1,0, 1,5, lty=2)
segments(2.5,0, 2.5,2, lty=2)
title(main="Bid Rent Curves", sub="Alonso Model",
xlab="Distance from CBD", ylab="Rent per m2")
text(2.5,7.5, "Commercial", col="green")
text(3.5,4, "Industrial", col="red")
text(5.5,2, "Residential", col="blue")
(Detail: Why the curves do not respect the ylim = 0 ?)
How make the projection and draw the semi-circles?
It is not exactly a 3D plot. I have looked into plot3D and rgl. I am not sure which packages or strategy to use from here.
I'm taking you at your word that you want circles, so you need to push the plot area into the upper right corner:
outHalfCirc <- function(r,colr) {opar=par(xpd=TRUE, new=TRUE) #plot ouside plot area
polygon(x=seq(r,-r,by=-0.1),
y= -sqrt(r^2 - seq(r,-r,by=-0.1)^2) , # solve r^2 = x^2 +y^2 for y
xlim =c(0,7 ), ylim=c(0,10), col=colr, # need xlim and ylim to match base plot ranges
yaxs="i", yaxt="n", xaxs="i") # yaxis off; x and y axes meet at origin
par(opar)}
Then push plot up and to the right: This will draw a colored half-circles (largest first so they overlap) below the y=0 line.
png() # send to image file; not needed for testing
opar <- par(mar=c(15, 15, 2,2) ) # default units are in widths of text-"line".
# the margins start at lower, then clockwise
# run your code
outHalfCirc(5.5, "blue")
outHalfCirc(2.5, "red")
outHalfCirc(1, "green")
dev.off() # complete image production
par(opar) # different than the 'opar' inside the function
Voila! Although not really circles because the aspect ratio is not 1. That can be fixed (or you could set the xlim and ylim to be equal.
I would like to plot something like this (from this paper) where icons, in this case small graphs, are used as tick labels.
I get this far, where icons are more or less properly placed:
This is the code:
library(igraph)
npoints <- 15
y <- rexp(npoints)
x <- seq(npoints)
par(fig=c(0.05,1,0.3,1), new=FALSE)
plot(y, xlab=NA, xaxt='n', pch=15, cex=2, col="red")
lines(y, col='red', lwd=2)
xspan <- 0.9
xoffset <- (0.07+0.5/npoints)*xspan
for(i in 1:npoints){
x1 <- (xoffset+(i-1)/npoints)*xspan
x2 <- min(xspan*(xoffset+(i)/npoints),1)
par(fig=c(x1,x2,0,0.5), new=TRUE)
plot(graph.ring(i), vertex.label=NA)
}
However, if the number of points grows (e.g. npoints <- 15) it complains because there is no place for the icons:
Error in plot.new() : figure margins too large
I wonder wether there is a more natural way to do this so that it works for any (reasonable) number of points.
Any advice is welcome.
library(igraph)
npoints <- 15
y <- rexp(npoints)
x <- seq(npoints)
# reserve some extra space on bottom margin (outer margin)
par(oma=c(3,0,0,0))
plot(y, xlab=NA, xaxt='n', pch=15, cex=2, col="red")
lines(y, col='red', lwd=2)
# graph numbers
x = 1:npoints
# add offset to first graph for centering
x[1] = x[1] + 0.4
x1 = grconvertX(x=x-0.4, from = 'user', to = 'ndc')
x2 = grconvertX(x=x+0.4, from = 'user', to = 'ndc')
# abline(v=1:npoints, xpd=NA)
for(i in x){
print(paste(i, x1[i], x2[i], sep='; '))
# remove plot margins (mar) around igraphs, so they appear bigger and
# `figure margins too large' error is avoided
par(fig=c(x1[i],x2[i],0,0.2), new=TRUE, mar=c(0,0,0,0))
plot(graph.ring(i), vertex.label=NA)
# uncomment to draw box around plot to verify proper alignment:
# box()
}
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"')
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.
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')
})
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: