I have some code that loops through and plots 3 red blocks and 3 blue blocks. The goal is to use the button functionality to turn on/off the blocks. I.e. when TestA is selected the red blocks show and when TestB is selected the blue blocks show. The code initially shows the red blocks but when selecting either buttons the blue blocks show and changing the button selection doesn't resort back to showing the red blocks, I have been able to get this button functionality to work with single blocks but it appears that using a for loop to create the blocks causes problems? Any help figuring this out would be greatly appreciated.
#Start vertices of rectangles at (0,0)
x1 = 0
x2 = 0
y1 = 0
y2 = 0
width=4
listA= append(list(T,T,T,F,F,F)
listB= append(list(F,F,F,T,T,T)
updatemenus <- list(
list(
active = -1,
type= 'buttons',
buttons = list(
list(
label = "TestA",
method = "update",
args = list(list(visible = listA),
list(title = "TestA"))),
list(
label = "TestB",
method = "update",
args = list(list(visible = listB),
list(title = "TestB"))))))
#Begin plot with a blank baseplot
p <- plot_ly(width = 725, height = 725,visible=T)%>%
layout(xaxis=list(range=c(0,width),showticklabels = F),yaxis=list(range=c(0,1625000),
linewidth=2,autotick = TRUE,ticks = "outside",ticklen = 5,tickwidth = 2,tickcolor = toRGB("black"),
title = "Volume [AF]"))
#Plot Red block
x1 = 0.05
x2 = width
y1 = 0
y2 = 500000
for(i in 1:3){
y2 = y2+250000
x2 = x2+1
x1 =x1+1
p <- add_trace(p,type='scatter',mode='none',x = c(x1,x2,x2,x1,x1),
y = c(y1,y1,y2,y2,y1),visible=T,
fill = 'toself',fillcolor = 'rgb(233,87,62)',
opacity=1,line=list(color='black'),
hoveron = 'fills',
showlegend = F)
}
#Plot Blue block
x1 = 0.05
x2 = width
y1 = 0
y2 = 500000
for(i in 1:3){
y2 = y2+250000
x2 = x2+1
x1 =x1+1
p <- add_trace(p,type='scatter',mode='none',x = c(x1,x2,x2,x1,x1),
y = c(y1,y1,y2,y2,y1),visible=F,
fill = 'toself',fillcolor = 'blue',
opacity=1,line=list(color='black'),
hoveron = 'fills',
showlegend = F)
}
p = p %>% layout(updatemenus=updatemenus)
p
The problem was with the T/F list creation. I was using the following code to generate my list:
list=list(c(rep(T,3),rep(F,3)))
Which resulted in a list of length 1. Using the code:
list = c(rep(list(T),3),rep(list(F),3))
Results in a list of length 6 which is needed for this example.
Related
I created a Sankey diagram using the plotly package.
Please look at below example. I tried to make five streams, 1_6_7, 2_6_7, and so on. But two of five links between 6 and 7 disappeared. As far as I see, plotly allows to make only three or less links between two nodes.
Can I remove this restrictions ? Any help would be greatly appreciated.
Here is an example code and the outputs:
d <- expand.grid(1:5, 6, 7)
node_label <- 1:max(d)
node_colour <- scales::alpha(RColorBrewer::brewer.pal(7, "Set2"), 0.8)
link_source_nodeind <- c(d[,1], d[,2]) - 1
link_target_nodeind <- c(d[,2], d[,3]) - 1
link_value <- rep(100, nrow(d) * 2)
link_label <- rep(paste(d[,1], d[,2], d[,3], sep = "_"), 2)
link_colour <- rep(scales::alpha(RColorBrewer::brewer.pal(5, "Set2"), 0.2), 2)
p <- plotly::plot_ly(type = "sankey",
domain = c(x = c(0,1), y = c(0,1)),
orientation = "h",
node = list(label = node_label,
color = node_colour),
link = list(source = link_source_nodeind,
target = link_target_nodeind,
value = link_value,
label = link_label,
color = link_colour))
p
I have created a plotly scatter plot which I add traces to using a for loop. When I add text labels or hoverinfo, the text for the last point overwrites all others. Does anyone know how to prevent this?
I have created a reproducible example below where the (correctly named) blue points are created outside the loop however the red points created within the loop have their names overwritten (all incorrectly labelled E as opposed to A->E):
library(plotly)
data.frame1 <- data.frame("name"=paste("name", LETTERS[6:10]), "x"=-1:-5, "y"=-1:-5)
data.frame2 <- data.frame("name"=paste("name", LETTERS[1:5]), "x"=1:5, "y"=1:5)
p <- plot_ly(data.frame1, x = ~x, y = ~y, text = ~paste0(name),
name = "Outside loop", type ="scatter",
mode = "markers+text", marker=list(color="blue") )
for(i in 1:nrow(data.frame2)) {
point <- data.frame2[i, ]
p <- p %>% add_trace(x = point$x, y = point$y, text = ~paste0(point$name),
type ="scatter", mode = "markers+text",
marker = list(color="red", size=10),
name=point$name )
}
p
The ~ sign causes the problem, remove in the loop and it should be fine. It makes sense when you refer to your data frame like in the first example but it causes the weird behavior you are observing in the loop.
library(plotly)
data.frame1 <- data.frame("name"=paste("name", LETTERS[6:10]), "x"=-1:-5, "y"=-1:-5)
data.frame2 <- data.frame("name"=paste("name", LETTERS[1:5]), "x"=1:5, "y"=1:5)
p <- plot_ly(data.frame1, x = ~x, y = ~y, text = ~paste0(name),
name = "Outside loop", type ="scatter",
mode = "markers+text", marker=list(color="blue") )
for(i in 1:nrow(data.frame2)) {
point <- data.frame2[i, ]
print(paste0(point$name))
p <- p %>% add_trace(x = point$x, y = point$y, text = paste0(point$name),
type ="scatter", mode = "markers+text",
marker = list(color="red", size=10),
name=point$name )
}
p
I'm trying to use the example code here for doing iGraph network graphs in plotly and shoehorn in my own data.frames instead of using the example karate club data. When the graph is plotted, it seems to ignore the edge list and a bunch of random connections are being made. I think either the labels or edges are wrong but I can't tell.
library(igraph)
library(plotly)
setwd('C:/Users/Andrew Riffle/Documents/MEGAsync/code/R/link_analysis')
ID <- c(1:50)
nodes <- data.frame(ID)
Source <- c(23, 24, 36, 20, 36, 41, 12, 8, 18, 28)
Target <- c(5, 7, 9, 35, 23, 12, 38, 29, 33, 45)
links <- data.frame(Source, Target)
net <- graph_from_data_frame(d=links, vertices=nodes, directed=FALSE)
net <- simplify(net, remove.multiple = F, remove.loops = T)
tkplot(net, vertex.label=nodes$id, vertex.label.color='white', layout=layout.fruchterman.reingold)
#####Begin plotly example code unmodified unless commented#####
G <- upgrade_graph(net) #put my iGraph object instead of the karate club one
L <- layout.circle(G)
vs <- V(G)
es <- as.data.frame(get.edgelist(G))
Nv <- length(vs)
Ne <- length(es[1]$V1)
Xn <- L[,1]
Yn <- L[,2]
network <- plot_ly(x = ~Xn, y = ~Yn, mode = "markers", text = vs$name, hoverinfo = "text")
edge_shapes <- list()
for(i in 1:Ne) {
v0 <- es[i,]$V1
v1 <- es[i,]$V2
edge_shape = list(
type = "line",
line = list(color = "#030303", width = 0.3),
x0 = Xn[v0],
y0 = Yn[v0],
x1 = Xn[v1],
y1 = Yn[v1]
)
edge_shapes[[i]] <- edge_shape
}
axis <- list(title = "", showgrid = FALSE, showticklabels = FALSE, zeroline = FALSE)
p <- layout(
network,
title = 'Test Network', #Changed the title
shapes = edge_shapes,
xaxis = axis,
yaxis = axis
)
p #added a call to display p instead of upload to plot.ly
When I run this, I get this nice pretty iGraph that has been plotted by Plotly. However, the edges are incorrect. It appears that only the ID's 1-10 are connecting, and only to other ID's less than 10. None of these connections is in the edge list, which is below.
Source Target
1 24 35
2 12 23
3 41 12
4 23 7
5 18 5
6 20 9
7 28 29
8 36 45
9 8 33
10 36 38
Does anyone see what I'm doing wrong? Help appreciated.
I know it's a bit too late for the OP, but for the others who stumbled upon this same problem (as did I).
May I suggest the following five changes in the tutorial source code:
G <- upgrade_graph(net)
L <- layout.circle(G)
rownames(L) <- get.vertex.attribute(G)$name #added line (#1 out of 5)
vs <- V(G)
es <- as.data.frame(get.edgelist(G))
Nv <- length(vs)
Ne <- length(es[1]$V1)
Xn <- L[,1]
Yn <- L[,2]
network <- plot_ly(x = ~Xn, y = ~Yn, mode = "markers", text = vs$name, hoverinfo = "text")
edge_shapes <- list()
for(i in 1:Ne) {
v0 <- es[i,]$V1
v1 <- es[i,]$V2
edge_shape = list(
type = "line",
line = list(color = "#030303", width = 0.3),
x0 = L[which(v0==rownames(L)),][1], #changed line (#2 out of 5)
y0 = L[which(v0==rownames(L)),][2], #changed line (#3 out of 5)
x1 = L[which(v1==rownames(L)),][1], #changed line (#4 out of 5)
y1 = L[which(v1==rownames(L)),][2] #changed line (#5 out of 5)
)
edge_shapes[[i]] <- edge_shape
}
axis <- list(title = "", showgrid = FALSE, showticklabels = FALSE, zeroline = FALSE)
p <- layout(
network,
title = 'Test Network', #Changed the title
shapes = edge_shapes,
xaxis = axis,
yaxis = axis
)
p
Works fine now.
Discovered that the tutorial is actually wrong. If you plot the same karate network using plot compared to using plotly, there are many connections in plot that aren't in plotly.
I've given up trying to make this work, visNetwork is an excellent alternative that I've had a much easier time figuring out. Recommend that for anyone with a similar issue reading this.
Absolutely cannot figure out why the error is coming even though there are no self edges.
Below is a reproducible code. Any help would be great
library(HiveR)
nodes = data.frame(id = 1:9, lab = c("A","B","C","E","F","G","H","I","J"),
axis = c(1,1,1,2,3,2,2,2,3), radius = rep(50,9),size = rep(10,9),
color = c("yellow","yellow","yellow", "green","red","green","green","green","red"))
edges = data.frame(id1 = c(1,2,3,4,5,4,1,9,8,6,1),id2 = c(2,3,4,1,9,9,9,8,7,7,6),
weight = rep(1,11),
color = c(rep("green",7), rep("red",4)))
test3 <- ranHiveData(nx = 3)
test3$nodes = nodes
test3$edges = edges
test3$edges$color <- as.character(test3$edges$color)
test3$edges$id1 <- as.integer(test3$edges$id1)
test3$edges$id2 <- as.integer(test3$edges$id2)
test3$nodes$color <- as.character(test3$nodes$color)
test3$nodes$lab <- as.character(test3$nodes$lab)
test3$nodes$axis = as.integer(test3$nodes$axis)
test3$nodes$id = as.integer(test3$nodes$id)
test3$nodes$radius = as.numeric(test3$nodes$radius)
test3$nodes$size = as.numeric(test3$nodes$size)
test3$edges$weight = as.numeric(test3$edges$weight)
test3$desc = "3 axes --9 nodes -- 11 edges"
sumHPD(test3, chk.sm.pt = TRUE)
The code is giving self edges and the the plot is not rendering plotHive(test3) showing
Error in calcCurveGrob(x,x$debug) : end points must not be identical
In your code the position of the nodes of the axis (radius) are all set to 50. Hence there are overlapping points (3 on axis 1, 4 on axes 2 and 2 on axis 3).
A correct definition of radius solves the problem.
library(HiveR)
# radius has been changed !
nodes = data.frame(id = 1:9, lab = c("A","B","C","E","F","G","H","I","J"),
axis = c(1,1,1,2,3,2,2,2,3), radius = c(1,2,3,1,1,2,3,4,2),size = rep(1,9),
color = c("yellow","yellow","yellow", "green","red","green","green","green","red"))
edges = data.frame(id1 = c(1,2,3,4,5,4,1,9,8,6,1),id2 = c(2,3,4,1,9,9,9,8,7,7,6),
weight = rep(1,11),
color = c(rep("green",7), rep("red",4)))
test3 <- ranHiveData(nx = 3)
test3$nodes = nodes
test3$edges = edges
test3$edges$color <- as.character(test3$edges$color)
test3$edges$id1 <- as.integer(test3$edges$id1)
test3$edges$id2 <- as.integer(test3$edges$id2)
test3$nodes$color <- as.character(test3$nodes$color)
test3$nodes$lab <- as.character(test3$nodes$lab)
test3$nodes$axis = as.integer(test3$nodes$axis)
test3$nodes$id = as.integer(test3$nodes$id)
test3$nodes$radius = as.numeric(test3$nodes$radius)
test3$nodes$size = as.numeric(test3$nodes$size)
test3$edges$weight = as.numeric(test3$edges$weight)
test3$desc = "3 axes --9 nodes -- 11 edges"
sumHPD(test3, chk.sm.pt = TRUE)
plotHive(test3)
Using a variation of the below example dimple chart, how can I get this to auto scale with Shiny bootstrap without having to hard code height and width of the chart?
#get data used by dimple for all of its examples as a first test
data <- read.delim(
"http://pmsi-alignalytics.github.io/dimple/data/example_data.tsv"
)
#eliminate . to avoid confusion in javascript
colnames(data) <- gsub("[.]","",colnames(data))
#example 27 Bubble Matrix
d1 <- dPlot(
x = c( "Channel", "PriceTier"),
y = "Owner",
z = "Distribution",
groups = "PriceTier",
data = data,
type = "bubble",
aggregate = "dimple.aggregateMethod.max"
)
d1$xAxis( type = "addCategoryAxis" )
d1$yAxis( type = "addCategoryAxis" )
d1$zAxis( type = "addMeasureAxis", overrideMax = 200 )
d1$legend(
x = 200,
y = 10,
width = 500,
height = 20,
horizontalAlign = "right"
)
d1
Hi you have to put width="100%" in dplot(), like this :
d1 <- dPlot(
x = c( "Channel", "PriceTier"),
y = "Owner",
z = "Distribution",
groups = "PriceTier",
data = data,
type = "bubble",
aggregate = "dimple.aggregateMethod.max",
width="100%"
)