Editing symbol attributes with R::grid - r

For grid practice purposes, I am trying to adjust the plot symbol. The idea is to connect min/max values with a vertical line, and give both symbols & line the same color fill without visible outline.
I've figured out most steps. My problem is with removing the symbol outline and changing the symbol.
library(grid)
n <- 10
mins <- 10*runif(n)
maxs <- mins + 5*runif(n)
grid.newpage()
pushViewport(plotViewport(c(5.1, 4.1, 4.1, 2.1)))
vp <- dataViewport( xData = 1:n , yData = c(mins,maxs) , name = "theRegion")
pushViewport(vp)
grid.rect()
grid.points(1:n,mins , gp = gpar(pch=2,col="blue",fill="blue"))
grid.edit("dataSymbols",pch=2)
# --------------------------------
# Error in editDLfromGPath(gPath, specs, strict, grep, global, redraw) :
# 'gPath' (dataSymbols) not found
# --------------------------------
grid.points(1:n,maxs, gp = gpar(pch=2,col="yellow"))
grid.xaxis()
grid.yaxis()
for(i in 1:n){
grid.lines(x = unit(c(i,i),"native"),
y = unit(c(mins[i],maxs[i]),"native"),
gp = gpar(col = "green",lwd=6))
}

First, a couple of issues:
1. pch is not a gpar parameter - move pch outside gpar.
2. pch=2 has a 'col' but does not have a 'fill'. A triangle-shaped symbol with both fill and col is pch=24.
3. If you want to edit a named grob, you need a grob with that name.
library(grid)
n <- 10
mins <- 10*runif(n)
maxs <- mins + 5*runif(n)
grid.newpage()
pushViewport(plotViewport(c(5.1, 4.1, 4.1, 2.1)))
vp <- dataViewport(xData = 1:n, yData = c(mins,maxs), name = "theRegion")
pushViewport(vp)
grid.rect()
# Symbols are triangles with blue border and yellow fill.
# Note the grob's name
grid.points(1:n, mins, pch = 24, gp = gpar(col = "blue", fill = "yellow"), name = "dataSymbols")
# Edit that grob so that the symbols do not have a border
grid.edit("dataSymbols", gp = gpar(col = NA))
# Edit that grob so that the symbol changes to pch = 2
grid.edit("dataSymbols", pch = 2)
# OOPS! The symbols have only a fill assigned, but pch = 2 does not have a fill
# So, give the symbols a blue border
grid.edit("dataSymbols", gp = gpar(col = "blue"))

Related

Barplot ComplexHeatmap

I did a barplot as column annotation on a heatmap. I use ComplexHeatmap.
My input for annotation is:
vector_pvalues_adj <- c(0.3778364, 0.0001000, 0.2122000, 0.4174714, 0.3778364, 0.4799250, 0.1613250, 0.4861000, 0.4174714, 0.1008000, 0.0141000, 0.4174714, 0.0001000, 0.0018000, 0.4861000, 0.4799250, 0.0001000, 0.0001000)
And the code is:
library(ComplexHeatmap)
column_ha3 = HeatmapAnnotation("-log adj p-value"= anno_barplot(-log(vector_pvalues_adj)), gp = gpar(fill = "red"), height = unit(20, "mm"))
I would to add an abline
abline(h = -log(0.05), col= "red")
But I'm not able, could someone suggest to me how to do it?
In order to add something like a horizontal line, you can use the ComplexHeatmap function decorate_annotation and the grid package.
This adds a dashed line.
library(ComplexHeatmap) # BiocManager::install("ComplexHeatmap")
library(grid)
# original code from question
vector_pvalues_adj <- c(0.3778364, 0.0001000, 0.2122000, 0.4174714,
0.3778364, 0.4799250, 0.1613250, 0.4861000,
0.4174714, 0.1008000, 0.0141000, 0.4174714,
0.0001000, 0.0018000, 0.4861000, 0.4799250,
0.0001000, 0.0001000)
# original code from question
column_ha3 = HeatmapAnnotation(
"-log adj p-value" = anno_barplot(-log(vector_pvalues_adj)),
gp = gpar(fill = "red"), height = unit(20, "mm"))
# added for context
Heatmap(matrix(rnorm(18*18), 18), name = "mat", top_annotation = column_ha3)
# 'decorate' "-log adj p-value"
decorate_annotation("-log adj p-value", {
grid.lines(c(.5, 18.5), c(4, 4), gp = gpar(lty = 2, col = "red"),
default.units = "native")
})
In the last function, c(.5, 18.5) is the x-axis values, which is always equivalent to the number of columns, or 1:18 based on your data (using .5 get's you to the edges).
For y, I have it set to start at 4 and end at 4, so you get a horizontal line. in gpar I used lty = 2 which gave me a dashed line instead of the default, a solid line.)

How to add centroids to an RDA plot

I'd like to replace the arrows on this RDA plot with centroids, something like what's pictured here.
This is the code I currently have which provides me arrows (I guess by default). I have shared our RDA code and I think this is where we might be able to change it from arrows to centroid:
# add arrows for effects of the expanatory variables
arrows(0,0, # start them from (0,0)
sc_bp[,1], sc_bp[,2], # end them at the score value
col = "red",
lwd = 1,
length = .1)
(but I share the entire code chunk (below), just in case.
Please note that my data is on fish community (species) and substrate types at 36 sites, I'd like to replace the arrows for substrates with centroids within my RDA.
##Now, the RDA
Y.mat<-Belt_2021_fish_transformed_forPCA #fish community
str(Y.mat)
X.mat<-Reefcheck_2021_forPCA #substrate
str(X.mat)
###Community data has already been transformed with hellinger
##Now, try the RDA
fish_substrate_rda<-rda(Y.mat,X.mat)
```
##Plot
## extract % explained by the first 2 axes
perc_b <- round(100*(summary(fish_substrate_rda)$cont$importance[2, 1:2]), 2)
## extract scores - these are coordinates in the RDA space
sc_si <- scores(fish_substrate_rda, display="sites", choices=c(1,2), scaling=1)
sc_sp <- scores(fish_substrate_rda, display="species", choices=c(1,2), scaling=1)
sc_sp <- sc_sp[c(2,7,8),]
sc_bp <- scores(fish_substrate_rda, display="bp", choices=c(1,2), scaling=1)
sc_bp <- sc_bp[c(2,5,6),]
# Set up a blank plot with scaling, axes, and labels
plot(fish_substrate_rda,
scaling = 1, # set scaling type
type = "none", # this excludes the plotting of any points from the results
frame = TRUE,
# set axis limits
ylim = c(-1.5,0.7),
xlim = c(-1.5,1.2),
# label the plot (title, and axes)
main = "Triplot RDA - scaling 1",
xlab = paste0("RDA1 (", perc_b[1], "%)"),
ylab = paste0("RDA2 (", perc_b[2], "%)")
)
# add points for site scores
points(sc_si,
pch = 21, # set shape (here, circle with a fill colour)
col = "black", # outline colour
bg = "steelblue", # fill colour
cex = 0.7) # size
# add points for species scores
points(sc_sp,
pch = 22, # set shape (here, square with a fill colour)
col = "black",
bg = "#f2bd33",
cex = 0.7)
# add text labels for species abbreviations
text(sc_sp + c(-0.09, -0.09), # adjust text coordinates to avoid overlap with points
labels = rownames(sc_sp),
col = "grey40",
font = 2, # bold
cex = 0.6)
# add arrows for effects of the expanatory variables
arrows(0,0, # start them from (0,0)
sc_bp[,1], sc_bp[,2], # end them at the score value
col = "red",
lwd = 1,
length = .1)
# add text labels for arrows
text(x = sc_bp[,1] -0.01, # adjust text coordinate to avoid overlap with arrow tip
y = sc_bp[,2] - 0.09,
labels = rownames(sc_bp),
col = "red",
cex = .7,
font = 1)
```
I have not found anything online that might help me to accomplish this.

Add axes to grid of ggplots

I have a grid composed of several ggplots and want to add an x axis, where axis ticks and annotations are added between the plots. I could not came up with a better solution than to create a custom plot for the axis and adding it below with arrangeGrob. But they do not align with the plots (I draw arrows where the numbers should be). Also there is a large white space below which I don't want.
I will also need an analogue for the y-axis.
library(ggplot2)
library(gridExtra)
library(ggpubr)
library(grid)
# Create a grid with several ggplots
p <-
ggplot(mtcars, aes(wt, mpg)) +
geom_point() +
theme_transparent() +
theme(plot.background = element_rect(color = "black"))
main.plot <- arrangeGrob(p, p, p, p, p, p, p, p, ncol = 4, nrow = 2)
# grid.draw(main.plot)
# Now add an x axis to the main plot
x.breaks <- c(0, 1, 2.5, 8, 10)
p.axis <- ggplot() +
ylim(-0.1, 0) +
xlim(1, length(x.breaks)) +
ggpubr::theme_transparent()
for (i in seq_along(x.breaks)) {
p.axis <- p.axis +
geom_text(aes_(x = i, y = -0.01, label = as.character(x.breaks[i])), color = "red")
}
# p.axis
final.plot <- arrangeGrob(main.plot, p.axis, nrow = 2)
grid.draw(final.plot)
Any help appreciated.
Note: In the code below, I assume each plot in your grid has equal width / height, & used equally spaced label positions. If that's not the case, you'll have to adjust the positions yourself.
Adding x-axis to main.plot:
library(gtable)
# create additional row below main plot
# height may vary, depending on your actual plot dimensions
main.plot.x <- gtable_add_rows(main.plot, heights = unit(20, "points"))
# optional: check results to verify position of the new row
dev.off(); gtable_show_layout(main.plot.x)
# create x-axis labels as a text grob
x.axis.grob <- textGrob(label = x.breaks,
x = unit(seq(0, 1, length.out = length(x.breaks)), "npc"),
y = unit(0.75, "npc"),
just = "top")
# insert text grob
main.plot.x <- gtable_add_grob(main.plot.x,
x.axis.grob,
t = nrow(main.plot.x),
l = 1,
r = ncol(main.plot.x),
clip = "off")
# check results
dev.off(); grid.draw(main.plot.x)
You can do the same for the y-axis:
# create additional col
main.plot.xy <- gtable_add_cols(main.plot.x, widths = unit(20, "points"), pos = 0)
# create y-axis labels as a text grob
y.breaks <- c("a", "b", "c") # placeholder, since this wasn't specified in the question
y.axis.grob <- textGrob(label = y.breaks,
x = unit(0.75, "npc"),
y = unit(seq(0, 1, length.out = length(y.breaks)), "npc"),
just = "right")
# add text grob into main plot's gtable
main.plot.xy <- gtable_add_grob(main.plot.xy,
y.axis.grob,
t = 1,
l = 1,
b = nrow(main.plot.xy) - 1,
clip = "off")
# check results
dev.off(); grid.draw(main.plot.xy)
(Note that the above order of x-axis followed by y-axis should not be switched blindly. If you are adding rows / columns, it's good habit to use gtable_show_layout() frequently to check the latest gtable object dimensions, & ensure that you are inserting new grobs into the right cells.)
Finally, let's add some buffer on all sides, so that the labels & plot borders don't get cut off:
final.plot <- gtable_add_padding(main.plot.xy,
padding = unit(20, "points"))
dev.off(); grid.draw(final.plot)

R. How to avoid lines connecting dots in dotplot

I made a plot using plot() using RStudio.
x = X$pos
y = X$anc
z = data.frame(x,y)
#cut in segments
my_segments = c(52660, 106784, 151429, 192098, 233666,
273857, 307933, 343048, 373099, 408960,
441545, 472813, 497822, 518561, 537471,
556747, 571683, 591232, 599519, 616567,
625727, 633744)
my_cuts = cut(x,my_segments, labels = FALSE)
my_cuts[is.na(my_cuts)] = 0
This is the code:
#create subset of segments
z_alt = z
z_alt[my_cuts %% 2 == 0,] = NA
#plot green, then alternating segments in blue
plot(z, type="p", cex = 0.3,pch = 16,
col="black",
lwd=0.2,
frame.plot = F,
xaxt = 'n', # removes x labels,
ylim = c(0.3, 0.7),
las = 2,
xlim = c(0, 633744),
cex.lab=1.5, # size of axis labels
ann = FALSE, # remove axis titles
mgp = c(3, 0.7, 0))
lines(z_alt,col="red", lwd=0.2)
# adjust y axis label size
par(cex.axis= 1.2, tck=-0.03)
If you see, some black dots are separated, but other black dots have red connecting lines. Does anyone know how to remove these annoying lines?. I just want black and red dots. Many thanks
there is no need to call the points in a second function. you can try to directly set the color in the plot function using a color vector.
# create some data as you have not provided some
set.seed(123)
df <- data.frame(x=1:100,y=runif(100))
# some sgment breaks
my_segments <- c(0,10,20,50,60)
gr <- cut(df$x, my_segments,labels = FALSE, right = T)
gr[is.na(gr)] <- 0
# create color vector with 1 == black, and 2 == red
df$color <- ifelse(gr %% 2 == 0, 1, 2)
# and the plot
plot(df$x, df$y, col = df$color, pch = 16)
The problem here is that you are using lines to add your z_alt. As the name of the function suggests, you will be adding lines. Use points instead.
z <- runif(20,0,1)
z_alt <- runif(20,0.8,1.2)
plot(z, type="p", col="black", pch = 16, lwd=0.2, ylim = c(0,1.4))
points(z_alt, col = "red", pch = 16, lwd = 0.2)

Multiple Venn diagrams in one ".EPS" file in R

I want to have two (or more) Venn diagrams in a ".eps" file. I used this post by fridaymeetssunday, which refers to this post by mnel, and I just changed the code from "pdf" to "eps" by postscript.
The problem is, when I run the code and open the file the diagrams are colorless and do not have any colors. Should I have done something else?
# libraries
library(VennDiagram)
library(grid)
library(gridBase)
library(lattice)
# create the diagrams
temp1 <- venn.diagram(list(B = 1:1800, A = 1571:2020),
fill = c("red", "green"), alpha = c(0.5, 0.5), cex = 1,cat.fontface = 2,
lty =2, filename = NULL)
temp2 <- venn.diagram(list(A = 1:1800, B = 1571:2020),
fill = c("red", "green"), alpha = c(0.5, 0.5), cex = 1,cat.fontface = 2,
lty =2, filename = NULL)
# start new page
plot.new()
#pdf("testpdf", width = 14, height = 7)
postscript("test.eps", height=8, width=8, paper="special", family="Helvetica", fonts=c("serif","Helvetica"), horizontal=FALSE)
# setup layout
gl <- grid.layout(nrow=1, ncol=2)
# grid.show.layout(gl)
# setup viewports
vp.1 <- viewport(layout.pos.col=1, layout.pos.row=1)
vp.2 <- viewport(layout.pos.col=2, layout.pos.row=1)
# init layout
pushViewport(viewport(layout=gl))
# access the first position
pushViewport(vp.1)
# start new base graphics in first viewport
par(new=TRUE, fig=gridFIG())
grid.draw(temp2)
# done with the first viewport
popViewport()
# move to the next viewport
pushViewport(vp.2)
grid.draw(temp2)
# done with this viewport
popViewport(1)
dev.off()

Resources