I wrote a function to generate multiple graphs in plotly. In each of those graph, I am only adding annotations for last data point.
To plot all those graphs at once, I am using subplot function.
This however shows some extra arrows on the graph. I'm not sure what I am doing wrong, where they are coming from, or how do I turn them off.
(Turning them white wouldn't be a solution as they are also problamatic in the sense that their position stays relatively constant if eg Y axis is formatted as %- they just dwarf everything)
Really appreciate some assistance with this.
library(plotly)
library(tibble)
library(dplyr)
# A function to generate plots in the required format
plotbundlefunction<-function(data1,ttitle){
mypalette <- c("#4E79A7","#F28E2B","#E15759","#76B7B2","#59A14F","#EDC948","#B07AA1","#FF9DA7","#9C755F","BAB0AC") %>% head(ncol(data1)-1)
lineannot<-c()
for(i in 2:ncol(data1)){
lineannot[[i]]<-list(x = tail(na.omit(data1 %>% select('ID',i)),n=1L)[['ID']], y = tail(na.omit(data1[[i]]),n=1L), text = tail(na.omit(data1[[i]]),n=1L),
font=list(color=mypalette[i-1]),xanchor = "left", bgcolor="#D4D8DF", showarrow = F)
}
p <- plot_ly()
for(i in 2:ncol(data1)){
p<-add_trace(p,x=data1[['ID']],y=data1[[i]],name=colnames(data1)[i], type='scatter', mode='lines')
}
p %>% layout(colorway=mypalette, annotations = lineannot) %>% return()
}
# Numerous dataframe representing snapshot at a point in time for same data characteristics
dflist<-list(
KPI1 = data.frame(ID=c(1,2,3,4,5), Japan=c(100,98,97,95,94), Korea = c(100,97,94,91,87) , Laos=c(100,97,94,90,84)),
KPI2 = data.frame(ID=c(1,2,3,4,5), Japan=c(5,7,8,9,3) , Korea = c(6,8,7,9,5) , Laos=c(7,5,5,2,1)),
KPI3 = data.frame(ID=c(1,2,3,4,5), Japan=c(78,89,56,48,92) , Korea = c(42,49,85,99,72) , Laos=c(78,58,88,87,68))
)
#Iterate over a function that generates a separate graph for each columns across dataframes
mainplotset<-lapply(1:length(dflist),function(s){
plotbundlefunction(dflist[[names(dflist)[s]]],names(dflist)[s])
})
#Do a subplot to show all results
subplot(mainplotset,nrows = 1,margin=0.05)
Update based on your comment
As I pointed out in my comment after I already posted this answer, the actual solution is the revise the for statement that creates the annnotations. Instead of
for(i in 2:ncol(data1)){
lineannot[[i]] <- ...
It should be
for(i in 2:ncol(data1)){
lineannot[[i - 1]] <- ...
On to how I found the arrows...
I meant to include how I came up with the annotations traces, sorry about leaving that out!
I can't think of any way an arrow can get into a plot without annotations, so I knew where to start. So first, I set the subplot to an object and looked at whether showarrow was set to TRUE or FALSE.
plt <- subplot(mainplotset,nrows = 1,margin=0.05)
invisible(lapply(
1:length(plt$x$layout$annotations),
function(k) {
res <- plt$x$layout$annotations[[k]]$showarrow
message("arrow? ", k, " ", res)
}
))
The default for annotations is showarrow = TRUE, so that's why your plots were returned with arrows.
Original answer
Such an odd error! I'm not sure how to prevent this error. (I'm still trying to figure that out.) In the meantime, I thought I could give you a way to fix it.
I used lapply to find out what traces were creating these arrows.
plt <- subplot(mainplotset, nrows = 1, margin = 0.05)
# arrow? 1
# arrow? 2 FALSE
# arrow? 3 FALSE
# arrow? 4 FALSE
# arrow? 5
# arrow? 6 FALSE
# arrow? 7 FALSE
# arrow? 8 FALSE
# arrow? 9
# arrow? 10 FALSE
# arrow? 11 FALSE
# arrow? 12 FALSE
When I looked at the traces that didn't indicate true or false, there was nothing in the traces except xref and yref.
To remove them:
plt$x$layout$annotations <- plt$x$layout$annotations[c(-1, -5, -9)]
plt
Related
I have 11 plots and used a looping function to plot them see my code below. However, I can't get them to fit in just 1 page or less. The plots are actually too big. I am using R software and writing my work in RMarkdown. I have spent almost an entire week trying to resolve this.
group_by(Firm_category) %>%
doo(
~ggboxplot(
data =., x = "Means.type", y = "means",
fill ="grey", palette = "npg", legend = "none",
ggtheme = theme_pubr()
),
result = "plots"
)
graph3
# Add statistical tests to each corresponding plot
Firm_category <- graph3$Firm_category
xx <- for(i in 1:length(Firm_category)){
graph3.i <- graph3$plots[[i]] +
labs(title = Firm_category[i]) +
stat_pvalue_manual(stat.test[i, ], label = "p.adj.signif")
print(graph3.i)
}
#output3.long data sample below as comments
#Firm_category billmonth Means.type means
#Agric 1 Before 38.4444
#Agric 1 After 51.9
Complete data is on my github: https://github.com/Fridahnyakundi/Descriptives-in-R/blob/master/Output3.csv
This code prints all the graphs but in like 4 pages. I want to group them into a grid. I have tried to add all these codes below just before my last curly bracket and none is working, please help me out.
library(cowplot)
print(plot_grid(plotlist = graph3.i[1:11], nrow = 4, ncol = 3))
library(ggpubr)
print(ggarrange(graph3.i[1:11], nrow = 4, ncol = 3))
I tried the gridExtra command as well (they all seem to do the same thing). I am the one with a mistake and I guess it has to do with my list. I read a lot of similar work here, some suggested
dev.new()
dev.off()
I still didn't get what they do. But adding either of them caused my code to stop.
I tried defining my 'for' loop function say call it 'XX', then later call it to make a list of graph but it returned NULL output.
I have tried defining an empty list (as I read in some answers here) then counting them to make a list that can be printed but I got so many errors.
I have done this for almost 3 days and will appreciate your help in resolving this.
Thanks!
I tried to complete your code ... and this works (but I don't have your 'stat.test' object). Basically, I added a graph3.i <- list() and replaced graph3.i in the loop ..
Is it what you wanted to do ?
library(magrittr)
library(dplyr)
library(rstatix)
library(ggplot2)
library(ggpubr)
data <- read.csv(url('http://raw.githubusercontent.com/Fridahnyakundi/Descriptives-in-R/master/Output3.csv'))
graph3 <- data %>% group_by(Firm_category) %>%
doo(
~ggboxplot(
data =., x = "Means.type", y = "means",
fill ="grey", palette = "npg", legend = "none",
ggtheme = theme_pubr()
),
result = "plots"
)
graph3
# Add statistical tests to each corresponding plot
graph3.i <- list()
Firm_category <- graph3$Firm_category
xx <- for(i in 1:length(Firm_category)){
graph3.i[[i]] <- graph3$plots[[i]] +
labs(title = Firm_category[i]) # +
# stat_pvalue_manual(stat.test[i, ], label = "p.adj.signif")
print(graph3.i)
}
library(cowplot)
print(plot_grid(plotlist = graph3.i[1:11], nrow = 4, ncol = 3))
I am trying to use spplot to visualize plots from different months. I'd like to change this figure so the same months are in the same columns to easily compare. I would like to push May 2016 5 panels in, so all the rest of the months are in line. I hope this makes sense.
click here for figure
I have missing data for Dec2017 for now which is why it's blacked out.
Here is my code:
stack_months <- stack(May2016, June2016, July2016, Aug2016, Sep2016, Oct2016, Nov2016, Dec2016, January2017, Febuary2017, March2017, April2017, May2017, June2017, July2017, July2017, Aug2017, Sep2017, Oct2017, Nov2017, Dec2017, January2018, Febuary2018, March2017, April2018, May2018, June2017, July2017, July2018, Aug2018, Sep2018, Oct2018, Nov2018, Dec2018, January2019, Febuary2019, March2019, April2019, May2019, June2019, July2019, July2019)
spplot(stack_months, col.regions=viridis(20), names.attr = c("May2016", "June2016", "July2016", "Aug2016", "Sep2016", "Oct2016", "Nov2016", "Dec2016",
"Jan2017", "Feb2017", "March2017", "April2017", "May2017", "June2017", "July2017", "July2017", "Aug2017", "Sep2017", "Oct2017", "Nov2017", "Dec2017",
"Jan2018", "Feb2018", "March2017", "April2018", "May2018", "June2017", "July2017", "July2018", "Aug2018", "Sep2018", "Oct2018", "Nov2018", "Dec2018",
"Jan2019", "Feb2019", "March2019", "April2019", "May2019", "June2019", "July2019", "July2019"), layout = c(12,4))
Is there an easy way to manipulate the panels?
Note that you have type some of the months twice, for example July2017 appeared 3 times and March2017, 2 times, June2017 2x and July2019 2x.
What I have below are complete months from May2016 to July2019, so that when you plot, the months will align.
library(raster)
library(sp)
library(viridis)
library(lattice)
months=c("May2016", "June2016", "July2016", "Aug2016", "Sep2016", "Oct2016",
"Nov2016", "Dec2016", "Jan2017", "Feb2017", "March2017", "April2017",
"May2017", "June2017", "July2017","Aug2017", "Sep2017",
"Oct2017", "Nov2017", "Dec2017","Jan2018", "Feb2018", "March2018",
"April2018", "May2018", "Jun2018", "July2018", "Aug2018",
"Sep2018", "Oct2018", "Nov2018", "Dec2018","Jan2019", "Feb2019",
"March2019", "April2019", "May2019", "June2019", "July2019")
I don't have your data, so I simulate something for the image:
r <- raster(system.file("external/test.grd", package="raster"))
stack_months = do.call(stack,lapply(months,function(i)runif(1)*r))
You defined layout to be 12,4 so you will have 48 entries which are filled by row. In your case, the first 4 will not be plotted and the last 5 will not be plotted:
SKIP = rep(FALSE,12*4)
SKIP[1:4] = TRUE
SKIP[44:48] = TRUE
Then we plot using the SKIP above:
spplot(stack_months, col.regions=viridis(20),
layout = c(12,4),
strip = strip.custom(par.strip.text = list(cex = 0.65)),
names.attr = months,
skip=SKIP
)
I think I have read every page on the internet that mentions coldiss and I am still having trouble getting the labels to look correctly. In the image I inserted, the matrices look good but the labels are default numbers (so aren't that useful for a stand alone image) and in the ordered matrix the matrix gets ordered correctly, but the labels didn't re-order, which doesn't make sense.
[Matrix output images][1]
My questions are:
1) How do I get the labels to order properly for the ordered matrix? If the cells in the heat map are changing colors after being ordered, the respective labels should be different too.
2) Is it possible to edit the coldiss function to use my isolate labels that can be found in the top row or first column to label the heat map rather than the default numbers?
Here is the code I'm running.
library(gclus)
library(ape)
source("coldiss.txt")
tree<-read.tree("BP_SNPS_only-BioNJ_tree_100BS")
PatristicDistMatrix100BS<-cophenetic.phylo(tree)
coldiss(D = PatristicDistMatrix100BS, nc = 4, byrank = TRUE, diag = TRUE)
Here is the coldiss.txt file:
# coldiss()
# Color plots of a dissimilarity matrix, without and with ordering
#
# License: GPL-2
# Author: Francois Gillet, 23 August 2012
#
"coldiss" <- function(D, nc = 4, byrank = TRUE, diag = FALSE)
{
require(gclus)
if (max(D)>1) D <- D/max(D)
if (byrank) {
spe.color <- dmat.color(1-D, cm.colors(nc))
}
else {
spe.color <- dmat.color(1-D, byrank=FALSE, cm.colors(nc))
}
spe.o <- order.single(1-D)
speo.color <- spe.color[spe.o, spe.o]
op <- par(mfrow=c(1,2), pty="s")
if (diag) {
plotcolors(spe.color, rlabels=attributes(D)$Labels,
main="Dissimilarity Matrix",
dlabels=attributes(D)$Labels)
plotcolors(speo.color, rlabels=attributes(D)$Labels[spe.o],
main="Ordered Dissimilarity Matrix",
dlabels=attributes(D)$Labels[spe.o])
}
else {
plotcolors(spe.color, rlabels=attributes(D)$Labels,
main="Dissimilarity Matrix")
plotcolors(speo.color, rlabels=attributes(D)$Labels[spe.o],
main="Ordered Dissimilarity Matrix")
}
par(op)
}
# Usage:
# coldiss(D = dissimilarity.matrix, nc = 4, byrank = TRUE, diag = FALSE)
# If D is not a dissimilarity matrix (max(D) > 1), then D is divided by max(D)
# nc number of colours (classes)
# byrank= TRUE equal-sized classes
# byrank= FALSE equal-length intervals
# diag = TRUE print object labels also on the diagonal
# Example:
# coldiss(spe.dj, nc=9, byrank=F, diag=T)
Here is an abbreviated version of PatristicDistMatrix100BS:
CDC-B043_1995 CDC-A267_1994 CDC-A161_1992 CDC-C931_1998
CDC-B043_1995 0 0.00099 0.00099 0.00166
CDC-A267_1994 0.00099 0 0.00066 0.00133
CDC-A161_1992 0.00099 0.00066 0 0.00133
CDC-C931_1998 0.00166 0.00133 0.00133 0
I hope this provides all the relevant information and thank you for any help you can provide even if it's a completely different function.
There is nothing wrong in the code. The main problem I think is some other packages you have loaded. I also had same problem but when I tried separately it worked well and as you require. Just remove other packages or calculate separately. For more details have a look on the code of chapter three of this document (http://adn.biol.umontreal.ca/~numericalecology/numecolR/). Here is the code I work with.
(vegan must be loaded after ade4 to avoid some conflicts)
library(ade4)
library(vegan)
library(gclus)
library(cluster)
library(FD)
files must be in the working directory. You can search this file from internet from this link (https://github.com/JoeyBernhardt/NumericalEcology)
source("coldiss.R")
source("panelutils.R")
Then calculate your dissimilarity matrix and plot using the code
BCD <- vegdist(df[-1])
coldiss(BCD, byrank = FALSE, diag = TRUE)
Hopefully it will work.
I want to create a heatmap using the heatmap.2 function from the gplots package. This is a minimal example.
require(gplots)
# create symmetric matrix
x = matrix(rnorm(100), nrow=10)
diag(x) <- 1
x[upper.tri(x)] <- t(x)[upper.tri(x)]
colnames(x) <- rownames(x) <- letters[1:nrow(x)]
# create side colours
varcols = setNames(rainbow(nrow(x)), rownames(x))
# create heatmap
heatmap.2(x,
symm = TRUE,
trace = "none",
revC=TRUE, # <-- THIS IS THE PROBLEM
ColSideColors = varcols,
RowSideColors = varcols
)
The problem are the sidecolors. x is a symmetric matrix, thus columns and rows should have the same sidecolors. This is fine as long as revC = FALSE. However, when I use revC = TRUE the order of the colors is messed up. Sometimes - in small examples - it helps to reverse the ColSideColors, but that doesn't always work.
Am I doing anything wrong or is this a gplots bug?
For anyone else who comes across this problem this is how I solved it:
thing = heatmap.2(my_matrix,...RowSideColors=row_cols, revC=F)
ordinary_order = thing$rowInd
reversal = cbind(ordinary_order, rev(ordinary_order))
rev_col = row_cols[reversal[,2]]; rev_col = rev_col[order(reversal[,1])];
heatmap.2(my_matrix, RowSideColors=rev_col, revC=T)
I have created 36 heatmaps with the function pheatmap, and I want to display them in just one figure. I have tried to using the function par(), but it did not work, I do not know why. Could someone tell me what should I do? Thank you very much. This is my code:
require(graphics);require(grDevices);library("pheatmap", lib.loc="D:/Program Files/R/R-3.1.1/library");library(gplots)
filenames<-list.files("D:/Project/bladder cancer/heatmap0829/heatmap/"); # detect all of the files in the fold
filename2<-strtrim(filenames,nchar(filenames)-4); # all of the filenames without extension names
par(mfrow=c(18,2)) #divide the graphics windows into a 18x2 matrix
for(i in 1:length(filename2)){
rt<-read.table(paste("D:/Project/bladder cancer/heatmap0829/heatmap/",filenames[i],sep = ""), header = T, sep = '\t') # Import the data with the ith file name
size=dim(rt) # the dimensional of the datafram
cw=400/size[1] #the width of the cell in the heatmap
rt<-log10(rt)
x <- t(data.matrix(rt))
pheatmap(x,color=greenred(256),main=filename2[i],cluster_rows = F, cluster_cols = T,cellwidth = cw, cellheight = 60,border_color =F,fontsize = 8,fontsize_col = 15)}
This is one dataset
ScaBER 5637
1 1.010001e+02
1.341186e+00 2.505067e+01
1.669456e+01 8.834190e+01
7.141351e+00 3.897474e+01
1.585592e+04 5.858210e+04
1 3.137979e+01
1.498863e+01 7.694948e+01
1.115443e+02 3.642917e+02
1.157677e+01 5.036716e+01
4.926492e+02 8.642784e+03
3.047117e+00 1.872154e+01
I have 36 txt files like this, but I can not put all of them here
"ScaBER 5637" is the column name of this dataset
See this previous answer: Histogram, error: Error in plot.new() : figure margins too large
par(mfcol=c(3,12), oma=c(1,1,0,0), mar=c(1,1,1,0), tcl=-0.1, mgp=c(0,0,0))
for(i in 1:36){
plot(runif(2), runif(2), type="l")
}
dev.off()