I would like to plot two graphs in the same plotting region with horizontal grid lines. Each side of the grid lines should give the value for one graph or the other. There should be no y-axis.
The grid() function allows me to simply set the number of bins using the ny= argument. How do I get the corresponding labels to the grid lines? Usually, I would use axis(..., lwd=0) to get the labels. However, the function requires label positions with at=c() and does not feature a ny= argument. Is there a way to automatically set the locations from the number of bins?
Based on Miff's hint below, this should solve the problem.
plot(1:10, axes=FALSE, ylim=c(0,10), ylab="")
par(yaxp=c(0, 10, 5))
axis(2, lwd=0, col.axis="gray")
par(new=TRUE)
plot(60:50, axes=FALSE, ylim=c(50,60), ylab="")
par(yaxp=c(50, 60, 5))
axis(4, lwd=0, col.axis="gray")
grid(NA, NULL)
grid() gets its locations for gridlines from axTicks(), which in turn uses numbers from par("yaxp"). If you modify this parameter (rather than explicitly passing it to grid), the result will then apply to both the grid drawn and the axis. For example:
plot(1:10, axes=FALSE)
axis(2) #Default 4 sections between ticks
par(yaxp=c(par("yaxp")[1:2], 7)) #Lets have seven instead
axis(4)
grid() #Grid now matches with right rather than left
Obviously similar works for the x axis.
Related
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))
How can one force the visualisation of the zero axes y=0, x=0 in R, removing the external ones siding the plot? I want to obtain the same effect that one can have for example in Gnuplot with set xzeroaxis, set yzeroaxis.
You can do this using by suppressing the default axes by using axes=FALSE and then using axis to draw horizontal and vertical lines to represent the axes.
# example plot
plot(-2:2, -2:2, axes=FALSE)
# add yaxis at position zero and rotate labels 45deg
axis(side=2, pos=0, las=1, lty="dashed")
# x axis
axis(side=1, at=c(-2,-1,1,2), pos=0, lty="dashed")
This produces
Actually, I have solved my own question as follows:
f<-function(x) x^3-2*x
# take the axes off first
plot(f,-2,2, axes=FALSE)
# re-set the axes at a given point (pos=0)
axis(1, pos=0, at=c(-2,-1,0,1,2))
axis(2, pos=0, at=c(-4,-2,2,4))
produces the below, which is what I had in mind (labels and the rest can be then adjusted at will).
I am trying to plot a chat with two axis, here is the code and attached is the plot,
I have to do two adjustments to it.
I want to plot a line with dots and dots should be middle of the bars
Adjusting right side axis(i.e axis(4)) tick marks should align with left side axix(i.e axis(2))
Code:
Region=c("North","South","East","West")
Sales=sample(500:1000,4)
Change=sample(1:10,4)/10
names(Sales)=Region
names(Change)=Region
barplot(Sales,ylim=c(0,1000))
par(new=T)
plot(Change,type="b",axes=F,ylim=c(0,1))
axis(4)
box()
Regards,
Sivaji
First, save your barplot as some object. So you will get coordinates of the middle points. Then to add line you can use also function lines() and just multiply Change values with 1000.
Then for axis() function supply at= values and labels= the same as at=, just divided by 1000.
x<-barplot(Sales,ylim=c(0,1000))
lines(x,Change*1000,type="b")
axis(4,at=seq(0,800,200),labels=seq(0,800,200)/1000)
You need to play to set the same x-axis in the second plot, you get this info from par("usr").
The xaxs="i" is to set the xlim exactly, by default R increase the xlim a bit to make it better looking.
par(mar=c(5,5,2,5)) # change margins
x = barplot(Sales, ylim=c(0,1000)) # barplot, keep middle points of bars
mtext("Sales", 2, line=3) # first y-axis label
xlim = par("usr")[1:2] # get xlim from plot
par(new=TRUE)
plot.new() # new plot
plot.window(xlim=xlim, ylim=c(0,1), xaxs="i", yaxs="i") # new plot area, same xlim
lines(x,Change,type="b") # the lines in the middle points
axis(4) # secondary y-axis
mtext("Change", 4, line=3) # secondary y-axis label
box()
I am running the following code:
par(bg="yellow", mar=c(2,2,2,2))
layout(matrix(c(rep(1,12),2:13),nrow=2,byrow=T),width=myWidth)
plot(days,sum_precip,type="l",xaxt="n",yaxt="n",ann=FALSE,
xlab="TEST",main="WEWQWE",ylab="dsads")
On the last statement, my plot fails to display any labels even after specifying this in arguments. Is it because my margins are too small?
I am trying to add a header for the x-axis for each of my graphs on the bottom row of the layout.
Example of Issue:
Note, I'm more curious about why this does not work. I know I can just specify an axis(..), but this is more out of interest.
Here a solution using mtext. see ?mtext
Text is written in one of the four margins of the current figure
region or one of the outer margins of the device region.
par(bg="lightyellow", mar=c(2,2,2,2))
layout(matrix(c(rep(1,12),2:13),nrow=2,byrow=T))
replicate(13,
{ plot(x=1:5,y=cumsum(1:5),type="l",xaxt="n",yaxt="n",ann=FALSE)
mtext(text='TEST',side=1,line=1)
mtext(text='dsads',side=2,line=1)
})
EDIT
You can set the margin for every plot.
par(bg="lightyellow", mar=c(2,2,2,0))
layout(matrix(c(rep(1,12),2:13),nrow=2,byrow=T))
for(i in 1:13){
if (i %in% 1:2){
plot(x=1:5,y=cumsum(1:5),type="l",xaxt="n",yaxt="n",ann=FALSE)
mtext(text='TEST',side=1,line=1)
mtext(text='dsads',side=2,line=1)
}else{
par( mar=c(2,0,2,0))
plot(x=1:5,y=cumsum(1:5),type="l",xaxt="n",yaxt="n",ann=FALSE)
}
}
Yeah margins are too small.
Example:
par(mar=rep(4,4))
plot(1, 1, xaxt='n', xlab='x', yaxt='n', ylab='y')
this shows the labels (sorry it's tiny).
However using par(mar=rep(2,4)):
The labels are cut off.
You can use the mgp argument to modify the offset (in lines) of the axis text from the axis. In particular (?par), mgp is a vector of length 3 where mgp[1] is the lines between the plot and axis label, mgp[2] is for the axis line itself and mpg[3] is for the axis tick labels.
So:
par(mar=rep(2,4))
# mgp[2:3] irrelevant in this case as we have turned
# axis line/ticks off; doesn't matter what they are set to
plot(1, 1, xaxt='n', xlab='x', yaxt='n', ylab='y', mgp=c(1,0,0))
This will place the axis labels 1 line away from the axis (i.e. on the second line away) which just fits into our margin of 2,2,2,2.
For some reason if I try to display data with the following code, I get the axis right, but the actual data does not plot. Any suggestions?
par(bg="lightgray")
adates <-as.Date(row.names(try),format="%Y-%m-%d")
plot(try[,1],x=adates,type="o",axes=FALSE, ann=FALSE)
usr <- par("usr")
rect(usr[1], usr[3], usr[2], usr[4], col="cornsilk", border="black")
lines(try[,1], col="blue")
axis(2,col.axis="blue",,at=pretty(try[,1]),las=1,labels=sprintf("$%1.0f",pretty(try[,1]/1000)),cex.axis=.75)
axis.Date(1, at=pretty(adates), label=format(pretty(adates),"%y"))
box()
title(main="This is a graph", font.main=4, col.main="red",xlab="Date",ylab="$ (in $1000s)")
Forgetting all the other bits of code, take a look at
plot(try[,1],x=adates,type="o",axes=FALSE, ann=FALSE)
The first argument to plot is the vector x-coordinates, which in this case is try[,1]. You then provide another set of x-coordinates with x=adates. So now you have two sets of x-coords but no y-coords.