I'm having a frustrating experience trying to use par(mfg) to move between subplots of a figure. It seems like changing which plot I'm working in using this command resets something about the way y axes are specified such that the ylim=c(a,b) call is useless. This thread (puzzled by xlim/ylim behavior in R) makes me believe that asp may play a role here, but I can't figure out how or how to correct the error.
Briefly, to plot results from density() for multiple datasets on two subplots of a single window, I've written a loop that increments through two lists of output from density() adding new lines to subplot 1, then subplot 2, then back to subplot 1, etc.
DATA.A<-vector("list",length=6)
DATA.B<-vector("list",length=6)
par(mfrow=c(2,1))
plot(0,0, main="title", xlab="X", ylab="Y", xlim=c(c,d), ylim=c(0,30))
plot(0,0, main="title", xlab="X", ylab="Y", xlim=c(c,d), ylim=c(-5,5))
for(i in 1:6){
DATA.A[[i]]<-density(RAWDATA.A[[i]][,"varname"], from=c, to=d, by=e)
DATA.B[[i]]<-density(RAWDATA.B[[i]][,"varname"], from=c, to=d, by=e)
par(mfg=c(1,1))
lines(DATA.A[[i]]$x,DATA.A[[i]]$y,ylim=c(0,30),col="black", lty=i)
lines(DATA.B[[i]]$x,DATA.B[[i]]$y,ylim=c(0,30),col="red", lty=i)
par(mfg=c(2,1))
lines(DATA.A[[i]]$x,DATA.B[[i]]$y-DATA.A[[i]]$y,
ylim=c(-5,5), col="red", lty=i)
abline(v=median(RAWDATA.A[[i]][,"varname"]),lty=i, col="black")
}
EDIT: I am realizing that it fails mostly for the first subplot where it is supposed to be plotting densities over the range from 0 to 30, but instead always resets the axis to the range -1 to 1. Calling plot(0,0), the y tick labels correspond to ylim values I provide, but the data is plotted on the -1 to 1 range. I'd be very grateful for any suggestions.
Related
I would like to represent two-dimensional data as bars, placed over the x-axis values, but barplot() does not allow to control x-axis placement, and plot() does not draw bars:
x <- c(1, 2, 3, 5)
y <- 1:4
plot(x, y, type = "h")
barplot(y)
Click for an image illustrating the plot() and barplot() examples.
I understand that I can plot a histogram –
hist(rep(x, y), breaks = seq(min(x) - 0.5, max(x) + 0.5, 1))
Click for an image illustrating the hist() example.
– but the recreation of the original (non-frequency) data and the calculation of the breaks is not always as straightforward as in this example, so:
Is there a way to force plot() to draw bars?
Or is there a way to force barplot() to place the bars at specific values on the x-axis?
Basically, what I would like is something like:
barplot(y, at = x)
I would prefer to use base R and avoid ggplot.
While I agree with #Dave2e that a barplot may not be the best way to represent your data, you can get something like what you are describing by starting with a blank plot and drawing the relevant rectangles. I am using your y values (1:4) and the x values that you mentioned in your comment. I am not sure what you want on the x-axis, but I show labels for the x-values that you give. In order to look like a barplot, I suppress the tick marks on the x-axis.
plot(NULL, xlim=c(0,11), ylim=c(0,4.5), bty="n",
xaxt="n", xaxs="i", yaxs="i", xlab="", ylab="")
rect(x-0.5, 0, x+0.5, y, col="gray")
axis(side=1, at=x, col.ticks=NA)
Purpose
Create scatter plot with third dimension and multiple colors.
First:
- 3rd dimension with another scale in contrast to y-axis
- create two colors (this is done using col, see code)
Sketch simulating the purpose:
Code
Two "containers" of points plotted in this way:
plot(1:3, c(3,3,3))
points(1:3, c(2,2,2), col="blue")
Another nice plotting is done by:
#install.packages("hexbin")
library(hexbin)
x <- 1:1000#rnorm(1000)
y <- 1500:501#rnorm(1000)
bin<-hexbin(x, y, xbins=50)
plot(bin, main="Hexagonal Binning")
But I do not know how to use hexbin (I do not understand the functionality). There are needed two colors which I do not know how to generate.
Questions
How to create the 3rd axis with other scaling than the y-axis?
Can I use ´hexbin´ to get the result?
For some reason, using points() does not work, but using plot() does work:
#Set margin on right side to be a bit larger
par(mar = c(5,4.5,4,5))
#Plot first set of data
plot(1:3, rep(3,3), ylim=c(-5,5), xlab="X-Axis", ylab="Y-Axis 1")
#Plot second set of data on different axis.
par(new=T)
plot(1:3, rep(5,3), ylim=c(-10,10), col="blue", xlab="", ylab="", axes=FALSE)
#Add numbers and labels to the second y-axis
mtext("Y-Axis 2",side=4,line=3)
axis(4, ylim=c(-10,10))
I am trying to plot several points with error bars, with two y axes.
However at every call of the plotCI or errbar functions, a new plot is initialized - with or without par(new=TRUE) calls -.
require(plotrix)
x <- 1:10
y1 <- x + rnorm(10)
y2<-x+rnorm(10)
delta <- runif(10)
plotCI(x,y=y1,uiw=delta,xaxt="n",gap=0)
axis(side=1,at=c(1:10),labels=rep("a",10),cex=0.7)
par(new=TRUE)
axis(4)
plotCI(x,y=y2,uiw=delta,xaxt="n",gap=0)
I have also tried the twoord.plot function from plotrix, but I don't think it's possible to add the error bars.
With ggplot2 I have only managed to plot in two different panels with the same Y axis.
Is there a way to do this?
Use add=TRUE,
If FALSE (default), create a new plot; if TRUE, add error bars to an
existing plot.
For example the last line becomes:
plotCI(x,y=y2,uiw=delta,xaxt="n",gap=0,add=TRUE)
PS: hard to do this with ggplot2. take a look at this hadley code
EDIT
The user coordinate system is now redefined by specifying a new user setting. Here I do it manually.
plotCI(x,y=y1,uiw=delta,xaxt="n",gap=0)
axis(side=1,at=c(1:10),labels=rep("a",10),cex=0.7)
usr <- par("usr")
par(usr=c(usr[1:2], -1, 20))
plotCI(x,y=y2,uiw=delta,xaxt="n",gap=0,add=TRUE,col='red')
axis(4,col.ticks ='red')
Hello I am trying to create a stacked barplot using the following code:
test <- as.matrix(read.csv(file="test4.csv",sep=",",head=TRUE))
test <- test[,2:ncol(test)]
pdf(file="test.pdf", height=4, width=6)
par(lwd = 0.3)
barplot(test, space=0.4, xaxt='n', ann=FALSE)
axis(1, cex.axis=0.25, las=2, at=1:ncol(test), space=0.4, labels=colnames(test))
dev.off()
And I get:
As you can see the labels in the x-axis do not match the bars in the plot. Also, the ticks are huge.
Can you guys help me beautify the x axis? Thanks so much
Try storing the returned value of the call to barplot() in a named object, and then passing that in to the at= argument of axis():
xLabLocs <- barplot(test, space=0.4, xaxt='n', ann=FALSE)
axis(1, cex.axis=0.25, las=2, at=xLabLocs,
space=0.4, labels=colnames(test))
This may look odd, but it is explained in the Value section of the ?barplot help file:
Value:
A numeric vector (or matrix, when ‘beside = TRUE’), say ‘mp’,
giving the coordinates of _all_ the bar midpoints drawn, useful
for adding to the graph.
You just made the (easy enough to make) mistake of assuming that the x-axis coordinates of the bar centers are at 1:n, where n is the number of bars. That's not necessarily true, so it's nice that a single call to barplot() will both: (a) plot the bar plot as its side effect; and (b) return the necessary x-axis coordinates as its return value.
I am starting on a bit of analysis on pairs of stocks (pairs trading) and here is the function I wrote for producing a graph (pairs.report - listed below).
I need to plot three different lines in a single plot. The function I have listed does what I want it to do, but it will take a bit of work if I want a fine customisation in the x-axis (the time line). As it is, it prints just the years (for 10 years of data) or the months (for 6 months of data) in the x-axis, with no formatting for ticks.
If I use an xts object, i.e., if I use
plot(xts-object-with-date-asset1-asset2, ...)
instead of
plot(date, asset2, ...)
I get a nicely formatted x-axis right away (along with the grid and the box), but subsequent additions to the plot using functions like points(), text(), lines() fails. I suppose points.xts() and text.xts() are not coming out any time soon.
I would like the convenience of xts objects, but I will also require a fine grained control over my plot. So what should my work-flow be like? Do I have to stick to basic graphics and do all the customisation manually? Or is there a way I can make xts work for me?
I am aware of lattice and ggplot2, but I don't want to use them now. Here is the function I mentioned (any criticism/ suggestions for improvement of the code is welcome) -
library(xts)
pairs.report <- function(asset1, asset2, dataset) {
#create data structures
attach(dataset)
datasetlm <- lm(formula = asset1 ~ asset2 + 0, data = dataset)
beta = coef(datasetlm)[1]
#add extra space to right margin of plot within frame
par(mar=c(5, 4, 4, 4) + 0.1)
# Plot first set of data and draw its axis
ylim <- c(min(asset2,asset1), max(asset2,asset1))
plot(date,
asset2,
axes=T,
ylim=ylim,
xlab="Timeline",
ylab="asset2 and asset1 equity",
type="l",
col="red",
main="Comparison between asset2 and asset1")
lines(date, asset1, col="green")
box()
grid(lwd=3)
# Allow a second plot on the same graph
par(new=T)
# Plot the second plot and
ylim <- c(min(asset1-beta*asset2), max(asset1-beta*asset2))
plot(date,
asset1-beta*asset2,
xlab="", ylab="",
ylim=ylim,
axes=F,
type="l",
col="blue")
#put axis scale on right
axis(side=4,
ylim=ylim,
col="blue",
col.axis="blue")
mtext("Residual Spread",side=4,col="blue",line=2.5)
abline(h=mean(asset1-beta*asset2))
}
plot.xts is a base plot function, which means you can use points.default() and lines.default() if you used the same x arguments as plot.xts uses. But that is not necessary. It is already hashed out in the xts and zoo packages because when those packages are loaded, and you execute methods(lines) and methods(points) you see such functions are already available. points.zoo is documented on the ?plot.zoo page.