how to increase the radius in circlize plot - r

I have drawn the following plot using the circlizepackage. The red circle is the unit circle drawn afterwards, using plotrix. I want to plot the first track outside the red unit circle. For this reason I changed canvas.xlim and canvas.ylim to c(-1.2, 1.2). However, this does not work. Any ideas how to increase the circle radius for the circlize plot?
NOTE: Alternatively, it would be sufficient for me, if the tracks would be outside of the unit circle instead of inside.
library(circlize)
set.seed(2)
n = 10
a = data.frame(factor = "dummy",
x = rnorm(n, 100, sd=10))
circos.par(track.height = 0.2,
canvas.xlim=c(-1.2, 1.2), # bigger canvas?
canvas.ylim=c(-1.2, 1.2)) # bigger canvas?
circos.initialize(factors = a$factor,
x = a$x, xlim = c(0, 360))
lim <- c(-1.2, 1.2)
plot(NULL, asp=1, xlim=lim, ylim=lim)
circos.trackHist(a$factor, a$x, col = "blue", bg.col = grey(.95))
plotrix::draw.circle(0,0,1, border="red", lwd=2) # unit circle

I don't know how to adjust xlim and ylim to make two plots fit. But if you just want to put the red circle inside the track, you can use draw.sector() function directly:
circos.initialize(factors = a$factor,
x = a$x, xlim = c(0, 360))
circos.trackHist(a$factor, a$x, col = "blue", bg.col = grey(.95))
draw.sector(0, 360, rou1 = circlize:::get_most_inside_radius(),
border = "red")
Here circlize:::get_most_inside_radius() returns the distance between the bottom border of the last track to the center of the circle.

Related

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.

Rotate text in outer margin of device region

I'd like to add text to the right outer margin of multiple plots that is parallel to the axis but oriented towards the center of the plot (the orientation of the words "red" and "blue" in the below plot:
par(mfcol=2:1)
curve(sin,-2*pi,2*pi,col=2)
limits <- par("usr")
text(limits[2]+.25, mean(limits[3:4]),
"red", srt=270, xpd=T)
curve(sin,-2*pi,2*pi,col=4)
text(limits[2]+.25, mean(limits[3:4]),
"blue", srt=270, xpd=T)
mtext("Color of line",side=4,outer=T)
If the mtext function used the srt parameter rather than las (which was apparently the case for S plus), this would be trivial and the above workaround using usr would be unnecessary. But I'd like to be able to orient text in the outer margin ("Color of line" above) this same way, which I appear to be unable to do even manually with text (using xpd=T still constrains the text to the most recent figure region rather than the device region).
Is there a way to do this that doesn't require using layout as in the answer of #mrflick here? This seems like it should be trivial but I don't see how it can be done.
To find the y coordinates of the center of the device, you can use grconvertY to convert from "normalized device coordinates" ("ndc"; ranges from 0 to 1) to user coordinates.
The x value is here simply adjusted with an appropriate factor (e.g. limits[2] * 1.2).
windows()
par(mfrow = c(2, 1), oma = c(0, 0, 0, 2))
curve(sin, -2*pi, 2*pi, col = 2)
limits <- par("usr")
text(limits[2] + 0.25, mean(limits[3:4]),
"red", srt = 270, xpd = TRUE)
curve(sin, -2*pi, 2*pi, col = 4)
text(limits[2] + 0.25, mean(limits[3:4]),
"blue", srt = 270, xpd = TRUE)
text(x = limits[2] * 1.2, y = grconvertY(0.5, from = "ndc"),
labels = "color of line", xpd = NA, srt = 270)
Please see previous revisions if you rather want to calculate y position from user coordinates ("usr") and plot margins ("mai").

How to adjust the position of circles when plotting venn diagram

I wanted to plot the venn diagram with two sets in which one set falls completely within another. I could draw a diagram with R package Venndiagram like this
library(VennDiagram)
grid.newpage();
venn.plot <- draw.pairwise.venn(area1 =467 ,area2 =273 ,cross.area = 273,
category = c("Set1", "Set2"),fill = c("darkorange", "dodgerblue1"),
lty = rep("solid", 2),lwd = c(2,2),col = c("black","black"),cex = 2,cat.cex = 2,cat.pos = c(310, 135),
cat.dist = 0.09,cat.just = list(c(-1, -1), c(1, 1)),
ext.pos = 30,ext.dist = -0.05,
ext.length = 0.85,ext.line.lwd = 2,ext.line.lty = "dashed");
grid.draw(venn.plot);
This may sound like esoteric tricks, but how to adjust the position of the circles, say, instead of two concentric circles, let the inner circle touch the the outer one?
Something like this one here. I added one non overlapping element.
I could not find an argument in the Venndiagram package allowing me to adjust the position of the circles.
You can try this with plotrix:
library(plotrix)
area1 = 467
area2 = 273
r1 = round(sqrt(area1/pi))
r2 = round(sqrt(area2/pi))
xc = 8
yc = 8
plot(0:40,0:40,type="n",xlab="",ylab="",main="Venn Diagram", xaxt='n', yaxt='n')
draw.circle(xc+r1,yc+r1,r1,border="black", col="orange",lty=1,lwd=1)
draw.circle(xc+2*r1-r2,yc+r1,r2,border="black", col="steelblue",lty=1,lwd=1)
text(xc+2*r1-r2,yc+r1, '272', cex=3)
text(xc+(r1-r2)/2+1,yc+r1, '195', cex=3)
text(xc+r1,yc+2*r1+7, 'Set1', cex=3)
text(xc+r1+r2,1, 'Set2', cex=3)

Removing lines within filled.contour legend

I might be missing something simple here... I can't find anyway to remove the lines that cross the legend differentiating different colours; following on the from the volcano topography example in ?filled.contour, I've got this:
x <- 10*1:nrow(volcano)
y <- 10*1:ncol(volcano)
filled.contour(x, y, volcano, color = terrain.colors,
plot.title = title(main = "The Topography of Maunga Whau",
xlab = "Meters North", ylab = "Meters West"),
plot.axes = { axis(1, seq(100, 800, by = 100))
axis(2, seq(100, 600, by = 100)) },
key.title = title(main="Height\n(meters)"),
key.axes = axis(2,
labels=FALSE,
at=FALSE,
lty=NULL,
tick=FALSE,
col="white",
col.ticks=NULL)
)
mtext(paste("filled.contour(.) from", R.version.string),side = 1, line = 4, adj = 1, cex = .66)
I've managed to remove all the labels and tick-marks from the axis, but the lines still exist (incidentally, the effect I'm trying to achieve is (I believe) the default in Matlab!)
If you examine the code for filled.contour you'll see this line:
rect(0, levels[-length(levels)], 1, levels[-1L], col = col)
that draws the color key rectangle. It's vectorized, so it's drawing each of the individual color boxes. The function rect accepts an argument border, which if you set to NA will omit the internal borders of the rectangles. So create your own version of the function and change this line to :
rect(0, levels[-length(levels)], 1, levels[-1L], col = col, border = NA)
or make it an argument, rather than hard coding. When I do this, I get the following graph:
You don't even need to change the filled.contour hardcode. Apparently the argument border in the function rect relies on par("fg"). Just set par(fg = NA) to remove those black lines.

trying to remove all margins so that plot region comprises the entire graphic

I am trying to remove all margins and the "figure region" of a plot in R, so that the plot region comprises the entire graphic device. I thought the code below would do it, but there is still a border around my plot (wider on left/bottom, thinner on top/right). Thanks
par(oma=c(0, 0, 0, 0))
par(mar=c(0, 0, 0, 0))
par(plt=c(0, 1, 0, 1))
Thought I would add a picture to show my progress. The xaxs and yaxs removed nearly all border from the top and right- there is still a border on the left and bottom.
The relevant portion of my script is below.
png("Test.png",
width = 256, height = 256,
units = "px", pointsize = 6.4,
bg = "black", res = NA)
par(mar=c(0, 0, 0, 0), xaxs='i', yaxs='i')
smoothScatter(lhb$px, lhb$pz, nrpoints=0, xlim=c(-3,3), ylim=c(0,5),
main="", xlab="", ylab="", axes=FALSE,
colramp=colorRampPalette(c("black", "#202020", "#736AFF", "cyan", "yellow", "#F87431", "#FF7F00", "red", "#7E2217"))
)
segments(.83, 1.597, .83, 3.436, col = par("fg"), lty = par("lty"), lwd = par("lwd"))
segments(-.83, 1.597, -.83, 3.436, col = par("fg"), lty = par("lty"), lwd = par("lwd"))
segments(-.83, 3.436, .83, 3.436, col = par("fg"), lty = par("lty"), lwd = par("lwd"))
segments(-.83, 1.597, .83, 1.597, col = par("fg"), lty = par("lty"), lwd = par("lwd"))
dev.off()
One issue is fundamentally not getting what plt does. From ?par we have:
‘plt’ A vector of the form ‘c(x1, x2, y1, y2)’ giving the
coordinates of the plot region as fractions of the current
figure region.
So your plot region is of zero size if you do par(plt=c(1, 1, 1, 1)), so that doesn't seem to be the way to go. This is because the figure region contains the plot region.
This plot seems to cover the entire region, without any margins:
op <- par(mar = rep(0, 4))
plot(1:10)
par(op)
it covers it so well you can't see the axes or the box:
This assumes the default for 0 outer margin (oma). Is this what you were looking for?
We can see that just adjusting the plot margins, as above, we also change the plt parameter as a side effect:
> par("plt")
[1] 0.1173174 0.9399106 0.1457273 0.8828467
> op <- par(mar = rep(0, 4))
> par("plt")
[1] 0 1 0 1
> par(op)
> par("plt")
[1] 0.1173174 0.9399106 0.1457273 0.8828467
indicating that simply setting the plot margins is sufficient to get a plot/figure region encompassing the entire device.
Of course, there is still a bit of internal padding that insures the ranges of the axes are slightly large than the range of the data in both the x and y coordinates. But you can control this with xaxs and yaxs --- see ?par
Update: As the OP has shown the sort of figure they are trying to produce without margins, I can provide a reproducible example:
set.seed(1)
dat <- matrix(rnorm(100*100), ncol = 100, nrow = 100)
layout(matrix(1:2, ncol = 2))
image(dat)
op <- par(mar = rep(0, 4))
image(dat)
par(op)
layout(1)
which gives for comparison:
and showing just the full plotting region:
Try setting the clip region parameter 'xpd' to NA ( clipped to device).
par(xpd = NA)

Resources