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.
Related
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))
So I have made a plot in R, with a lot of different colors indicating which of my 23 categories a point belongs to. The colors of points are added through a vector (stratumcol, which is a factor with 23 levels).
When I add the legend, trying to let that show the colors and their category, it seems they do not match (tested using ordihull, see picture below).
This is my plot code:
plot(pca_nmdsscores, type = "n")
points(pca_nmdsscores, col=stratumcol, cex=1.5, pch = 15)
legend("right","top",levels(stratumcol),cex=.8, col = as.numeric(stratumcol), pch =15, lty = 0) # pch = stratumcol
ordihull(pca_nmdsscores, groups = stratumcol,draw = "polygon", col ="purple",label = T, show.groups = "LateMoistRich")
ordihull(pca_nmdsscores, groups = stratumcol,draw = "polygon", col ="blue",label = T, show.groups = "MidWetPoor")
Here my Rplot should be visible. As you can see, my category "MaleMoistRich" connects the points with the pink-ish color, but in the legend this color is named "MidMoistRich".
The same for "MidWetPoor", connecting the mid-blue points, in the legend this color refers to "LateMoistPoor".
How do I solve this problem?
I tried looking for solutions, but didn't come across any that could solve it - including "unique" (which doesn't change anything, since my palette has been defined with 23 colors, so no need to recycle those anyway)
[Plot from R, showing legend and points color][1]
Ok - so since I'm a newbie I can't upload an image of my plot...
But see it here instead: http://i.stack.imgur.com/pzn2y.png
/thanks
Edit:
The solution was to not use levels() on my factor! Not in legend = levels(stratumcol), nor in col = levels(stratumcol). Richard and DeveauP suggested levels might be the problem.
This created a new problem: my legen displayed the whole factor, not just the levels in it (but the colors corresponded to the correct point colors, which was the original problem).
this new problem was solved by using "unique()" instead of "levels()".
legend("Right","top",legend=unique(stratumcol), cex=.8, col = unique(stratumcol), pch=15, lty=0)
I found a solution
Try
legend("right","top",legend = levels(stratumcol),cex=.8, col = levels(stratumcol), pch =15, lty = 0)
So I am trying to add some graphs to my notes of different functions.
Below is a simple interest function that gives the accumulated value of 1$ at time t with interest rate i. When I plot it, the initial function avSimple(0.075,t) looks fine but the addition ploted lines from the lines command plots the lines red & blue lines one unit to the right.
But they should all have a common point at t = 0, AV = 1.
What is going on here? I'm fairly new to this so I hope this isn't a dumb question.
# AV Simple Interest
avSimple = function(i,t){
av = (1 + (i * t))
return(av)}
t = 0:50
plot(t,avSimple(0.075,t), type="l", main = "AV Simple Interest",
xlab = "Time", ylab = "AV") # This plots good
lines(avSimple(0.05,t), col = "red") #This is shifted to right
lines(avSimple(0.025,t), col = "blue") #This is also shifted right
When using lines you should specify both the x and y values. If you only specify one value, R will assume those are y values and will set x=seq_along(y) (which will start at 1). You should be doing
t = 0:50
plot(t,avSimple(0.075,t), type="l", main = "AV Simple Interest",
xlab = "Time", ylab = "AV") # This plots good
lines(t, avSimple(0.05,t), col = "red") #This is shifted to right
lines(t, avSimple(0.025,t), col = "blue")
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.
Is there a way to draw the lines in such a way that they would start on the side of the points, or allow the symbols to be in foreground?
My solution was to make the symbols bigger and more visible.
Edit 1: it's for plot {graphics} of the R program.
Edit 2: the code per popular request.
legend(2,.4,bty='n', c('sugar','citrus','none'), pch=c('s','c','u'), pt.bg='white',lty= c(1,2,3), lwd=1.5, title="Condition",pt.cex=c(1.5),cex=1.5)
Edit 3: This is solved for plot(type='b') but somehow not for legend.
Thanks for reading!
The only thing I can come up with is to manually finagle the dash lengths until they end up looking the way you want them. For instance, this:
> plot(1,1)
> legend(c("A", "B"), col = 1:2, x = 1, y = .8, lty="99", pch=1:2)
produces the image below.
The lty parameter allows you to specify the lengths of lines and dashes as hex characters. In this case, it's saying to create a line of length 9 then create a space of length 9 then repeat. It looks like 9 is about the best fit to space around a normal pch symbol.
Note that you'd probably need to adjust this depending on the size of the image, symbol, etc. My advice ultimately would be to export the image from R and touch up the image to meet your needs in graphic editing software.
Going with the suggestion by #JeffAllen, here is a way to get what I think you might want. It requires modifying the legend() function to return the position of the points (these are given by x1 and y1 in body(legend)[[46]]).
legend2 <- legend
body(legend2)[[49]] <- quote(
invisible(list(rect = list(w = w, h = h, left = left, top = top),
text = list(x = xt, y = yt), points = list(x = x1, y = y1)))
)
Make a plot:
plot(-100:100, -100:100, type = "b")
While drawing the legend, draw white circles (pch = 21 with pt.bg = 'white') over the lines, and assign the values invisibly returned by legend2() to an object. Note also the changes to pt.lwd and pt.cex.
myLegend <- legend2(1, .8, bty = 'n', c('sugar','citrus','none'), pch = 21,
pt.bg = 'white', pt.lwd = 0, lty = c(1, 2, 3), lwd = 1.5, title = "Condition",
pt.cex = c(1.8), cex = 1.5)
Finally, draw the characters you'd like to use in the legend using points(), supplying the x and y values from the object myLegend.
points(myLegend$points$x, myLegend$points$y, pch = c('s','c','u'), cex = 1.5)
And this should get you something like:
You could also use the filled points offered by R (pch=21:25) and specify the fill color using pc.bg which gets passed to the points call when creating a legend.
plot(1,1)
legend(c("A", "B"), col = 1:2, x = 1, y = .8, lty=1, pt.bg=1:2, pch=21:22)
generates the following: