How to assign colors using plotTangentSpace - r

I am performing a PCA on my .tps file and I need to assign colors to species or specimens so that when plotting the graph (and the legend on it) colors do not overlap.
This is my current code:
prueba <- readland.tps("todos",specID = "ID")
ProPrueba <- gpagen(prueba)
NameList <- dimnames(prueba)[[3]]
UniqueNames <- gsub('[[:digit:]]+', '', NameList)
dimnames(prueba)[[3]] <- UniqueNames
factores <- factor(UniqueNames)
pca_prueba <- plotTangentSpace(ProPrueba$coords, label= NULL, verbose =T,
groups=factores, warpgrids=F, legend = T)
Resulting in:

Related

Save/export plots from list of plots as single .png files

I'm a bit stuck on this issue. I have this data obtained from a likert survey (so I make everything a factor):
df1<-data.frame(A=c(1,2,2,3,4,5,1,1,2,3),
B=c(4,4,2,3,4,2,1,5,2,2),
C=c(3,3,3,3,4,2,5,1,2,3),
D=c(1,2,5,5,5,4,5,5,2,3),
E=c(1,4,2,3,4,2,5,1,2,3),
dummy1=c("yes","yes","no","no","no","no","yes","no","yes","yes"),
dummy2=c("high","low","low","low","high","high","high","low","low","high"))
df1[colnames(df1)] <- lapply(df1[colnames(df1)], factor)
I then create a list of dataframes to be used in each plot:
vals <- colnames(df1)[1:5]
dummies <- colnames(df1)[-(1:5)]
step1 <- lapply(dummies, function(x) df1[, c(vals, x)])
step2 <- lapply(step1, function(x) split(x, x[, 6]))
names(step2) <- dummies
tbls <- unlist(step2, recursive=FALSE)
tbls<-lapply(tbls, function(x) x[(names(x) %in% names(df1[c(1:5)]))])
This is the plotting function I made (I used the likert package)
plot_likert <- function(x){
y<-deparse(substitute(x))
y<-sub("\\$", " - ",y)
p<-plot(likert(x),
type ="bar",center=3,
group.order=names(x))+
labs(x = "Theme", subtitle=paste("Number of observations:",nrow(x)))+
guides(fill=guide_legend("Rank"))+
ggtitle(paste("How do they rank? -",gsub("\\.",": ",y)))
png(filename=paste("Ranking -",y,".png"), width = 3000, height = 2000, res=300)
print(p)
dev.off()
}
So that now I can make the plot by writing:
plot_likert(tbls$dummy1.no)
Finally, I apply the function over the whole table by using
lapply(tbls,function(x) {
y<-deparse(substitute(x))
y<-sub("\\$", " - ",y)
plot(likert(x),
type ="bar",center=3,
group.order=names(x))+
labs(x = "Theme", subtitle=paste("Number of observations:",nrow(x)))+
guides(fill=guide_legend("Rank"))+
ggtitle(paste("How do these themes rank? -",gsub("\\.",": ",y)))
}) -> list_plots
But now I don't know how to save each graph in the list as a separate .png file! I managed to put everything in a pdf like this, but it's not what I actually want:
ggsave(
filename = "plots.pdf",
plot = marrangeGrob(list_plots, nrow=1, ncol=1),
width = 15, height = 9
)
Do you have any suggestions on how to fix this? Also, if you have anything to add about my function/procedure overall, everything is welcome! I'm still quite new to R.
Thanks in advance
we can use:
sapply(1:length(list_plots), function(i) ggsave(
filename = paste0("plots ",i,".pdf"),
plot = list_plots[[i]],
width = 15, height = 9
))
For names: see https://stackoverflow.com/a/73370416/5224236
mynames <- sapply(names(tbls), function(x) {
paste("How do they rank? -",gsub("\\.",": ",x))
})
myfilenames <- names(tbls)
plot_likert <- function(x, myname, myfilename){
p <- plot(likert(x),
type ="bar",center=3,
group.order=names(x))+
labs(x = "Theme", subtitle=paste("Number of observations:",nrow(x)))+
guides(fill=guide_legend("Rank"))+
ggtitle(myname)
p
}
list_plots <- lapply(1:length(tbls),function(i) {
plot_likert(tbls[[i]], mynames[i], myfilenames[i])
})

How can I delete column names in heatmap.2 in R?

I've built a great heatmap.2 in R but I am trying to remove the column names at the bottom of the heatmap because they are illegible. I am not able to delete the column names.
I've tried doing labCol = NULL and nothing seems to happen. Additionally, colCol = "white" also doesn't work. Any suggestions?
data<-read.csv("Symptoms Only.csv",row.names=1)
data$Subject_type<-gsub("0","Contact",data$Subject_type)
data$Subject_type<-gsub("1","Survivor",data$Subject_type)
data$Gender<-gsub("0","Male",data$Gender)
data$Gender<-gsub("1","Female",data$Gender)
condition_colors <- unlist(lapply(data$Subject_type,function(x){
if(grepl('Contact',x)) '#FFC0CB'
else if(grepl('Survivor',x)) '#808080'
}))
condition_colors
colnames(data)
data<-data[-c(1:3)]
colnames(data)
data<-t(data)
data<-as.matrix(data)
x<-data
z <- heat.clust(x,
scaledim="column",
zlim=c(-3,3),
zlim_select = c("dend","outdata"),
reorder=c("column","row"),
distfun = function(x) as.dist(1-cor(t(x))),
hclustfun= function(x) hclust(x, method="ward.D"),
scalefun = scale)
heatmap.2(z$data,
Rowv=z$Rowv,
Colv=z$Colv,
trace="none",
scale="none",
symbreaks = TRUE,
srtCol=90,
adjCol=c(0.8,1),
key=FALSE,
dendrogram = "both",
lhei=c(1,5),
cexRow = 1.1,
margins=c(4,7),
labCol = NULL,
xlab="complete",
ColSideColors = condition_colors,
col=rev(colorRampPalette(brewer.pal(10, "RdBu"))(256)),
)```
The image is base R plot, so setting xaxt="n" will remove column names. You would set the column names to empty strings, but maybe not so advisable.
library(gplots)
data(mtcars)
# correct solution
heatmap.2(x,xaxt="n")
# not so good
colnames(x) = rep("",ncol(x))
heatmap.2(x)

mschart: How do I pass mschart a dynamic list of column names and colors

In the code below, I generate some random data. I want to pass it to a function to plot but want to be able to control the looks through parameters. For e.g. I want to control the line colors, but mschart outputs red and blue lines. This is not what I want. I want it programmatically set like the rest of the chart (title , x axis etc).
#### GENERATE RAW AND RANDOM DATA
DT<-data.table(x=1:10,y=1:10, group=c(1))
DT<-rbind(DT,data.table(x=1:10,y=(1:10)**2, group=c(2)))
generate_chart <-
function(DT,x, y, group_by_col, xlab, ylab, title, num_format,color_list)
{
rr_chart <-
ms_linechart(DT,
x = x,
y = y,
group = group_by_col)
groups<-unique(DT[,get(group_by_col),] )
#TRY TO GENERATE LIST FOR COLORS from what is input
l<-list()
for(i in 1:length(groups)){
l[[groups[i]]]<-color_list[i]
}
# Standatd code where the list above is used to color the data
rr_chart <-
chart_ax_x(
rr_chart,
minor_tick_mark = 'none',
major_tick_mark = 'none'
) %>% chart_labels(title = title,
xlab = xlab,
ylab = ylab) %>% chart_ax_y(num_fmt = num_format) %>% chart_data_stroke(
l
)
rr_chart <- set_theme(rr_chart, crm_chart_theme)
}
# call function
x<-generate_chart(DT,x="x", y="y", group_by_col="group", xlab="xxxx", ylab="yyyy", title="Title", num_format="#0.0",color_list=c('red','black'))
#Add to slide
# blank because of missing template
The elements of your color list l need proper names. They must be the names attributed to the two lines (1 and 2 in your example). Adding names(l) <- 1:2 to your code now the line colors can be programmatically set.
library(mschart)
library(data.table)
library(dplyr)
generate_chart <- function(DT, x, y, group_by_col, xlab, ylab, title,
num_format, color_list) {
rr_chart <- ms_linechart(DT, x=x, y=y, group=group_by_col)
groups <- unique(DT[,get(group_by_col),] )
l <- list()
for (i in 1:length(groups)) {
l[[groups[i]]] <- color_list[i]
}
# Set Names for elements of the color list
names(l) <- 1:2
###
rr_chart <-
chart_ax_x(rr_chart, minor_tick_mark = 'none', major_tick_mark = 'none') %>%
chart_labels(title = title, xlab = xlab, ylab = ylab) %>%
chart_ax_y(num_fmt = num_format) %>%
chart_data_stroke( values=l )
rr_chart <- set_theme(rr_chart, crm_chart_theme)
}
DT <- data.table(x=1:10, y=1:10, group=c(1))
DT <- rbind(DT,data.table(x=1:10, y=(1:10)**2, group=c(2)))
x <- generate_chart(DT, x="x", y="y", group_by_col="group",
xlab="xxxx", ylab="yyyy", title="Title",
num_format="#0.0", color_list=c('red','black'))
print(x, preview=T)

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)
}

Plot polygons with different colors using rMaps

I'm trying to plot polygons on a map using rMaps and fill the polygons with different colors.
I tried unsuccessfully change the 'color' and 'fillcolor' attributes:
require(yaml)
library(rCharts)
library(rMaps)
library(plyr)
mk_polygon <- function(lats, lons, poly_color){
stopifnot(length(lats)==length(lons))
coord_list <- llply(seq_along(lats), function(i) c(lons[[i]], lats[[i]]))
list(
type = 'Feature',
properties = list(color = poly_color,
fillcolor = poly_color,
name = "station"),
geometry = list(type = 'Polygon',
coordinates = list(coord_list))
)
}
style <- list()
polygons <- list()
path <- "C:/DataVisualization/polygons/"
files <- list.files(path)
for(i in 1:length(files)){
poly <- read.csv(paste(path,files[i],sep=""),header=T)
polygons[[length(polygons)+1]] <- mk_polygon(poly$lat, poly$lon, color[i])
}
NYC <- c(40.7142700, -74.0059700)
map <- Leaflet$new()
map$setView(NYC, zoom = 10)
map$geoJson(polygons)
map
My code plots all the polygons with the same color (blue, the default color).
Does anyone know how to change it?
Any help is greatly appreciated.

Resources