Draw vertical ending of error bar line in dotplot - r

I am drawing dotplot() using lattice or Dotplot() using Hmisc. When I use default parameters, I can plot error bars without small vertical endings
--o--
but I would like to get
|--o--|
I know I can get
|--o--|
when I use centipede.plot() from plotrix or segplot() from latticeExtra, but those solutions don't give me such nice conditioning options as Dotplot(). I was trying to play with par.settings of plot.line, which works well for changing error bar line color, width, etc., but so far I've been unsuccessful in adding the vertical endings:
require(Hmisc)
mean = c(1:5)
lo = mean-0.2
up = mean+0.2
d = data.frame (name = c("a","b","c","d","e"), mean, lo, up)
Dotplot(name ~ Cbind(mean,lo,up),data=d,ylab="",xlab="",col=1,cex=1,
par.settings = list(plot.line=list(col=1),
layout.heights=list(bottom.padding=20,top.padding=20)))
Please, don't give me solutions that use ggplot2...

I've had this same need in the past, with barchart() instead of with Dotplot().
My solution then was to create a customized panel function that: (1) first executes the original panel function ; and (2) then uses panel.arrows() to add the error bar (using a two-headed arrow, in which the edges of the head form a 90 degree angle with the shaft).
Here's what that might look like with Dotplot():
# Create the customized panel function
mypanel.Dotplot <- function(x, y, ...) {
panel.Dotplot(x,y,...)
tips <- attr(x, "other")
panel.arrows(x0 = tips[,1], y0 = y,
x1 = tips[,2], y1 = y,
length = 0.15, unit = "native",
angle = 90, code = 3)
}
# Use almost the same call as before, replacing the default panel function
# with your customized function.
Dotplot(name ~ Cbind(mean,lo,up),data=d,ylab="",xlab="",col=1,cex=1,
panel = mypanel.Dotplot,
par.settings = list(plot.line=list(col=1),
layout.heights=list(bottom.padding=20,top.padding=20)))

Related

Move title of plots in a list of plots in R

I have a list of plots that I have assigned names to, and then converted to plot titles as suggested by https://stackoverflow.com/a/14790376/9335733. The titles happen to appear over the top x-axis title and so I attempt to move them as suggested here: https://stackoverflow.com/a/44618277/9335733. The overall code looks as follows:
lapply(names(Cast.files), function (x) plot(Cast.files[[x]],
main = x,
adj = 0, #adjust title to the farthest left
line =2.5 #adjust title up 2.5
)
)
It should be noted that plot is now converted from base R to the oce package for analyzing oceanographic data, but calls the same arguments from base R plot.
The problem becomes that in trying to move the title, the axis labels move as well and overlap. Any suggestions?
Edit: Here is what the image looks like before:
And after:
You might also want to look into the oma= argument in par(), which provides an "outer" margin which can be used to put a nice title. Something like:
library(oce)
data(ctd)
par(oma=c(0, 0, 1, 0))
plot(ctd)
title('Title', outer=TRUE)
This was solved by adding a title argument outside of the plot function as follows:
lapply(names(Cast.files), function (x) plot(Cast.files[[x]],
which = c("temperature", "salinity", "sigmaT","conductivity"),
Tlim = c(11,12),
Slim = c(29,32),
col = "red")
+ title(main = x, adj = 0.48, line = 3.5)#adding the titles at a specific location
)
This allowed for plots that looked like:
If you use the title function, rather than setting main within plot, it would allow you to change the line without affecting anything else in the plot.

R-package beeswarm generates same x-coordinates

I am working on a script where I need to calculate the coordinates for a beeswarm plot without immediately plotting. When I use beeswarm, I get x-coordinates that aren't swarmed, and more or less the same value:
But if I generate the same plot again it swarms correctly:
And if I use dev.off() I again get no swarming:
The code I used:
n <- 250
df = data.frame(x = floor(runif(n, 0, 5)),
y = rnorm(n = n, mean = 500, sd = 100))
#Plot 1:
A = with(df, beeswarm(y ~ x, do.plot = F))
plot(x = A$x, y=A$y)
#Plot 2:
A = with(df, beeswarm(y ~ x, do.plot = F))
plot(x = A$x, y=A$y)
dev.off()
#Plot 3:
A = with(df, beeswarm(y ~ x, do.plot = F))
plot(x = A$x, y=A$y)
It seems to me like beeswarm uses something like the current plot parameters (or however it is called) to do the swarming and therefore chokes when a plot isn't showing. I have tried to play around with beeswarm parameters such as spacing, breaks, corral, corralWidth, priority, and xlim, but it does not make a difference. FYI: If do.plot is set to TRUE the x-coordinates are calculated correctly, but this is not helpful as I don't want to plot immediately.
Any tips or comments are greatly appreciated!
You're right; beeswarm uses the current plot parameters to calculate the amount of space to leave between points. It seems that setting "do.plot=FALSE" does not do what one would expect, and I'm not sure why I included this parameter.
If you want to control the parameters manually, you could use the functions swarmx or swarmy instead. These functions must be applied to each group separately, e.g.
dfsplitswarmed <- by(df, df$x, function(aa) swarmx(aa$x, aa$y, xsize = 0.075, ysize = 7.5, cex = 1, log = ""))
dfswarmed <- do.call(rbind, dfsplitswarmed)
plot(dfswarmed)
In this case, I set the xsize and ysize values based on what the function would default to for this particular data set. If you can find a set of xsize/ysize values that work for your data, this approach might work for you.
Otherwise, perhaps a simpler approach would be to leave do.plot=TRUE, and then discard the plots.

How do I exclude parameters from an RDA plot

I'm still relatively inexperienced manipulating plots in R, and am in need of assistance. I ran a redundancy analysis in R using the rda() function, but now I need to simplify the figure to exclude unnecessary information. The code I'm currently using is:
abio1516<-read.csv("1516 descriptors.csv")
attach(abio1516)
bio1516<-read.csv("1516habund.csv")
attach(bio1516)
rda1516<-rda(bio1516[,2:18],abio1516[,2:6])
anova(rda1516)
RsquareAdj(rda1516)
summary(rda1516)
varpart(bio1516[,2:18],~Distance_to_source,~Depth, ~Veg._cover, ~Surface_area,data=abio1516)
plot(rda1516,bty="n",xaxt="n",yaxt="n",main="1516; P=, R^2=",
ylab="Driven by , Var explained=",xlab="Driven by , Var explained=")
The produced plot looks like this:
Please help me modify my code to: exclude the sites (sit#), all axes, and the internal dashed lines.
I'd also like to either expand the size of the field, or move the vector labels to all fit in the plotting field.
updated as per responses, working code below this point
plot(rda,bty="n",xaxt="n",yaxt="n",type="n",main="xxx",ylab="xxx",xlab="xxx
Overall best:xxx")
abline(h=0,v=0,col="white",lwd=3)
points(rda,display="species",col="blue")
points(rda,display="cn",col="black")
text(rda,display="cn",col="black")
Start by plotting the rda with type = "n" which generates an empty plot to which you can add the things you want. The dotted lines are hard coded into the plot.cca function, so you need either make your own version, or use abline to hide them (then use box to cover up the holes in the axes).
require(vegan)
data(dune, dune.env)
rda1516 <- rda(dune~., data = dune.env)
plot(rda1516, type = "n")
abline(h = 0, v = 0, col = "white", lwd = 3)
box()
points(rda1516, display = "species")
points(rda1516, display = "cn", col = "blue")
text(rda1516, display = "cn", col = "blue")
If the text labels are not in the correct position, you can use the argument pos to move them (make a vector as long as the number of arrows you have with the integers 1 - 4 to move the label down, left, up, or right. (there might be better solutions to this)

abline will not put line in correct position

I am quite new to programming/R and I'm having a very unusual problem. I've made a scatterplot and I would like to simply put the x y axis at 0 on the plot. However, when I use abline they are slightly off. I managed to get them to 0 using trial and error, but trying to plot other lines becomes impossible.
library('car')
scatterplot(cost~qaly, reg.line=FALSE, smooth=FALSE, spread=FALSE,
boxplots='xy', span=0.5, xlab="QALY", ylab="COST", main="Bootstrap",
cex=0.5, data=scat2, xlim=c(-.05,.05), grid=FALSE)
abline(v = 0, h = 0)
This gives lines which are slightly to the left and below 0.
here is an image of what this returns:
(I can't post an image since I'm new apparently)
I found that these values put the lines on 0:
abline(v=0.003)
abline(h=3000)
Thanks in advance for the help!
Using #Laterow's example, reproduce the issue
require(car)
set.seed(10)
x <- rnorm(1000); y <- rnorm(1000)
scatterplot(y ~ x)
abline(v=0, h=0)
scatterplot seems to be resetting the par settings on exit. You can sort of check this with locator(1) around some point, eg, for {-3,-3} I get
# $x
# [1] -2.469414
#
# $y
# [1] -2.223922
Option 1
As #joran points out, reset.par = FALSE is the easiest way
scatterplot(y ~ x, reset.par = FALSE)
abline(v=0, h=0)
Option 2
In ?scatterplot, it says that ... is passed to plot meaning you can use plot's very useful panel.first and panel.last arguments (among others).
scatterplot(y ~ x, panel.first = {grid(); abline(v = 0)}, grid = FALSE)
Note that if you were to do the basic
scatterplot(y ~ x, panel.first = abline(v = 0))
you would be unable to see the line because the default scatterplot grid covers it up, so you can turn that off, plot a grid first then do the abline.
You could also do the abline in panel.last, but this would be on top of your points, so maybe not as desirable.

Error bar ticks |--o--| don't draw for more then three conditions in dotplot

This question is an unexpected follow-up from Draw vertical ending of error bar line in dotplot. While the quoted question was succesfully resolved - there is a caveat. When I introduce more then three conditions to dotplot it doesn't want to draw the vertical ticks |--o--| in the endings of error bars.
As #Josh suggested in the comments, I injected browser() into first line of function that draws updated panel.Dotplot to see what goes wrong, but it didn't come out with anything that helps me to solve it. Here is an example code for four-conditions Dotplot() with updated panel.Dotplot function that doesn't work. It will work, if you decrease number of conditions (check answer for the question quoted above):
require(Hmisc)
#Fake conditions
mean = c(1:18)
lo = mean-0.2
up = mean+0.2
name = c("a","b","c")
cond1 = c("A","B","C")
cond2 = c(rep("E1",9),rep("E2",9))
d = data.frame (name = rep(name,6), mean, lo, up,
cond1=rep(cond1,each=3,times=2), cond2)
# Create the customized panel function
mypanel.Dotplot <- function(x, y, ...) {
panel.Dotplot(x,y,...)
tips <- attr(x, "other")
panel.arrows(x0 = tips[,1], y0 = y,x1 = tips[,2],
y1 = y,length = 0.1, unit = "native",
angle = 90, code = 3)
}
#Draw Dotplot - `panel.Dotplot` doesn't change anything
setTrellis()
Dotplot(name ~ Cbind(mean,lo,up) | cond1 * cond2, data=d, ylab="", xlab="",col=1,
panel = mypanel.Dotplot)
The error bars are in fact being rendered, but are not visible due to their very short length (± 0.2 units). Increasing the error to ± 1 results in the following (I've also increased the length specified in panel.arrows - i.e. the error bar cap length - to 0.5):
If your true data is so precise relative to the range of x-values then you might want to consider smaller points (so they aren't as prone to obscuring the error bars) or a layout that exaggerates the x axis. For example, the following uses your original error of ± 0.2 units, and your original arrow cap length of 0.1:
Dotplot(name ~ Cbind(mean,lo,up) | cond1 * cond2, data=d, ylab="", xlab="",
col=1, panel = mypanel.Dotplot, pch=20, cex=0.4, layout=c(1, 6), strip=FALSE,
strip.left=strip.custom(par.strip.text=list(cex=0.75), bg=0, fg=0))

Resources