In R is there a way to have titles for side 3 (top) = x2 and side 4 (right) = y2 like highlighted below?
Below is R code.
x<-1:4; y=x*x
plot(x, y, pch=18, col="red", type="b",
frame=FALSE, xaxt="n") # Remove x axis
axis(1, 1:4, LETTERS[1:4], col.axis="blue")
axis(3, col = "darkgreen", lty = 2, lwd = 0.5)
axis(4, col = "violet", col.axis = "dark violet", lwd = 2)
You can add labels to additional axes using mtext(). For the right y axis you will probably need to add extra space using par(mar = ...)
par(mar = c(5, 4, 4, 5)) # create extra space for label
plot(1:5)
axis(3)
axis(4)
mtext("top xaxis", side = 3, line = 2)
mtext("right y axis needs extra space", side = 4, line = 2)
Created on 2022-11-08 with reprex v2.0.2
Related
par(mfrow=c(1,2)) #Plot the two bar charts together
par(mar = c(4, 7, 1, 1)) # Adjust the margins on the four sides of the plot
barplot(height = table(s50_1995$Smoking_status),
main = "Smoking status ", xlab = "", ylab = "", font.lab = 2, col.lab = "Red", cex.lab = 1.5, xlim=c(0,40) ,col = 1:3, horiz = TRUE, las = 2)
# Plot the bar chart indicating the title,the color,
#size and font of the label, the correct x limits,the colors
#for the bars and set the y-axis labels perpendicular to the y axis
mtext("Smoking Status", side=2, line=6) #Set the label for the y axis
mtext("Number of Pupils", side=1, line=2) #Set the label for the x axis
par(mar = c(4, 7, 1, 3)) # Adjust the margins on the four sides of the plot
barplot(height = table(s50_1995$Sport_participation),
main = "Sport participation ",
xlab = "", ylab = "",
font.lab = 2, col.lab = "Red",
cex.lab = 1.5,
xlim=c(0,40) ,
col = 1:3, horiz = TRUE, las = 2)
mtext("Sport participation Status ", side=2, line=6)
mtext("Number of Pupils", side=1, line=2)
par(mfrow=c(1,2))
How do I put these bar charts further away from each other? They are way too close to each other right now
Using some dummy data. it's a balancing act between the allowance for the left margin for the second plot and the location of the axis title for the second plot.
In this case I've increased the size of the left margin in the call to par(mar...) for the second plot to 11 and reduced the mtext position to line 4.
Alternatively you could increase the size of the right margin for the left hand plot.
fruit1 <- c(apple = 40, kiwi = 15, grape = 30)
fruit2 <- c(apple = 20, kiwi = 5, grape = 40)
par(mfrow=c(1,2))
#optionally you could increase the value of the end value to increase the size of the right margin.
par(mar = c(4, 7, 1, 1))
barplot(fruit1,
col="blue",
horiz=TRUE,
las=1)
mtext("Fruit 1", side=2, line=6)
#this is the key line, adjust the second value to increase the gap between the charts
par(mar = c(4, 11, 1, 1))
barplot(fruit2,
col="green",
horiz=TRUE,
las=1)
mtext("Fruit 2", side=2, line=4)
Created on 2021-11-26 by the reprex package (v2.0.1)
I am trying to plot a dual y axis plot using the following code:
plot(dataset1, col="black", ylab="Height (ft)", main = "W7R001")
par(new = TRUE)
points(dataset5, col="red", pch = ".", xlab="", ylab="", axes = FALSE)
axis(side = 4)
mtext(side = 4, "Height (m)")
My issue now is that, on the secondary plot, the label of the secondary y axis lies on the secondary y axis values. How do I fix or avoid this?
You can shift the label on the second y-axis with the line parameter. You also need to increase the right margin of the plot.
par(mar=c(5, 4, 4, 4) + 0.1) #increase plot margins to the right
plot(x = 1:5, y = 1:5, xlab = "", ylab="LABEL")
axis(side = 4)
mtext(side = 4, "LABEL", line = 3) #shift position of the label
When adding ticks to a plot (more ticks than default), how does one get the grid() to align the grid to the ticks?
plot(1:10,las=1,xaxp = c(0, 10, 10),xlim=c(0,10), ylim=c(0,10))
grid(lwd=2, nx=10, ny=10)
Tried changed the xlim and different numbers for the nx arg in grid (number of cells), but the grid simply doesn't line up.
Related, but doesn't answer question: Aligning grid lines in R, bReeze package
Related, and uses workaround: Align grid with ticks
Is the workaround the most efficient option?
You could use abline to draw grids. You can specify where the grids should be with h (for horizontal lines) and v (for vertical lines)
#Plot
plot(1:10,las=1,xaxp = c(0, 10, 10),xlim=c(0,10), ylim=c(0,10))
#Add horizontal grid
abline(h = c(0,2,4,6,8,10), lty = 2, col = "grey")
#Add vertical grid
abline(v = 1:10, lty = 2, col = "grey")
Another workaround is to use axis where tck value is 1. With axis, you can specify where the grids should be with at
#Plot
plot(1:10,las=1,xaxp = c(0, 10, 10),xlim=c(0,10), ylim=c(0,10))
#Add horizontal grid
axis(2, at = c(0,2,4,6,8,10), tck = 1, lty = 2, col = "grey", labels = NA)
#Add vertical grid
axis(1, at = 1:10, tck = 1, lty = 2, col = "grey", labels = NA)
#Add box around plot
box()
The problem is that grid is putting nx grid lines in the user space, but plot is adding 4% extra space on each side. You can take control of this. Adding xaxs="i", yaxs="i" to your plot will turn off the extra space. But then your upper right point will be cut off, so you need to change the xlim and ylim values and change nx to match. Final code is:
plot(1:10,las=1,xaxp = c(0, 10, 10),xlim=c(0,11), ylim=c(0,11),
xaxs="i", yaxs="i")
grid(lwd=2, nx=11, ny=11)
The answer to your question
When adding ticks to a plot (more ticks than default), how does one get the grid() to align the grid to the ticks?
is:
Using function axis to obtain the x axis tick locations created by plot function in combination with abline
Concretely, you substitute the line
grid(lwd=2, nx=10, ny=10)
by the following three lines
x_ticks <- axis(1, 0:10, labels = FALSE)
grid(lwd = 2, ny = NULL, nx = NA)
abline(v = x_ticks, lwd = 2, lty = 3, col = "lightgray")
and the result will be
You can control both x ticks and y ticks and get rid of the grid function. In this case the 3 lines would be
x_ticks <- axis(1, 0:10, labels = FALSE)
y_ticks <- axis(2, labels = FALSE)
abline(v = x_ticks, h = y_ticks, lwd = 2, lty = 3, col = "lightgray")
I would vote for the workaround. Because if you look at manual from ?grid, it has this statement,
"Note: If more fine tuning is required, use ‘abline(h = ., v = .)’
directly."
With the ablineclip I can draw a straight line to any plot like:
ablineclip(h = 2, x1 = 0,x2 = 5,lty = 2, col = "green")
this draws a horizontal line where y=2 from x=0 to x=5.
How can I draw a line for a second y axis??
(meaning a horizontal line where y value on the right axis is 2).
I have no code yet, sorry for the non reproductive code.
Something like the following will work:
library(plotrix)
plot(1, type="n", xlim=c(-10,10), ylim=c(0,4))
ablineclip(h = 2, x1 = 0,x2 = 5,lty = 2, col = "green")
par(new=TRUE)
plot(1, type="n", xlim=c(-10,10), ylim=c(10,15), xaxt="n",yaxt="n",xlab="",ylab="")
axis(4)
ablineclip(h = 12, x1 = -4,x2 = 4,lty = 2, col = "red")
I am doing a plot with R, the code for stacked bar and axis 2 are simple, here is the code for line and axis 4:
lines(y,
theLineValues,
type = "o",
pch = 20,
lwd = 2,
cex = 1.2,
lty = 1,
col ="forestgreen")
axis(4,
at = getYaxis(0,1,0.01, 3), # function to get 3 values for axis
labels = getYaxis(0,1,0.01, 3),
col.axis= "forestgreen",
las = 1,
cex.axis= 0.7,
col = "forestgreen",
line = 0)
then I found the min and max value: 0.46, 0.68 , and want to use them as axis, so the changing of line can be seen more obviously(the red line).
labels = getYaxis(min(theLineValues),max(theLineValues),0.01,3),
How would I scale the 'theLineValues' to do this?
Thanks.
======================================================================
Update 1: the code for 'y':
y <- barplot(
combinedvalues, # it's list of 3-combined values.
col = c("slategray1","darkseagreen1","moccasin"),
beside = FALSE,
border = "grey80",
las = 1,
cex.axis= 1.0,
ann = FALSE,
ylim = c(0,1),
yaxt = "n")
======================================================================
Update 2: the combined values:
these values are in .csv file, and use the following to get the 'combinedvalues' and pass it to 'y':
rbind(csv$frame0,csv$frame1,csv$frame2)
# frame0+frame1+frame2 shoud be 1, theLineValues were calculated by some formulas.
the csv file:
frame0 frame1 frame2 theLineValues
------------------------------------------------------------
0.4460203874 0.2271394791 0.3268401336 0.4674583872
0.4473756948 0.2084173711 0.3442069341 0.4796977238
0.5296042291 0.1570493286 0.3133464423 0.570317484
0.5255498752 0.1234146373 0.3510354875 0.6095475721
0.5405768621 0.119299957 0.3401231808 0.6251561825
0.5657840709 0.0916650587 0.3425508703 0.6896446583
0.4826617968 0.0877739789 0.4295642243 0.6610089801
0.3588171226 0.122977733 0.5182051444 0.606129318
0.2608499204 0.1705417922 0.5686082874 0.595971676
0.2111782825 0.2040231107 0.5847986067 0.6057364576
0.1731616573 0.240909341 0.5859290016 0.6153720603
Thanks.
======================================================================
Update 3: the final plot:
Frames.txt is based on the three frame columns.
Data
frames <- read.table("/your-path/frames.txt",header=T,na.string="NA")
theLineValues<-c(0.4674583872, 0.4796977238, 0.570317484, 0.6095475721, 0.6251561825, 0.6896446583, 0.6610089801, 0.606129318, 0.595971676, 0.6057364576, 0.6153720603)
Plot
barplot(t(frames), , col = c("slategray1","darkseagreen1","moccasin"))
axis(2, ylim=c(0,1))
mtext("barplot values", side=2, line=2)
box()
par(new=TRUE)
plot(theLineValues, type = "l", pch = 20, xlab="", ylab="", col = "forestgreen", lwd=2, ylim=c(min(theLineValues), max(theLineValues)), axes=FALSE)
axis(4, ylim=c(min(theLineValues), max(theLineValues)))
mtext("lineValues", side=4, line=0.2)
box()