I have a problem labelling my matplot x-axis row. So I have 1388 instances, but I want my X-axis to a custom labeling in the form of a sequence in dates.
My R code looks like this:
Dates <- seq(as.Date("2004/01/29"), as.Date("2009/07/31"), by = "quarter")
matplot(seq(1388), t(Alldata[1, ]), type = "l",
lwd = 1, lty = 1, col = 1:10, xlab = "Dates", ylab = "Strike",
main = paste("TEST"), xaxt='n')
axis(side = 1:23, at=1, labels = paste(Dates, 1:23))
Can anybody help me get the Dates into the x-axis?
I have tried using same method as this: Change axis labels with matplot in R
but it doesn't work.
AllData is from an excel file in which the first number of rows looks like this:
I think you have confused the way the function axis works. In answering below I will generate a random matrix to replace your Alldata which I don't have access to
Alldata <- t(as.matrix(rnorm(23)))
We can generate the plot again:
matplot(seq(23), Alldata[1, ], type = "l",
lwd = 1, lty = 1, col = 1:10, xlab = "Dates",
ylab = "Strike", main = paste("TEST"), xaxt='n')
Now, its import to know what the arguments to axis are. First
side this is literally the side of the the rectangle on which the plot is drawn. It is one of the numbers 1, 2, 3, 4 corresponding to bottom, left, top, right, respectively.
You want the axis to be on the bottom so we set this to 1.
Next, the at argument, is for where the tick marks should be drawn. So if you have 10 points on your line, and you set this value to 1:10 it will draw a tick mark at each point on the axis. If you set it to c(2,4,6,8,10) it will draw a mark at every second point on the axis. In your case you've set it to 1, which would draw only one tick. Although since the side was set to 1:23 none showed up.
labels This argument will label the ticks which are drawn. Ideally it should be a vector the same length as the at value. You can make sure that they are the same length by creating an index variable and using this as the at variable and to index the labels.
This gets us to:
index <- c(1,7,14,21)
axis(side = 1, at = index, labels = paste(Dates, 1:23)[index])
I think having a full range of dates would look cluttered. But you can drop the index and choose the below if you prefer:
axis(side = 1, at = 1:23, labels = paste(Dates, 1:23))
Related
I have this plot that it's creating me some problems as I don't manage to plot the red line between CIs. This plot is the fifth of a series of plots that are identical in nature and code. Only in this case, the line doesn't show up. I can't figure it out why.
This is my dataset and code:
ap_pp = structure(list(appp = c(0.0534256470459521, 0.318338283911788,
0.510498594892796, 0.659918013907143, 0.847855923395071, 1.33512933449448,
1.79114871626335), LB_T = c(-0.0039953960988687, -0.00128119112255898,
1.231602663197e-05, 0.000409544070864543, 0.00117091129359269,
0.00719127778296817, 0.0141800410470155), UB_T = c(0.00506390903978775,
0.00764795680079474, 0.010197655871224, 0.0127888162072783, 0.0157862071743087,
0.0195113089069214, 0.0216429332782514), LB_T = c(-0.0039953960988687,
-0.00128119112255898, 1.231602663197e-05, 0.000409544070864543,
0.00117091129359269, 0.00719127778296817, 0.0141800410470155),
UB_T = c(0.00506390903978775, 0.00764795680079474, 0.010197655871224,
0.0127888162072783, 0.0157862071743087, 0.0195113089069214,
0.0216429332782514)), class = "data.frame", row.names = c(NA,
-7L))
plot(ap_pp$appp, ylim = range(c(ap_pp$LB_T, appp$UB_T)), xlab = "", ylab = "", main = "LSAP", type = "n", xaxt = "n")
axis(1, at = 1:7, labels = load_unscaled_m$Date)
with(ap_pp, polygon(c(xx,rev(xx)),c(LB_T,rev(UB_T)), col = "#FFA6AA", border = FALSE))
abline(h = 0, col = "black", lty = 2)
lines(ap_pp$appp, type = "o", lwd = 2, col = "red")
Can anyone help me?
Thanks
You have some issues:
Typo, you use appp$UB_T in the range(), which doesn't exist. You need ap_pp$UB_T
Range. The line data you are trying to plot has a minimum of 0.05:
range(ap_pp$appp)
[1] 0.05342565 1.79114872
However, you set the y-axis to have a maximum of 0.02:
range(c(ap_pp$LB_T, ap_pp$UB_T))
[1] -0.003995396 0.021642933
Since the maximum of your y axis, 0.0216, is less than the minimum of the data you are plotting, 0.0534, all the points you are trying to plot are "above" the graph.
Graph type. You say "line", but by default plot will plot points. If you want a line, use type = "l". (Or lines(), as you do later.)
I have no idea what xx is, so I don't know what's going on with your polygon code. But presumably the y limits are again defined by UB_T and LB_T, and so the maximum of the y axis is still lower than the minimum of the data in lines()
Duplicate column names are a bad idea. You have two columns named LB_T and two named UB_T. They appear to be identical, which is less bad than if they were different, but I would strongly suggest not using duplicate column names so there is no ambiguity about which column you are referring to.
Perhaps you should include ap_pp$ppp in the range call.
I was wondering if it's possible to get a two sided barplot (e.g. Two sided bar plot ordered by date) that shows above Data A and below Data B of each X-Value.
Data A would be for example the age of a person and Data B the size of the same person. The problem with this and the main difference to the examples above: A and B have obviously totally different units/ylims.
Example:
X = c("Anna","Manuel","Laura","Jeanne") # Name of the Person
A = c(12,18,22,10) # Age in years
B = c(112,186,165,120) # Size in cm
Any ideas how to solve this? I don't mind a horizontal or a vertical solution.
Thank you very much!
Here's code that gets you a solid draft of what I think you want using barplot from base R. I'm just making one series negative for the plotting, then manually setting the labels in axis to reference the original (positive) values. You have to make a choice about how to scale the two series so the comparison is still informative. I did that here by dividing height in cm by 10, which produces a range similar to the range for years.
# plot the first series, but manually set the range of the y-axis to set up the
# plotting of the other series. Set axes = FALSE so you can get the y-axis
# with labels you want in a later step.
barplot(A, ylim = c(-25, 25), axes = FALSE)
# plot the second series, making whatever transformations you need as you go. Use
# add = TRUE to add it to the first plot; use names.arg to get X as labels; and
# repeat axes = FALSE so you don't get an axis here, either.
barplot(-B/10, add = TRUE, names.arg = X, axes = FALSE)
# add a line for the x-axis if you want one
abline(h = 0)
# now add a y-axis with labels that makes sense. I set lwd = 0 so you just
# get the labels, no line.
axis(2, lwd = 0, tick = FALSE, at = seq(-20,20,5),
labels = c(rev(seq(0,200,50)), seq(5,20,5)), las = 2)
# now add y-axis labels
mtext("age (years)", 2, line = 3, at = 12.5)
mtext("height (cm)", 2, line = 3, at = -12.5)
Result with par(mai = c(0.5, 1, 0.25, 0.25)):
I have a horizontal barplot, with zero in the middle of the x-axis and would like the name for each bar to appear on the same side as the bar itself. The code I am using is:
abun<-data$av.slope
species<-data$Species
cols <- c("blue", "red")[(abun > 0)+1]
barplot(abun, main="Predicted change in abundance", horiz=TRUE,
xlim=c(-0.04,0.08), col=cols, names.arg=species, las=1, cex.names=0.6)
I have tried creating two separate axes and the names do appear on the desired side for each bar, but are not level with the appropriate bar. I will try and upload an image of the barplot, am still very new to R, apologies if I am missing something basic!
barplot1- names in correct position but all on one axis
barplot2- names on both sides of plot but not in line with appropriate bar
We can accomplish this using mtext:
generate data
Since you didn't include your data in the question I generated my own dummy data set. If you post a dput of your data, we could adapt this solution to your data.
set.seed(123)
df1 <- data.frame(x = rnorm(20),
y = LETTERS[1:20])
df1$colour <- ifelse(df1$x < 0, 'blue', 'red')
make plot
bp <- barplot(df1$x, col = df1$colour, horiz = T)
mtext(side = ifelse(df1$x < 0, 2, 4),
text = df1$y,
las = 1,
at = bp,
line = 1)
I want to create a graph in R using the image()-function. My x-axis has non-numerical subdivisions. The axis is divided like this: "Arctic Ocean" - "North Atlantic Ocean" - etc.
How can I add vertical lines to this axis in order to separate different groups on my axis using the abline(v = [value]) function?
This is the code I used to create the image (which works fine):
dev.new()
par(mar = c(9,9,1,1), bg = "grey90")
n.bins <- 24
image(log10(data.stand), col = colorRampPalette(blues9)(n.bins), xaxt = "n", yaxt = "n", useRaster = F)
axis(side = 2, at = 0:(n.taxa.data - 1) / (n.taxa.data - 1), labels = colnames(data.by.tax), las = 1)
axis(side = 1, at = 0:(n.iho.obis - 1) / (n.iho.obis - 1), labels = rownames(data.by.tax), las = 2, cex.axis = 0.5)
I tried implementing the vertical lines using the abline() function, but it doesn't appear on the figure.
Now my question is: how do I implement it correctly in this code? And how can I also make it appear in the figure?
Cheers!!
Since you didn't provide x and y arguments to image but only a z matrix, it took by default seq(0,1,nrow(z)) and seq(0,1,ncol(z)) as x and y values. So your vertical lines will have to be expressed in the [0,1] range. Let's say your 10 first columns out of 100 are one group then abline(v=.1) should do the trick. Of course it may be more convenient for you to declare a x and a y directly so you'll have better control on it.
I have a question regarding the command plot().
Is there a way to fully eliminate the x-axis and replace it with own values? I know that I can get rid of the axis by doing
plot(x,y, xaxt = 'n')
and then add an axis with
axis(side = 1 etc.)
However, when I add the axis, obviously it still refers to the data plotted as 'x'.
I would only like to plot the 'y'-values and add the x-axis my own in the sense of just "drawing" the x-axis with own values specified. Is there any way to do that?
The background of this question is that my two data frames differ in their length and therefore I cannot plot them.
Not sure if it's what you mean, but you can do this:
plot(1:10, xaxt = "n", xlab='Some Letters')
axis(1, at=1:10, labels=letters[1:10])
which then gives you the graph:
You could set labels = FALSE inside axis(...) and then print the labels in a separate command using text(...). This option would allow you to rotate the text in case you need it.
lablist<-as.vector(c(1:10))
axis(1, at=seq(1, 10, by=1), labels = FALSE)
text(seq(1, 10, by=1), par("usr")[3] - 0.2, labels = lablist, srt = 45, pos = 1, xpd = TRUE)
Detailed explanation here