Arrange and size multiple plots in Lattice R - r

I want to plot three plots vary close together, so they appear as one field. My data are arrays with different dimensions.
Here is some example code to display my problem:
library(lattice)
theme.novpadding = list(layout.heights = list(top.padding = 0,
main.key.padding = 0,
key.axis.padding = 0,
axis.xlab.padding = 0,
xlab.key.padding = 0,
key.sub.padding = 0,
bottom.padding = 0),
layout.widths = list(left.padding = 0,
key.ylab.padding = 0,
ylab.axis.padding = 0,
axis.key.padding = 0,
right.padding = 0),
axis.line = list(col = "transparent"))
p1 = levelplot(array(c(1:100), c(10,10)), colorkey=F, par.settings=theme.novpadding)
p2 = levelplot(array(c(1:100), c(9,9)), colorkey=F, ylab = NULL, par.settings=theme.novpadding)
p3 = levelplot(array(c(1:100), c(11,11)), ylab=NULL, par.settings=theme.novpadding)
width = 0.33
height = 1
ph = list(5, "in")
print(p1, position = c(0, 0, width, height), panel.height=ph, more=T)
print(p2, position = c(width, 0, 2*width, height), panel.height=ph, more=T)
print(p3, position = c(2*width, 0, 3*width, height),panel.height=ph, more=F)
As you see, they are spread very wide. I want them as close as possible.
I use theme.novpadding to set the margins to zero.
Is the a way to say something like "distance between plots"?

This problem is easy to solve if you structure your data into a nice data.frame. Lattice works best on data.frames. See the example bellow:
g.xy <- expand.grid(1:10, 1:10)
my.data <- data.frame(x=g.xy$Var1, y = g.xy$Var2, value1=1:100, value2 = 1:100, value3=1:100, value4=1:100)
levelplot(value1+value2+value3+value4~x+y, data=my.data, scales=list(x="free", y="free")) # free
levelplot(value1+value2+value3+value4~x+y, data=my.data, scales=list(x="same", y="same")) # same range, so panels are "touching"
You can control for the plots to appear very close together by setting the scale argument.

A trick you could use is to tweak the position argument. In stead of not letting the areas overlap, you can do just that to make them close together. For example, you can change the position arguments to:
ovr = 0.05
print(p1, position = c(0, 0, width + ovr, height), panel.height=ph, more=T)
print(p2, position = c(width - ovr, 0, 2*width+ovr, height), panel.height=ph, more=T)
print(p3, position = c(2*width - ovr, 0, 3*width, height),panel.height=ph, more=F)
You have to some tweaking with this, and I have not tested this code. But I think the general idea should work.

Related

How to display text out of color figure and easy to read in visNetwork?

I'm getting a Network Map done using R with visNetwork library, but I hate that displayed legend has text inside the shape, so it's size is defined by how big the name is and I don't want it to be that way to avoid confusion. In library documentation they add shapes that display text outside, but you have to set it group by group with a visGroups piece (shape = "triangle", for example) for each one of the groups and I want it set in a way where I can leave that code set without specifically knowing how many groups they will be, because it won't necesarilly be the same number every time.
Coding below is the one I'm using (way much bigger, made it simple by selecting only some colums & rows):
library(igraph)
library(visNetwork)
twd2 <- structure(c(0.0854374047081175, 0.116200039661793, 0.0289142580616779,
0.12768720590989, 0.273786051264039, 0, 0.000593902599973604,
0, 0.00184397276348455, 0, 0, 0, 0, 0, 0, 0, 0.106048390315551,
0, 0, 0, 0.0142648455772593, 0, 0.0197857551361577, 0.0290239379534046,
0, 0, 0, 0, 0, 0, 0, 0, 0.00197967638677129, 0, 0.000296951299986802,
0, 0.0111915576381184, 0, 0.00111081782587656, 0.0276104933163398,
0, 0, 0.00487220095904272, 0.0149921777316026, 0, 0, 8.79855703664599e-05,
0.00674104365369398, 0, 0, 0.0330935726540847, 0, 0, 0.0362094142674287,
0, 0, 0, 0.00172168238114983, 0.00232061941841538, 0.0248983709144504
), .Dim = c(4L, 15L), .Dimnames = list(NULL, c("water_treatment",
"waste_water", "utility_model", "water_inlet", "waste_water_treatment",
"treatment_system", "model_discloses", "utility_model_discloses",
"water_outlet", "water_treatment_system", "treatment_device",
"water_tank", "sludge_treatment", "reverse_osmosis", "raw_water")))
twd2_num_col <- ncol(twd2)
twd2_cor <- cor(twd2, method = "pearson")
twd2_cor[ abs(twd2_cor) < 0.75 ] <- 0
twd2_cor[ abs(twd2_cor) > 0.925 ] <- 0
diag(twd2_cor) <- 0
graph <- graph.adjacency(twd2_cor, weighted=TRUE, mode="lower")
E(graph)$edge.width <- E(graph)$weight
V(graph)$group <- apply(twd2, 2, which.max) # Max topic prob for colors
V(graph)$betweenness <- betweenness(graph, v = V(graph), directed = F)
V(graph)$degree <- degree(graph, v = V(graph))
# Fit data for visNetwork
nm_data <<- toVisNetworkData(graph)
nodes <<- as.data.frame(nm_data[[1]], stringsAsFactors = F)
nodes <<- nodes[nodes$degree != 0,] # Bye topics that don't have a connection (degree = 0)
nodes$group <<- swap(nodes$group , 1:length(topic_names), topic_names) # Swap long real names
nodes$label <<- rep("")
# Plot
# Graph
set.seed(17);visNetwork(as.data.frame(nodes, stringsAsFactors = F),
as.data.frame(nm_data[[2]], stringsAsFactors = F),
main = "Relation between topics") %>%
visOptions(highlightNearest = TRUE, selectedBy = "group") %>%
visInteraction(dragNodes = FALSE) %>%
visLegend(useGroups = TRUE, main = "Topic") %>%
visNodes(shape = "dot",label = NULL) %>%
visIgraphLayout(randomSeed = 17)
Additionaly, here they make reference to what I said aboud selecting type of shapes, but they don't add any code and I can't figure out if there is a way to do it directly and apply it to all group options or any other choice I could have.
ledges <- data.frame(color = c("lightblue", "red"),
label = c("reverse", "depends"), arrows =c("to", "from"),
font.align = "top")
visNetwork(nodes, edges) %>%
visGroups(groupname = "A", color = "red") %>%
visGroups(groupname = "B", color = "lightblue") %>%
visLegend(addNodes = lnodes, addEdges = ledges, useGroups = FALSE)
font.align = "top" must do the job
For future visitors;
See https://www.rdocumentation.org/packages/visNetwork/versions/2.0.9/topics/visNodes
The location of the label depends on the chosen shape, for default elipse this will be inside the node." The types with the label inside of it are: ellipse, circle, database, box, text. The ones with the label outside of it are: image, circularImage, diamond, dot, star, triangle, triangleDown, square and icon."

R: Export 3D scatterplots non-interactively

Creating 3D plots in R opens up an interactive window where the user can rotate the view. For example below using package rgl:
library(rgl)
plot3d(iris[,1:3],col=c("red","green","blue")[iris$Species],size=5)
Is there some way to set a predefined view and export the plot as a regular image. I would like to do this in an automated non-interactive manner for many datasets.
Use scatterplot3d package.
library(scatterplot3d)
graphics.off()
png(filename = "test.png", width = 8, height = 6, units = "in", res = 300)
par(mai = c(0.5, 0.5, 0.5, 0.5))
scatterplot3d(x = iris$Sepal.Length, y = iris$Sepal.Width, z = iris$Petal.Length,
color = c("red","green","blue")[iris$Species],
cex.symbols = 1, pch = 19, angle = -30)
dev.off()
Besides #d.b's answer using scatterplot3d instead of rgl, you could save results using R Markdown. The advantage of doing it this way is that you get an interactive display instead of a static one; the disadvantage is that the format is HTML, not PNG or another bitmap format.
Before knitting the document, run code like this and interactively choose
the initial display you want:
library(rgl)
options(rgl.useNULL = FALSE)
plot3d(iris[,1:3],col=c("red","green","blue")[iris$Species],size=5)
Once you have it oriented correctly, run this code:
M <- par3d("userMatrix")
dput(M)
You'll get something like
structure(c(0.776694416999817, 0.198224693536758, -0.597873568534851,
0, -0.629868388175964, 0.249577552080154, -0.735511302947998,
0, 0.00341932475566864, 0.947849154472351, 0.318700969219208,
0, 0, 0, 0, 1), .Dim = c(4L, 4L))
as output. Then start your R Markdown document with something like
library(rgl)
options(rgl.useNULL = TRUE)
M <- structure(c(0.776694416999817, 0.198224693536758, -0.597873568534851,
0, -0.629868388175964, 0.249577552080154, -0.735511302947998,
0, 0.00341932475566864, 0.947849154472351, 0.318700969219208,
0, 0, 0, 0, 1), .Dim = c(4L, 4L))
(which you would probably choose not to echo), and in each code chunk that produces a plot, write code like this:
plot3d(iris[,1:3],col=c("red","green","blue")[iris$Species],size=5)
par3d(userMatrix = M)
rglwidget()
(If this is in a loop or isn't at the top level for some other reason, you'll need print(rglwidget()) instead.)
Then all of your plots will initially have the same orientation, but all of them will be user-rotatable.

More plots in an unique page: the titles are hidden

I'm trying to plot 6x4 graphs on a page, each with its title. I have used a lot of options.
pdf("myDocument.pdf") #, width = 50, height =60)
par(mfrow=c(6,4), oma = c(2,0,2,0) + 0.0)
par(mar=c(2, 0, 1, 0) + 0.1)
par(cex.axis=0.1)
par( mgp = c(1, 1, 0),
omd = c(1.0, 0, 1.0, 0),
pin=c(10,10),
plt = c(1,1,1,1),
usr =c(1,0,1,0)
)
for(z in 1:ncol(df_finale)){
...
corrplot(matriceTermine,
title = colnames(df_finale)[z],
xaxs = "i",
#insig = "pch",
#pch.col="blue",
#addrect=24, rect.lwd=10,
#addCoefasPercent=T,
method = "shade", # shade ellipse
order="original",
col=col1(11),
addgrid.col="grey",
addCoef.col="grey",
mar = c(0,0,0,0),
cl.cex= 0.2, cl.pos = "n", # 0.2
tl.pos = "n", tl.cex= 0.3, tl.offset = 0.9, tl.srt = 90,
#tl.pos="d")
}
dev.off()
It results:
Which parameters do I have to modify to make the titles visible?
And suppose I want to reduce the dimensions of the plots (to give extra-spaces to the titles), how can I do?
I have solved in this way, adding:
...
corrplot(matriceTermine,
#title = colnames(df_finale)[z],
...,
method = "s")
title(colnames(df_finale[z]), line = -0.1, cex = 2.5, font=3, cex.main = 2)
...
With
line = - q
it's possible to "move" the title of q.
For successive modifications I suggest to save the plot in a "svg" and modifying it with Inkscape.

levelplot (R lattice package) with 2 yaxis labels

I want to place 2 sets of y-axis labels on the graph I created using levelplot function from lattice library at R. I was able to get two sets of labels to show but they are overlapping. Below please see a minimum example. I also tried a few options at par.settings such as ylab.axis.padding and axis.components padding, but nothing seemed to change the superimposition of 2 y-labels. Perhaps they have been overwritten somehow? Any ideas will be appreciated.
My example codes :
A = matrix( c(3, 1, 0, 1, 2, 3, 1, 0,
rep(1,4), 2, 0, 1), nrow=3, ncol=5, byrow = TRUE)
colnames(A)= c("XXX5", "XXX4", "XXX3", "XXX2", "XXX1")
axis.build=function(side,...){
if(side == "left"){
panel.axis(side=side, outside=TRUE, at=1:5,tck=0,
text.col="black", labels=colnames(A), text.cex=0.5)
panel.axis(side=side, outside=TRUE, at=1:5,tck=0,
text.col="brown", labels=seq(ncol(A)), text.cex=0.9 )
} else axis.default(side=side, ...)
}
levelplot(A, aspect="iso", shrink = c(0.8, 0.8),
scales= list(x=list(draw=F),cex=0.5, font=2),
axis=axis.build,, xlab= NULL, ylab=NULL,
col.regions=c("black", "orange", "red","purple"),
at=c(-1, 0, 1, 2, 3), colorkey = FALSE,
par.settings = list(axis.line=list(col="transparent"),
axis.components=list(bottom=list(pad1=1, pad2=3)) ))
I think I have found the solution. In case anyone interested : I changed the first tck=0 to tck=2, and added line.col= "transparent", thus two left axis are stacked next to each other. Voila ! However, I can't seem to find where the documentation is for using pad1 and pad2 parameters. Any suggestion?

Reset margins in the wireframe plot using lattice R package

I am trying to plot a 3D graph in lattice using wireframe. I want to reset the margins between the 3d plot and the R window,
The top margins is too big and this wastes lots of space when I convert it into postscript files. I am trying to reduce to margins.
I tried the following R code par(mar=c(4,3,3,1)+0.1).
However nothing is happening.
Try this snippet, adapted from https://stat.ethz.ch/pipermail/r-help/2007-January/123556.html. It worked for me.
library(lattice)
theme.novpadding <- list(
layout.heights = list(
top.padding = 0,
main.key.padding = 0,
key.axis.padding = 0,
axis.xlab.padding = 0,
xlab.key.padding = 0,
key.sub.padding = 0,
bottom.padding = 0
),
layout.widths = list(
left.padding = 0,
key.ylab.padding = 0,
ylab.axis.padding = 0,
axis.key.padding = 0,
right.padding = 0
)
)
wireframe(volcano, shade = TRUE,
aspect = c(61/87, 0.4),
#par.settings = theme.novpadding, # uncomment this
light.source = c(10,0,10))

Resources