I have made a RGB composite image of a satellite image using ggRGB() from the RStoolbox package. I would like to add a scale bar to the image, but I'm stumped as to how to do this. I would usually use scalebar() from the ggsn package when working with ggmaps() in R, but it doesn't look like it can handle a RasterBrick object as input like like is required for ggRGB().
Here is an example:
library(raster)
library(ggplot2)
library(RStoolbox)
data(lsat)
ggRGB(img = lsat,
r = 3,
g = 2,
b = 1,
stretch = 'hist') +
blank() # eliminate x and y axes
This produces the following image:
I would like to add a scale bar in the upper right corner. Here's what I tried:
ggRGB(img = lsat,
r = 3,
g = 2,
b = 1,
stretch = 'hist') +
blank() +
ggsn::scalebar(lsat, dist = 2, dist_unit = "km",
transform = TRUE, model = "WGS84", location = "upperright")
This returns an error: "Error in .local(x, ...) : invalid layer names"
Any help would be much appreciated. I'd like to stick with ggRGB() if possible, but I'd be open to other plotting methods if I can place a scale bar on the image.
You could use package ggspatial
ggRGB(img = lsat,
r = 3,
g = 2,
b = 1,
stretch = 'hist') +
theme_void() +
ggspatial::annotation_scale(location = "tr", width_hint =0.5, pad_x = unit(0.7, "cm"))
If you want more fine control over the appearance, a slightly more verbose but highly customizable method is also given in this answer https://stackoverflow.com/a/39069955/2761575
Related
I am trying to rotate one of the labels on my grid.arrange panel figure to look like the axis of all three plots, but this is not working using the methods I am finding online.
When I use a textGrob for control of the font size (which I need to be 24), using this code, I get this figure. I am inserting the rot= 90 argument but it isn't doing anything to the figure.
grid.arrange(d.a.plot1, d.b.plot1, d.c.plot1, ncol = 1, left = textGrob("Probability of remaining availabile", gp=gpar(fontsize=24, rot = 90)), bottom = textGrob("Depth(cm)", gp=gpar(fontsize = 24)))
When I use the standard grid.arrange code to add a rotated label using the code below, the position is fine, but then I can't adjust the font.
grid.arrange(d.a.plot1, d.b.plot1, d.c.plot1, ncol = 1, left = "Probability of remaining availabile", bottom = textGrob("Depth(cm)", gp=gpar(fontsize = 24)))
You just need to take rot = 90 out of gpar and pass it directly to textGrob:
# Simulate the plot grobs:
f <- function() cowplot::as_grob(~plot(rnorm(100), rnorm(100)))
grid.arrange(f(), f(), f(), ncol = 1,
left = textGrob("Probability of remaining availabile", rot = 90,
gp = gpar(fontsize=24)),
bottom = textGrob("Depth(cm)", gp=gpar(fontsize = 24)))
I'm using the function waterfall from GenVisR package. As the vignette suggests, I am changing the top plot with custom values. However, those values cannot be specified and appear in gray as "Undefined" (see image)
.
I would like to add a layer with ggplot in order to define (and colour) the barplot like the following plot:
In the vignette the authors have an argument called mutBurdenLayer that seems to do the job but I'm not able to change the graph.
Any ideas?
Here is my code:
library(GenVisR)
library(ggplot2)
library(RColorBrewer)
custom_pallete <- brewer.pal(8, "Paired")
waterfall(VCFs, coverageSpace = 179977, main_geneLabSize = 5,
mainLabelSize = 2, mainLabelCol="HGVSp", mainDropMut = T,
mainPalette = custom_pallete, mainXlabel = T)
I would like to add something like:
mut_burden_layer <- theme(...)
waterfall(VCFs, coverageSpace = 179977, main_geneLabSize = 5,
mainLabelSize = 2, mainLabelCol="HGVSp", mainDropMut = T,
mainPalette = custom_pallete, mutBurden = mut, mainXlabel = T,
mutBurdenLayer = mut_burden_layer)
Being mutBurden a data table with the new proportions and mutBurdenLayer the parameter I would like to custom.
Does anyone know of a way to 1) complete the missing gridlines in the grid3d call for y, and 2) draw horizontal gridlines to close the top of the grids constructed by the grid3d calls for x and y? I've played around with various combinations of pretty calls within grid3d to no avail and am wondering if this is an rgl quirk or a misspecification on my part. Additionally, I'd like to extend the vertical axis numbering to wherever the closed grids end up.
library(rgl)
cpts <- seq(0, 2, length = 40)
spts <- seq(0, 1, length = 20)
grid <- expand.grid(s=spts, c=cpts)
UFn <- function(s,c){c^(0.5) - exp(s) + 1}
U <- UFn(grid$s, grid$c)
open3d()
rgl.surface(x = spts, y = matrix(U,nrow = 40, ncol = 20), z = cpts,
coords = c(1,3,2), specular = "black")
axes3d("x", at = pretty(spts, n = 2), color = "black")
axes3d("y", at = pretty(cpts, n = 5), color = "black")
axes3d("z--", color = "black")
grid3d("x")
grid3d("y", at = pretty(spts, n = 2))
title3d(xlab ='s', ylab = 'c', zlab = 'U', color = "black")
rgl.snapshot("3d.png")
I would say it is a bug. You don't get any z-lines when using grid3d("y",n=2) even though it should be the same. You can work around it by using the list specification of at, setting the x element of the list, eg:
grid3d("y", at = list(x=pretty(spts, n = 2)))
I'm trying to produce a non-ultrametric tree using the ape package in R and the function plot.phylo(). I'm struggling to find any documentation on how to keep the tip label vertically aligned on their left edge and with a series of dots (variable length) linking the species' name to the tip of the node.
Any help would be much appreciated as well as links to other packages within R that may be able to achieve this.
An example of the newick tree
I don't have any tree examples of what i want, however, the description seems self explanatory. the labels would all be shifted to the very right, and aligned on their left side, then a series of dots (.......) would link the label to where there old position was.
MLJTT = newickTree (as a string)
plot.phylo(read.tree(text = MLJTT), show.tip.label = T,use.edge.length = T, no.margin = T, cex = 0.55)
And example of three that I want to copy the layout of from here:
Ok, I ended up slightly modifying the default plot.phylo code to accomidate such a change. Here's how it looks
library(ape)
plot.phylo2 <- plot.phylo
environment(plot.phylo2) <- environment(plot.phylo)
body(plot.phylo2)[[c(34, 3, 6, 3, 4, 3)]] <- quote({
mx <- max(xx[1:Ntip])
segments(xx[1:Ntip], yy[1:Ntip] + loy, mx, yy[1:Ntip] + loy,
lty=2, col="grey")
text(mx + lox, yy[1:Ntip] + loy, x$tip.label, adj = adj,
font = font, srt = srt, cex = cex, col = tip.color)
})
This is somewhat fragile and may change in different version of ape, I've tested this with version ape_3.1-4. You can check if this will work by verifying that
body(plot.phylo)[[c(34, 3, 6, 3, 4, 3)]]
returns
text(xx[1:Ntip] + lox, yy[1:Ntip] + loy, x$tip.label, adj = adj,
font = font, srt = srt, cex = cex, col = tip.color)
just to make sure we are changing the correct line. But the code above basically replaces that line where the labels are drawn by moving the x axis where they are drawn and adding in the segments for the dotted lines. Then you can run this with your test data
MLJTT = read.tree(text="..<sample data>..")
plot.phylo2(MLJTT,
show.tip.label = T,use.edge.length = T, no.margin = T, cex = 0.55)
And this produces
I think what you may be looking for is the argument to plot.phylo:
align.tip.label = TRUE
Have you tried this?
MLJTT <- rtree(100)
plot.phylo(MLJTT, show.tip.label = T, align.tip.label = T, use.edge.length = T, no.margin = T, cex = 0.55)
I am trying to put two Venn diagrams in one single graph, i.e. I am using par(mfrow=c(1,2)) at the very beginning. However, when I use the Venn() function in the Vennerable package:
VennCompare = Venn(SetNames = c("A", "B", "C"), Weight = c(0, 38, 1, 0, 1, 80, 0, 14))
pdf(file="Venn.pdf", width=12, height=6)
par(mfrow=c(1,2))
plot(VennCompare, doWeights=FALSE)
plot(VennCompare, doWeights=TRUE, show = list(SetLabels = TRUE, Faces = FALSE))
dev.off()
The resultant pdf file contains 2 pages, and each page has a single Venn diagram.
How can I put the two diagrams into a single page (i.e. side-by-side)?
As already discussed in comments, Vennerable uses grid graphics and fixes the grid parameters inside of the package functions. You should probably ask kindly from package maintainers if they could add this kind of functionality in their packages, but in a meantime I offer you a Sketchof a hack which allows you to do what you want:
The first command allows you to edit the function called makevp.eqsc which seems to contain the grid definitions:
trace("makevp.eqsc",edit=TRUE)
Original code looks like this:
function (xrange, yrange)
{
pushViewport(plotViewport(name = "Vennmar", c(1, 1, 1, 1)))
pushViewport(viewport(name = "Vennlay", layout = grid.layout(1,
1, widths = diff(xrange), heights = diff(yrange), respect = TRUE)))
pushViewport(viewport(name = "Vennvp", layout.pos.row = 1,
layout.pos.col = 1, xscale = xrange, yscale = yrange))
}
The most relevant parts are grid.layout, which tells you what kind of grid you want to draw. Also layout.pos.row and layout.pos.col are important, they tell in which position to draw. Change the code for example like this:
function (xrange, yrange)
{
pushViewport(plotViewport(name = "Vennmar", c(1, 1, 1, 1)))
pushViewport(viewport(name = "Vennlay", layout = grid.layout(2,
1, widths = diff(xrange), heights = diff(yrange), respect = TRUE)))
pushViewport(viewport(name = "Vennvp", layout.pos.row = number,
layout.pos.col = 1, xscale = xrange, yscale = yrange))
}
Now you will get two stacked graphs, like this:
number<-1 #change the argument inside of makevp.eqsc
plot(VennCompare, doWeights=FALSE)
number<-2
plot(VennCompare, doWeights=TRUE,
show = list(SetLabels = TRUE, Faces = FALSE),add=TRUE) #note add=TRUE
This doesn't look really nice, but by modifying makevp.eqsc you can probably archieve more nice results.
I couldn't install that package, but a trick that might help here is to use grid.grab to capture the drawing into a grob that can be placed elsewhere,
library(grid)
myplot <- function(){
pushViewport(viewport(x=0.5,width=1, just=0.5))
grid.rect(gp=gpar(fill=grey(runif(1, 0.2, 0.8))))
grid.points()
popViewport()
}
p1 <- grid.grabExpr(myplot())
p2 <- grid.grabExpr(myplot())
library(gridExtra)
grid.arrange(p1, p2, ncol=2)
Try this:
v <- Venn(n=2)
plot(v)
grid.text("Title", vp = viewport(x=0.5, y=.9, w=unit(1, "npc"), h=unit(1, "npc")))