pictorial chart in r - r

I am trying to develop pictorial charts. Is it possible to develop such charts in R ?
myd <- data.frame (categories = c("Planes", "Ships", "Cars", "Trains"),
values = c(15, 18, 22, 11))
Component icons are here:

Hope that this would be helpful four your house / parliament floor
Edit: I forget to mention my reference and I add some explanations.
library(lattice)
library(grid)
imgs.names <- c('WNinq','7dqJM','9E3Wj','tStmx')
library(png)
images <- lapply(imgs.names, function(x)
readPNG(paste(mypath,x,'.png',sep=''),native=TRUE))
## I generate some data because we don't give a reproducible example
x <- c(rep(0,4),rep(10,9),rep(20,3),rep(5,8),rep(4,8),rep(15,4),rep(13,8))
barchart(1:4~x, origin=0, col="yellow",xlim=c(0,30),
xlab ='values',ylab='categories',title = 'Pictorial',
scales = list(
y = list(cex=2,col='blue', at = 1:4,labels = c('Trains','Cars','Ships','Planes')),
x = list(cex=2,col='blue',at=seq(0,30,by=10))
),
panel=function(x, y, ...) {
panel.fill(col = rgb(1,1,205/255)) ## I had to pick up the same yellow color!!
panel.grid()
lapply(1:4,function(id){
grid.raster(images[[id]], x=x[which(y==id)], y=y[which(y==id)],
default.units="native",
just="left",
width =unit(2, "native"),
height=unit(0.7, "native"))
}
)
}
)

Related

Multi-panel network figure using a loop?

I'm trying to make a multipanel figure with networks in the igraph package. I'd like 2 rows, each with 3 networks. I need to be able to save the figure as a PNG and I'd like to label them each A:F in one of the corners. I've tried to do this in a loop but only one network appears in the figures. I need the V(nw)$x<- y and E(nw)$x<- y code in the loop to make my networks come out properly. My networks are in a list().
I've made a small sample of the code I've tried, I would like to avoid doing it without a loop if I can. Thanks in advance.
srs_1nw <- graph("Zachary")
srs_2nw <- graph("Heawood")
srs_3nw <- graph("Folkman")
srs_1c <- cluster_fast_greedy(srs_1nw)
srs_2c <- cluster_fast_greedy(srs_2nw)
srs_3c <- cluster_fast_greedy(srs_3nw)
listofsrs_nws <- list(srs_1nw,srs_2nw,srs_3nw)
listofsrs_cs <- list(srs_1c,srs_2c,srs_3c)
colours <- c("red","blue","green","yellow")
par(mfrow=c(2,3))
for (i in length(listofsrs_nws)) {
c<-listofsrs_cs[[i]]
nw<-listofsrs_nws[[i]]
V(nw)$size <- log(strength(nw))*6 # weighted nodes
E(nw)$arrow.size <- 2 # arrow size
c.colours <- colours[membership(c)]
plot(c, nw, col = c.colours,
mark.col = adjustcolor(colours, alpha.f = 0.4),
mark.border = adjustcolor(colours, alpha.f = 1),
vertex.frame.width = 5, edge.curved = .15)
}
We can use mapply like below
mapply(function(c, nw) {
V(nw)$size <- log(strength(nw)) * 6 # weighted nodes
E(nw)$arrow.size <- 2 # arrow size
c.colours <- colours[membership(c)]
plot(c, nw,
col = c.colours,
mark.col = adjustcolor(colours, alpha.f = 0.4),
mark.border = adjustcolor(colours, alpha.f = 1),
vertex.frame.width = 5, edge.curved = .15
)
}, listofsrs_cs, listofsrs_nws)

R Shiny HTMLWidget for interactive 3D-histograms

I would like to include a 3D dynamic (i.e. one can change its perspective just by moving the plot) histogram widget in a R Shiny application.
Unfortunately I didn't find any until now.
So far the results of my searches: with threejs (e.g. here on CRAN and there on GitHub) one can use many different representations (scatterplots, surfaces, etc.) but no 3D histogram. plot3D and plot3Drgl don't have any R Shiny counterpart.
Unless something already exists my intention is to create an HTMLWidget from one of the sub-libraries of vis.js, namely graph3d.
What are your views on this issue?
Best regards,
Olivier
It's possible with plot3Drgl. Here is an example.
library(plot3Drgl)
library(shiny)
options(rgl.useNULL = TRUE)
ui <- fluidPage(
rglwidgetOutput("myWebGL")
)
server <- function(input, output) {
save <- options(rgl.inShiny = TRUE)
on.exit(options(save))
output$myWebGL <- renderRglwidget({
try(rgl.close())
V <- volcano[seq(1, nrow(volcano), by = 5),
seq(1, ncol(volcano), by = 5)] # lower resolution
hist3Drgl(z = V, col = "grey", border = "black", lighting = TRUE)
rglwidget()
})
}
shinyApp(ui, server)
My package graph3d is on CRAN now.
library(graph3d)
dat <- data.frame(x = c(1,1,2,2), y = c(1,2,1,2), z = c(1,2,3,4))
graph3d(dat, type = "bar", zMin = 0, tooltip = TRUE)
You can customize the tooltips:
graph3d(dat, type = "bar", zMin = 0,
tooltip = JS(c("function(xyz){",
" var x = 'X: ' + xyz.x.toFixed(2);",
" var y = 'Y: ' + xyz.y.toFixed(2);",
" var z = 'Z: ' + xyz.z.toFixed(2);",
" return x + '<br/>' + y + '<br/>' + z;",
"}"))
)
I realize I have to add an option to control the size of the axes labels...
Many thanks, DSGym. I didn't know this library.
In my initial message (now amended) I actually forgot to mention the dynamic feature, i.e. the ability to change the perspective of the plot just by moving it with the mouse, like with vis.js-graph3d.
It seems plots from highcharter cannot do that, or am I mistaken?
[EDIT]: I just checked with Shiny: it is static.

How can I remove elements from plot in R?

Just a quick question: I want to remove plot elements. Such as col, main etc.
I am adding a picture to you can understand better.
https://hizliresim.com/XMQr0R
str(nr)
kmncluster <- kmeans(na.omit(nr), centers = 10, iter.max = 500, nstart = 5, algorithm="Lloyd")
knr <- ndvi
knr[] <- kmncluster$cluster
values(knr) <- kmncluster$cluster
mycolor <- c("#fef65b","#ff0000", "#daa520","#0000ff","#0000ff","#00ff00","#cbbeb5",
"#c3ff5b", "#ff7373", "#00ff00", "#808080")
par(mfrow = c(1,2))
plot(ndvi, col = rev(terrain.colors(10)), main = 'Landsat-NDVI')
plot(knr, main = 'Unsupervised classification', col = mycolor )
dev.off()
I just want to keep the picture. I don't want to see any other information.

Partial Row Labels Heatmap - R

I was wondering if anyone knows of a package that allows partial row labeling of heatmaps. I am currently using pheatmap() to construct my heatmaps, but I can use any package that has this functionality.
I have plots with many rows of differentially expressed genes and I would like to label a subset of them. There are two main things to consider (that I can think of):
The placement of the text annotation depends on the height of the row. If the rows are too narrow, then the text label will be ambiguous without some sort of pointer.
If multiple adjacent rows are significant (i.e. will be labelled), then these will need to be offset, and again, a pointer will be needed.
Below is an example of a partial solution that really only gets maybe halfway there, but I hope illustrates what I'd like to be able to do.
set.seed(1)
require(pheatmap)
require(RColorBrewer)
require(grid)
### Data to plot
data_mat <- matrix(sample(1:10000, 300), nrow = 50, ncol = 6)
rownames(data_mat) <- paste0("Gene", 1:50)
colnames(data_mat) <- c(paste0("A", 1:3), paste0("B", 1:3))
### Set how many genes to annotate
### TRUE - make enough labels that some overlap
### FALSE - no overlap
tooMany <- T
### Select a few genes to annotate
if (tooMany) {
sigGenes_v <- paste0("Gene", c(5,20,26,42,47,16,28))
newMain_v <- "Too Many Labels"
} else {
sigGenes_v <- paste0("Gene", c(5,20,26,42))
newMain_v <- "OK Labels"
}
### Make color list
colors_v <- brewer.pal(8, "Dark2")
colors_v <- colors_v[c(1:length(sigGenes_v), 8)]
names(colors_v) <- c(sigGenes_v, "No")
annColors_lsv <- list("Sig" = colors_v)
### Column Metadata
colMeta_df <- data.frame(Treatment = c(rep("A", 3), rep("B", 3)),
Replicate = c(rep(1:3, 2)),
stringsAsFactors = F,
row.names = colnames(data_mat))
### Row metadata
rowMeta_df <- data.frame(Sig = rep("No", 50),
stringsAsFactors = F,
row.names = rownames(data_mat))
for (gene_v in sigGenes_v) rowMeta_df[rownames(rowMeta_df) == gene_v, "Sig"] <- gene_v
### Heatmap
heat <- pheatmap(data_mat,
annotation_row = rowMeta_df,
annotation_col = colMeta_df,
annotation_colors = annColors_lsv,
cellwidth = 10,
main = "Original Heat")
### Get order of genes after clustering
genesInHeatOrder_v <- heat$tree_row$labels[heat$tree_row$order]
whichSigInHeatOrder_v <- which(genesInHeatOrder_v %in% sigGenes_v)
whichSigInHeatOrderLabels_v <- genesInHeatOrder_v[whichSigInHeatOrder_v]
sigY <- 1 - (0.02 * whichSigInHeatOrder_v)
### Change title
whichMainGrob_v <- which(heat$gtable$layout$name == "main")
heat$gtable$grobs[[whichMainGrob_v]] <- textGrob(label = newMain_v,
gp = gpar(fontsize = 16))
### Remove rows
whichRowGrob_v <- which(heat$gtable$layout$name == "row_names")
heat$gtable$grobs[[whichRowGrob_v]] <- textGrob(label = whichSigInHeatOrderLabels_v,
y = sigY,
vjust = 1)
grid.newpage()
grid.draw(heat)
Here are a few outputs:
original heatmap:
ok labels:
ok labels, with flags:
too many labels
too many labels, with flags
The "with flags" outputs are the desired final results.
I just saved these as images from the Rstudio plot viewer. I recognize that I could save them as pdfs and provide a larger file size to get rid of the label overlap, but then the individual cells would be larger than I want.
Based on your code, you seem fairly comfortable with gtables & grobs. A (relatively) straightforward way to achieve the look you want is to zoom in on the row label grob, & make some changes there:
replace unwanted labels with "";
evenly spread out labels within the available space;
add line segments joining the old and new label positions.
I wrote a wrapper function for this, which works as follows:
# heat refers to the original heatmap produced from the pheatmap() function
# kept.labels should be a vector of labels you wish to show
# repel.degree is a number in the range [0, 1], controlling how much the
# labels are spread out from one another
add.flag(heat,
kept.labels = sigGenes_v,
repel.degree = 0)
add.flag(heat,
kept.labels = sigGenes_v,
repel.degree = 0.5)
add.flag(heat,
kept.labels = sigGenes_v,
repel.degree = 1)
Function (explanations in annotations):
add.flag <- function(pheatmap,
kept.labels,
repel.degree) {
# repel.degree = number within [0, 1], which controls how much
# space to allocate for repelling labels.
## repel.degree = 0: spread out labels over existing range of kept labels
## repel.degree = 1: spread out labels over the full y-axis
heatmap <- pheatmap$gtable
new.label <- heatmap$grobs[[which(heatmap$layout$name == "row_names")]]
# keep only labels in kept.labels, replace the rest with ""
new.label$label <- ifelse(new.label$label %in% kept.labels,
new.label$label, "")
# calculate evenly spaced out y-axis positions
repelled.y <- function(d, d.select, k = repel.degree){
# d = vector of distances for labels
# d.select = vector of T/F for which labels are significant
# recursive function to get current label positions
# (note the unit is "npc" for all components of each distance)
strip.npc <- function(dd){
if(!"unit.arithmetic" %in% class(dd)) {
return(as.numeric(dd))
}
d1 <- strip.npc(dd$arg1)
d2 <- strip.npc(dd$arg2)
fn <- dd$fname
return(lazyeval::lazy_eval(paste(d1, fn, d2)))
}
full.range <- sapply(seq_along(d), function(i) strip.npc(d[i]))
selected.range <- sapply(seq_along(d[d.select]), function(i) strip.npc(d[d.select][i]))
return(unit(seq(from = max(selected.range) + k*(max(full.range) - max(selected.range)),
to = min(selected.range) - k*(min(selected.range) - min(full.range)),
length.out = sum(d.select)),
"npc"))
}
new.y.positions <- repelled.y(new.label$y,
d.select = new.label$label != "")
new.flag <- segmentsGrob(x0 = new.label$x,
x1 = new.label$x + unit(0.15, "npc"),
y0 = new.label$y[new.label$label != ""],
y1 = new.y.positions)
# shift position for selected labels
new.label$x <- new.label$x + unit(0.2, "npc")
new.label$y[new.label$label != ""] <- new.y.positions
# add flag to heatmap
heatmap <- gtable::gtable_add_grob(x = heatmap,
grobs = new.flag,
t = 4,
l = 4
)
# replace label positions in heatmap
heatmap$grobs[[which(heatmap$layout$name == "row_names")]] <- new.label
# plot result
grid.newpage()
grid.draw(heatmap)
# return a copy of the heatmap invisibly
invisible(heatmap)
}

Printing Venn Diagram after calculating overlap

I'm trying to use the calculate.overlap function within the VennDiagram package to first calculate and then print a Venn Diagram. I was able to calculate the overlap of my data set but looking for help how to print the Venn graphic. Can anyone provide assistance? I read through the documentation but didn't find this.
> library('VennDiagram')
# A simple single-set diagram
cardiome <- letters[1:10]
superset <- letters[8:24]
overlap <- calculate.overlap(
x = list(
"Cardiome" = cardiome,
"SuperSet" = superset
)
);
Another simple example that shows how to print a Venn diagram using the VennDiagram package:
library(VennDiagram)
cardiome <- letters[1:10]
superset <- letters[8:24]
overlap <- calculate.overlap(
x <- list("Cardiome"=cardiome, "SuperSet"=superset))
venn.plot <- draw.pairwise.venn(
area1 = length(cardiome),
area2 = length(superset),
cross.area = length(overlap),
category = c("Cardiome", "Superset"),
fill = c("blue", "red"),
lty = "blank",
cex = 2,
cat.cex = 2,
cat.pos = c(180, 180),
cat.dist = 0.05,
cat.just = list(c(0, 1), c(1, 1))
)
grid.draw(venn.plot)
savePlot(filename="venndiag", type="png")
Venn diagrams with item labels inside the sets:
library(RAM)
vectors <- list(Cardiome=cardiome, Superset=superset)
group.venn(vectors=vectors, label=TRUE,
fill = c("blue", "red"),
cat.pos = c(180, 180),
lab.cex=1.1)
The funtion venn.diagram() does it. For instance in your example
venn.diagram(x = list(
"Cardiome" = cardiome,
"SuperSet" = superset
), "plot_venn")
It saves to working directory. Type getwd() to see what it is set to.
See the
?venn.diagram()
for more info.
?venn.diagram suggests this
library('VennDiagram')
venn.plot <- venn.diagram(
x = list(
cardiome = letters[1:10],
superset = letters[8:24]
),
filename = NULL
);
grid.draw(venn.plot);

Resources