I have created this data frame:
seq(1,70)
Group <-paste("a", 1:70, sep="")
Counts <- c(1:18, 5:14, 1:20, 5:20, 10:15)
When plotted, it returns a large plot where "Group" does not fit:
barplot(Counts, names.arg=Group,
horiz=TRUE, las=1, cex.names=0.6, border=NA,
ylim=c(0,30), xlim=c(0,20), width = 1.5)
EDIT: this is the plot after deleting ylim=c(0,30)
I would like to be able to see each term on the "Group" axis.
The ylim argument is constraining how many groups are shown. Remove it and you can see all of them.
I tried:
barplot(stage1_90$Percentage.stage1,
names.arg=stage1_90$miR.stage1,
horiz=TRUE, las=1, cex.names=0.5, border=NA,
ylim=c(0,125), xlim=c(0,14), main = "Stage 1. Top 90%",
xlab = "% total expression", space = 1, yaxs = "i")
And then I printed out in A4 format
Related
I have data sets containing daily precipitation and discharge data. Now I would like to plot everything in one plot. All data sets are of length 61, so they can share the same x axis. The discharge data should be plotted the "normal" way, meaning that the y axis starts at the bottom and is placed on the left side. The precipitation data should be plotted "from the top", meaning that the y axis is reversed and placed on the right side.
Here is some code for a minimal reproducible example:
precipitation <- runif(61, min=0, max=25)
discharge <- runif(61, min=370, max=2610)
The result should approximately look like this:
Anybody with an idea how to achieve this?
EDIT: thanks pascal for the answer that implies the usage of ggplot2.
I also found a way by myself to do it with Base R, in case it could help anybody in the future:
precipitation <- runif(61, min=0, max=25)
discharge <- runif(61, min=370, max=2610)
# plot with Base R
par(mar = c(5, 5, 3, 5), xpd = TRUE)
plot(precipitation, type= "l", ylim= c(0,80), ylab= "Precipitation [mm/day]", main= "Comparison",
xlab= "Day", col= "blue")
par(new = TRUE)
plot(discharge, type= "l", xaxt = "n", ylim= rev(c(0,5000)), yaxt = "n", ylab = "", xlab = "", col= "red", lty= 2)
axis(side = 4)
mtext("Discharge [m³/s]", side = 4, line = 3)
The ggplot2 way looks a bit fancier of course.
ggplot2 can be used to make plots with a second, inverted axis. One has to specify sec.axis in scale_y_continuous(). I'm using a transformation ((100-x)*100) for your data and apply it to the axis as well, so that it fits. This can be changed to any numbers.
ggplot() +
geom_line(aes(y=precipitation, x=1:61), col="orange") +
geom_line(aes(y=100-discharge/100, x=1:61), col="blue") +
scale_y_continuous(name="rain", sec.axis=sec_axis(~(100-.)*100, name= "discharge"))
This is a follow-up question to my other question on barplots:
Tornado plot in R
I realized the question about getting greek letters on the y-axis needed to be asked as an own question.
The question is:
I have the following barplot and need to change the y-axis to respective greek letters (and a V with a bar over).
I use the following code:
# Tornado plot
data <- matrix(c(-0.02,0.02,-0.01,0.01,-0.03,0.02,-0.01,0.04), ncol = 4)
rownames(data) <- c('+10%','-10%')
colnames(data) <- c('V_bar', 'alpha', 'rho','xi')
x <- seq(-0.04,0.04, length=10)
barplot(data[1,], horiz = T, las=1, xlim = c(-0.04,0.04), xaxt='n', ylab='',
beside=T, col=c('springgreen'))
barplot(data[2,], horiz = T, las=1, xlim = c(-0.04,0.04), xaxt='n',
yaxt='n', #To prevent double printing of y-labels.
beside=T, col=c('indianred2'), add = TRUE)
axis(1, at=pretty(x), lab=paste0(pretty(x) * 100," %"), las=TRUE)
To get the greek letters I have tried the following:
barplot(data[2,], horiz = T, las=1, xlim = c(-0.04,0.04), xaxt='n',
yaxt= c(expression(bar(V)), expression(alpha),expression(rho), expression(xi)),
beside=T, col=c('indianred2'), add = TRUE))
and
axis(2, at=c(1:4), lab = expression(xi ~ rho ~ alpha ~ bar(V)), las=T)
or
axis(2, at=pretty(x), lab = paste0(expression(xi ~ rho ~ alpha ~ bar(V)), las=T))
But no success. Anyone now the trick?
Note. I have seen this question: Adding greek character to axis title
But it focuses on the labels, not the y-axis "values".
Also, I have tried something like Putting greek letters in column names
with no success.
There's no need to call axis for labeling of the bars if you provide the argument names.arg to barplot:
barplot(data[1,], horiz = T, las=1, xlim = c(-0.04,0.04), xaxt='n', ylab='',
beside=T, col=c('springgreen'),
names.arg=c(expression(xi),expression(rho), expression(alpha), expression(bar(V))))
You just need to pass lab in axis as a vector of expressions.
axis(2, at=c(1:4), lab = c(expression(xi),
expression(rho), expression(alpha), expression(bar(V))), las=T)
Then you can play with the settings of the axis as needed.
I am very new to R, so I'm struggling here a bit and I haven't found an answer to my problem.
I'm trying to produce a simple bar-chart in R, and I have set my x-axis variable labels to be vertical, using las=2. I then changed the margins for the barplot so that the labels would not overlap the xlab label, using par(mar=c(20,15,5,3)) and par(mgp=c(6,1,0)).
I would like to add a legend to this, but the one I have has adopted the margin dimensions of the graph itself, so that it appears too big and does not fit. I tried using cex but that only affects the text in the legend. Is there anyway for me to change the legend margins (or the graph margins) independently?
Here's what I have coded:
par(mar=c(20,15,5,3))
par(mgp=c(6,1,0))
par(xpd=TRUE)
barplot(
names.arg=c("Africa", "Central America, South America, Caribbean",
"Middle East", "Central and Eastern Europe",
"South and East Asia"),
cex.names=0.8, las=2, t(YLL),
ylab="Percentage (%)", ylim=c(0,100), main="", beside=TRUE,
col= c("green4", "orange"),xlab="Regions", mar=c(20,15,5,3)
)
legend(
10, 100,
legend=c("Communicable diseases", "Communicable diseases"),
fill= c("green4", "orange"), cex=0.7
)
I will really appreciate the help, thanks.
You can also use the arguments of legend function: y.intersp, x.intersp and text.width for reduce the size of the legend.
Here an example:
set.seed(55) # Set the seed of R‘s random number generator
x <- 1:10
y <- runif(10, min=0, max=100) # Generating random numbers
z <- runif(10, min=0, max=100) # Generating random numbers
plot(x,y, type="l", ylim=c(0,100), ylab="y and z")
par(new=TRUE)
plot(x,z, type="l", col="red", ylim=c(0,100), ylab=NA, xaxt='n', yaxt='n')
legend("topright", c("y","z"), lty="solid", col=c("black", "red"))
And same code modifiying the legend function:
set.seed(55) # Set the seed of R‘s random number generator
x <- 1:10
y <- runif(10, min=0, max=100) # Generating random numbers
z <- runif(10, min=0, max=100) # Generating random numbers
plot(x,y, type="l", ylim=c(0,100), ylab="y and z")
par(new=TRUE)
plot(x,z, type="l", col="red", ylim=c(0,100), ylab=NA, xaxt='n', yaxt='n')
legend("topright", c("y","z"), lty="solid", col=c("black", "red"), y.intersp=0.5,x.intersp=0.5,text.width=0.1)
I don't know if I understood your problem correctly, but maybe you can try x.intersp or y.intersp to modify the spacing in the x and y axis of your legend. For example, you could add x.intersp=0.5 to bring the elements of your legend closer in the x axis.
If this does not work and you provide a screenshot, maybe I could try to help you better.
Is it possible to rearrange the legend of the following plot
plot(1,1, type="n")
legend("topleft", c("1", "2"), col=c("darkblue", "darkred"), pch = 1, bty = "n", horiz = T, lwd=1.25, cex=1.8)
to look like this ("point-line-point" pattern)?
Usually, if you want this level of control over plot elements, you'll have to do it manually with primitives (points(), lines()/segments(), text(), etc.) and careful calculations from the plot parameters (e.g. par('usr')). It's not easy. Here's an example of how this could be done:
point.line.point <- function(x1,y1,x2=x1,y2=y1,...) {
points(c(x1,x2),c(y1,y2),...);
segments(x1,y1,x2,y2,...);
};
legend.plp <- function(x,y,labels,col,linewidth=diff(par('usr')[1:2])/10,textgap=diff(par('usr')[1:2])/20,...) {
comb <- cbind(labels,col);
xc <- x;
for (i in seq_len(nrow(comb))) {
x2 <- xc+linewidth;
point.line.point(xc,y,x2,col=comb[i,'col'],...);
text(x2+textgap,y,comb[i,'labels'],...);
xc <- x2+textgap*1.5+strwidth(comb[i,'labels']);
};
};
plot(1,1,type="n");
legend.plp(par('usr')[1]+diff(par('usr')[1:2])/20,par('usr')[4]-diff(par('usr')[3:4])/20,1:2,c('darkblue','darkred'),font=2,cex=1.5);
Here is an alternative solution that is the opposite of elegant. It involves embedding a couple of plots (one per legend), and a great deal of manual manipulation (to set the 'legends' where you want them to be):
library(Hmisc)
data(mtcars)
#plots the one in blue
plot(mtcars$cyl, type="o", col="darkblue")
#plots the one in red
lines(mtcars$carb, type="o", col="darkred")
#name the legends
text(6.5,7, "Cyl", font=2)
text(14,7, "Carb", font=2)
#add the subplots, it's actually a normal plot wrapped around the subplot with the x and y positions
subplot(plot(c(1,0),c(1,1), xlab=NA, ylab=NA, xaxt="n", yaxt="n", col="darkblue", type="o", axes=FALSE), 3, 7)
subplot(plot(c(1,0),c(1,1), xlab=NA, ylab=NA, xaxt="n", yaxt="n", col="darkred", type="o", axes=FALSE), 10, 7)
That yields the following plot:
I have combined two data sets into one graph and I would like to add the corresponding pch symbols right into the axis labels.
Now, I know that solutions using text() instead of xlab and ylab and Hershey vector fonts (instead of citing a pch=16, etc.) are given here and here but the symbols appear kinda wonky-shaped. Does anyone have a more "well-rounded" solution?
thinkoholic.com's reproducible example,
par(mar=c(5,5,2,5))
# create data and plot circles
x <- seq(0,5,0.5)
y <- seq(0,5,0.5)
plot(x,y, xlab="", ylab="")
#create random data and add bullets (pch=19)
x <- rnorm(20,2.5)
y <- rnorm(20,2.5)
points(x,y, pch=19)
#add y axis on right side
axis (side = 4)
#create text with symbols
text(-1,2.5,"\\#H0850 y1 axis text", vfont=c("sans serif","plain"), cex=1.25, adj=0.5, srt=90, xpd=TRUE)
text(6,2.5,"\\#H0902 y2 axis text", vfont=c("sans serif","plain"), cex=1.25, adj=0.5, srt=90, xpd=TRUE)
text(2.5,-1,"x axis text", vfont=c("sans serif","plain"), cex=1.25, adj=0.5, srt=0, xpd=TRUE)
If you insist on doing this:
par(mar=c(5,5,2,5), xpd=TRUE)
x <- seq(0,5,0.5)
y <- seq(0,5,0.5)
plot(x,y, xlab="", ylab="")
text(-1,2.5,"y axis text", cex=1.25, adj=0, srt=90)
points(-1,2.4)
This should work:
mtext(paste0("your label text", " (", intToUtf8(9679), ")"), side = 2, line=2.5)