Dotchart with secondary axis - r

I'm trying to produce a dotchart with a secondary axis on top. However once I plot the second dotchart (with a par(new=T)), I can't figure out how not to display the axis ticks over the previous ones in axis side=1. Here's my code with mock data:
y1_i <- c(2,8,2,14,2)
y2_i <- c(15,17,28,22,30)
y1_f <- c(4,9,11,16,7)
y2_f <- c(13,11,16,11,21)
y=c(y1_i,y2_i,y1_f,y2_f)
x <- c("AAEG","AALO","AGAM","ACHR","AALB")
y1=c(y1_i,y1_f)
y2=c(y2_i,y2_f)
dotchart(y1_i,labels=x,xlab="N50 length",xlim = c(0,max(y1)))
par(new=T)
dotchart(y2_i,labels=x,xlim = c(0,max(y2)))
axis(side=3)
Also, if possible, I would like to add a second data set which would be slightly pushed vertically above the first dataset (to not overlap it), but still corresponding to the same y-axis categories.
Thank you for any suggestion :)

Found it, by using dotchart2 from the Hmisc package
library(Hmisc)
y1_i <- c(2,8,2,14,2)
y2_i <- c(15,17,28,22,30)
y1_f <- c(4,9,11,16,7)
y2_f <- c(13,11,16,11,21)
y=c(y1_i,y2_i,y1_f,y2_f)
x <- c("AAEG","AALO","AGAM","ACHR","AALB")
y1=c(y1_i,y1_f)
y2=c(y2_i,y2_f)
y1_i <- c(2,8,2,14,2)
y2_i <- c(15,17,28,22,30)
y1_f <- c(4,9,11,16,7)
y2_f <- c(13,11,16,11,21)
y=c(y1_i,y2_i,y1_f,y2_f)
x <- c("AAEG","AALO","AGAM","ACHR","AALB")
y1=c(y1_i,y1_f)
y2=c(y2_i,y2_f)
dotchart2(y1_i,labels=x,xlab="N50 length",xlim = c(0,max(y1)))
par(new=T)
dotchart2(y2_i,labels=x,xlim = c(0,max(y2)),xlab="Scaffold number",lines=F,xaxis=F)
axis(side=3,xlab="Scaffold number")

Related

In R (rgl), how to print shadows of points in plot3d?

In R, using package rgl, I'd like to add the shadows of the points in plot3d(), just like in the image below.
I've added the bottom grid using grid3d(), but still have no clue on how to add the shadows. If I plot the same points changing the 3rd axis value to its minimum value (-100 in the image), the plot area automatically increases, leaving a gap between the points and the grid. Is there a better way to do that?
I think it was obvious from the question, but here is a sample code:
library(rgl)
df <- data.frame(x=rnorm(100),
y=rnorm(100),
z=rnorm(100))
plot3d(df)
grid3d('z')
The idea of setting z to the minimal value fails because rgl makes the bounding region slightly bigger. But you can grab the z value from the grid, and use that. You can also tell rgl not to expand the bounding box to include the new points. This code does both things:
library(rgl)
df <- data.frame(x=rnorm(100),
y=rnorm(100),
z=rnorm(100))
plot3d(df)
id <- grid3d('z') # Get id values for grid
gridz <- rgl.attrib(id[1], "vertices")[1,3] # Use the first z value
save <- par3d(ignoreExtent = TRUE) # Ignore points for bbox
with(df, points3d(x, y, gridz, col = "gray"))# Plot the "shadows"
par3d(save) # Restore bbox status
Here's what I get:
there is now the convenience show2d function available to produce the desired 2D projections
library(rgl)
df <- data.frame(x=rnorm(100),
y=rnorm(100),
z=rnorm(100))
plot3d(df)
grid3d('z')
show2d({
par(mar=c(0,0,0,0))
plot(x = df$x, y = df$y,
col = "black")
})

Retrieve facet labels from a ggplot or a gtable/gTree/grob/gDesc object

I have data I'm plotting using ggplot's facet_grid:
My data:
species <- c("spcies1","species2")
conditions <- c("cond1","cond2","cond3")
batches <- 1:6
df <- expand.grid(species=species,condition=conditions,batch=batches)
set.seed(1)
df$y <- rnorm(nrow(df))
df$replicate <- 1
df$col.fill <- paste(df$species,df$condition,df$batch,sep=".")
My plot:
integerBreaks <- function(n = 5, ...)
{
library(scales)
breaker <- pretty_breaks(n, ...)
function(x){
breaks <- breaker(x)
breaks[breaks == floor(breaks)]
}
}
library(ggplot2)
p <- ggplot(df,aes(x=replicate,y=y,color=col.fill))+
geom_point(size=3)+facet_grid(~col.fill,scales="free_x")+
scale_x_continuous(breaks=integerBreaks())+
theme_minimal()+theme(legend.position="none",axis.title=element_text(size=8))
which gives:
Obviously the labels are long and come out pretty messed up in the figure so I was wondering if there's a way edit these labels in the ggplot object (p) or the gtable/gTree/grob/gDesc object (ggplotGrob(p)).
I am aware that one way of getting better labels is to use the labeller function when the ggplot object is created but in my case I'm specifically looking for a way to edit the facet labels after the ggplot object has been created.
As I mentioned in the comments, the facet names are nested quite deeply within the gtable that ggplotGrob() gives you. However, this is still possible and since the OP explicitly wants to edit them after being plotted, you can do this with:
library(grid)
gg <- ggplotGrob(p)
edited_grobs <- mapply(FUN = function(x, y) {
x[["grobs"]][[1]][["children"]][[2]][["children"]][[1]][["label"]] <- y
return(x)
},
gg$grobs[which(grepl("strip-t",gg$layout$name))],
unique(gsub("cond","c", df$condition)),
SIMPLIFY = FALSE)
gg$grobs[which(grepl("strip-t",gg$layout$name))] <- edited_grobs
grid.draw(gg)
Note that this extracts all the strips using gg$grobs[which(grepl("strip-t",gg$layout$name))] and passes them to the mapply to be reset with the gsub(...) that OP specified in their comment.
In general, if you want to access just one of the text labels, there is a very similar structure which I made use of in my mapply:
num_to_access <- 1
gg$grobs[which(grepl("strip-t",gg$layout$name))][[num_to_access]][["grobs"]][[1]][["children"]][[2]][["children"]][[1]]$label
So to access the 4th label for example all you would need to do is change num_to_acces to be 4. Hope this helps!

How to adjust x labels in R boxplot

This is my code to create a boxplot in R that has 4 boxplots in one.
psnr_x265_256 <- c(39.998,39.998, 40.766, 38.507,38.224,40.666,38.329,40.218,44.746,38.222)
psnr_x264_256 <- c(39.653, 38.106,37.794,36.13,36.808,41.991,36.718,39.26,46.071,36.677)
psnr_xvid_256 <- c(33.04564,33.207269,32.715427,32.104696,30.445141,33.135261,32.669766, 31.657039,31.53103,31.585865)
psnr_mpeg2_256 <- c(32.4198,32.055051,31.424819,30.560274,30.740421,32.484694, 32.512268,32.04659,32.345848, 31)
all_errors = cbind(psnr_x265_256, psnr_x264_256, psnr_xvid_256,psnr_mpeg2_256)
modes = cbind(rep("PSNR",10))
journal_linear_data <-data.frame(psnr_x265_256, psnr_x264_256, psnr_xvid_256,psnr_mpeg2_256)
yvars <- c("psnr_x265_256","psnr_x264_256","psnr_xvid_256","psnr_mpeg2_256")
xvars <- c("x265","x264","xvid","mpeg2")
bmp(filename="boxplot_PSNR_256.bmp")
boxplot(journal_linear_data[,yvars], xlab=xvars, ylab="PSNR")
dev.off()
This is the image I get.
I want to have the corresponding values for each boxplot in x axis "x265","x264","xvid","mpeg2".
Do you have any idea how to fix this?
There are multiple ways of changing the labels for your boxplot variables. Probably the simplest way is changing the column names of your data frame:
colnames(journal_linear_data) <- c("x265","x264","xvid","mpeg2")
Even simpler: you could do this right at the creation of your data frame too:
journal_linear_data <- data.frame(x265=psnr_x265_256, x264=psnr_x264_256, xvid=psnr_xvid_256, mpeg2=psnr_mpeg2_256)
If you run into the problem of your labels not being shown or overlapping due to too few space, try rotating the x labels using the las parameter, e.g. las=2 or las=3.

Creating Hexbins with Dates in R hexbin()

I am trying to create hexbins where the x-axis is a date using the hexbin function in the hexbin package in R. When I feed in my data, it seems to convert the dates into a numeric, which gets displayed on the x-axis. I want it force the x-axis to be a date.
#Create Hex Bins
hbin <- hexbin(xData$Date, xData$YAxis, xbins = 80)
#Plot using rBokeh
figure() %>%
ly_hexbin(hbin)
This gives me:
Here's a brute force approach using the underlying grid plotting package. The axes are ugly; maybe someone with better grid skills than I could pretty them up.
# make some data
x = seq.Date(as.Date("2015-01-01"),as.Date("2015-12-31"),by='days')
y = sample(x)
# make the plot and capture the plot
p <- plot(hexbin(x,y),yaxt='n',xaxt='n')
# calculate the ticks
x_ticks_date <-
x_ticks <- axTicks(1, log = FALSE, usr = as.numeric(range(x)),
axp=c(as.numeric(range(x)) ,5))
class(x_ticks_date) <- 'Date'
y_ticks_date <-
y_ticks <- axTicks(1, log = FALSE, usr = as.numeric(range(y)),
axp=c(as.numeric(range(y)) ,5))
class(y_ticks_date) <- 'Date'
# push the ticks to the view port.
pushViewport(p$plot.vp#hexVp.off)
grid.xaxis(at=x_ticks, label = format(y_ticks_date))
grid.yaxis(at=y_ticks, label = format(y_ticks_date))

Stacked barplot is opposite order to legend?

A minor question about plotting stacked barplot in R.
The stacked bars represent the series bottom-to-top.
But the legend always shows the series top-to-bottom. I think that is also true with ggplot2::geom_bar
Is there any nicer idiom than using rev(...) twice inside either legend() or barplot() as in:
exports <- data.frame(100*rbind('Americas'=runif(6),'Asia'=runif(6),'Other'=runif(6)))
colnames(exports) <- 2004:2009
series_we_want <- c(1,2,3)
barplot( as.matrix(exports[series_we_want,]), col=mycolors, ...)
legend(x="topleft", legend=rev(rownames(exports)[series_we_want]), col=rev(mycolors) ...)
(If you omit one of the rev()'s the output is obviously meaningless. Seems like an enhance case for adding a single flag yflip=TRUE or yreverse=TRUE)
This is what I got using your code:
exports <- data.frame(100*rbind('Americas'=runif(6),'Asia'=runif(6),'Other'=runif(6)))
colnames(exports) <- 2004:2009
series_we_want <- c(1,2,3)
barplot( as.matrix(exports[series_we_want,]))
legend(x="topleft", legend=rev(rownames(exports)[series_we_want]))
try this:
exports <- data.frame(100*rbind('Americas'=runif(6),'Asia'=runif(6),'Other'=runif(6)))
colnames(exports) <- 2004:2009
series_we_want <- c(1,2,3)
test_data<-as.matrix(exports[series_we_want])
barplot( test_data,
legend.text=as.character(rev(rownames(exports)[series_we_want])),
args.legend = list(x="topleft"))
seems to produce the legend in the opposite order of what you have

Resources