Plotly node placement in R in a Sankey Diagram - r

Okay, I can't figure out what I'm doing wrong here.
I want the nodes to be positioned green, yellow, red in descending order. I'm trying to create a number of them, so I don't want to have to position the nodes by hand in Viewer.
I've updated R, and plotly, and everything else I can think of. Through trial and error I think I have the right side in the correct order, but the left side still bedevils me.
fig <- plot_ly(type = 'sankey',
orientation = 'h',
arrangement = 'snap',
node = list(label = c("Low", "Moderate", "High", "-4.9%", "+0%", "+4.9%"),
color = c('green', 'yellow', 'red', 'green', 'yellow', 'red'),
y = c(0, .1, .5, 0, .1, .5),
x = c(0, 0, 0, 1, 1, 1),
pad = 10,
thickness = 20,
line = list(color = 'black',
width = .5)
),
link = list(source = c(0, 0, 0, 1, 1, 1, 2, 2, 2),
target = c(3, 4, 5, 3, 4, 5, 3, 4, 5),
value = c(17,7, 8, 5, 1,10, 5, 8,42)))
fig <- fig %>%
layout()
fig
Edit: To be more specific about my question, I don't understand how the x and y coordinates work. The effect of changing those parameters seems to be very unpredictable, and I can't suss out how they work.

According to this open issue, node.x and node.y arguments for manual positions can't be equal to 0. Changing the 0 values to 0.001 in your code fixes the ordering. It seems that if any 0 values are present, the arguments are ignored with a silent error. I have been digging into this recently and opened a related issue about the documentation and general problems with overriding the node order.
fig <- plot_ly(type = 'sankey',
orientation = 'h',
arrangement = 'snap',
node = list(label = c("Low", "Moderate", "High", "-4.9%", "+0%", "+4.9%"),
color = c('green', 'yellow', 'red', 'green', 'yellow', 'red'),
y = c(0.001, .1, .5, 0, .1, .5),
x = c(0.001, 0.001, 0.001, 1, 1, 1),
pad = 10,
thickness = 20,
line = list(color = 'black',
width = .5)
),
link = list(source = c(0, 0, 0, 1, 1, 1, 2, 2, 2),
target = c(3, 4, 5, 3, 4, 5, 3, 4, 5),
value = c(17,7, 8, 5, 1,10, 5, 8,42)))
fig <- fig %>%
layout()
fig

Related

ggbetweenstats: logarithmic y axis removes grouped analysis from plot

I am conducting a kruskal-wallis test to determine statistically significance between three groups of a measurement. I use ggbetweenstats to determine between which group there is a statistically significant association.
Here is the code for sample data and the plot:
sampledata <- structure(list(ID = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20), group = c(1, 2, 3, 1, 2, 3,
1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2), measurement = c(0,
1, 200, 30, 1000, 6000, 1, 0, 0, 10000, 20000, 700, 65, 1, 8,
11000, 13000, 7000, 500, 3000)), class = "data.frame", row.names = c(NA,
20L))
library(ggstatsplot)
library(ggplot2)
ggbetweenstats(
data = sampledata,
x = group,
y = measurement,
type = "nonparametric",
plot.type = "box",
pairwise.comparisons = TRUE,
pairwise.display = "all",
centrality.plotting = FALSE,
bf.message = FALSE
)
You can see the results from the kruskal wallis test on the top of the plot as well as the groupes analysis in the plot. Now I want to change y axis to logarithmic scale:
ggbetweenstats(
data = sampledata,
x = group,
y = measurement,
type = "nonparametric",
plot.type = "box",
pairwise.comparisons = TRUE,
pairwise.display = "all",
centrality.plotting = FALSE,
bf.message = FALSE
) +
ggplot2::scale_y_continuous(trans=scales::pseudo_log_trans(sigma = 1, base = exp(1)), limits = c(0,25000), breaks = c(0,1,10,100,1000,10000)
)
However, this removes the grouped analysis. I have tried different scaling solutions and browsed SO for a solution but couldn't find anything. Thank you for your help!
It seems that the y_position parameter in the geom_signif component is not affected by the y axis transformation. You will need to pass the log values of the desired bracket heights manually. In theory, you can pass these via the ggsignif.args parameter, but it seems that in the latest version of ggstatsplot this isn't possible because the y_position is hard-coded.
One way tound this is to store the plot then change the y positions after the fact. Here's a full reprex with the latest versions of ggplot2, ggstatsplot and their dependencies (at the time of writing)
sampledata <- structure(list(ID = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20), group = c(1, 2, 3, 1, 2, 3,
1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2), measurement = c(0,
1, 200, 30, 1000, 6000, 1, 0, 0, 10000, 20000, 700, 65, 1, 8,
11000, 13000, 7000, 500, 3000)), class = "data.frame", row.names = c(NA,
20L))
library(ggstatsplot)
library(ggplot2)
library(scales)
p <- ggbetweenstats(
data = sampledata,
x = group,
y = measurement,
type = "nonparametric",
plot.type = "box",
pairwise.comparisons = TRUE,
pairwise.display = "all",
centrality.plotting = FALSE,
bf.message = FALSE
) + scale_y_continuous(trans = pseudo_log_trans(sigma = 1, base = exp(1)),
limits = c(0, exp(13)),
breaks = c(0, 10^(0:5)),
labels = comma)
#> Scale for y is already present.
#> Adding another scale for y, which will replace the existing scale.
i <- which(sapply(p$layers, function(x) inherits(x$geom, "GeomSignif")))
p$layers[[i]]$stat_params$y_position <- c(10, 10.8, 11.6)
p
Created on 2023-01-15 with reprex v2.0.2

R Plotly 3D: Add Mesh to Scatter plot without inheriting color scheme

Basically I have a scatter 3d Scatter plot with the points in two categories (selected, unselected) which are represented in red and grey. To better visualize the selected volume I want to add a cube with low opacity in blue. However, when I add the mesh for the cube, the cube appears in green and the unselected points in orange instead of grey.
In short: Why is the cube not blue and the unselected points not grey and how can I make them do so?
library(shiny)
library(plotly)
ui <- fluidPage(
tags$h2("This is my 3D plot."),
plotlyOutput("Plot3d", width = "1000px", height = "1000px")
)
server <- function(input, output, session){
output$Plot3d <- renderPlotly ({
#Defining data frame for scatter
df_scatter <- data.frame(X_VAL = rnorm(50, mean = 0.5, sd = 0.15),
Y_VAL = rnorm(50, mean = 0.5, sd = 0.15),
Z_VAL = rnorm(50, mean = 0.5, sd = 0.15),
SCATTER_COL = rep("unselected", 50))
#Every point inside of the cube is labeled "selected"
for (i in 1:nrow(df_scatter)){
if (df_scatter$X_VAL[i] < 0.5 && df_scatter$Y_VAL[i] < 0.5 && df_scatter$Z_VAL[i]< 0.5) {
df_scatter$SCATTER_COL[i] <- "selected"
}
}
df_scatter$SCATTER_COL <- factor(df_scatter$SCATTER_COL, levels = c("selected", "unselected"))
#Defining data frame for mesh
df_mesh <- data.frame(X_VAL = c(0, 0, 0.5, 0.5, 0, 0, 0.5, 0.5),
Y_VAL = c(0, 0.5, 0.5, 0, 0, 0.5, 0.5, 0),
Z_VAL = c(0, 0, 0, 0, 0.5, 0.5, 0.5, 0.5),
MESH_COL = factor(rep("CUBE", 8), levels = c("CUBE")))
plot_ly()%>%
add_markers(type = "scatter3d",
mode = "markers",
data = df_scatter,
x = ~X_VAL,
y = ~Y_VAL,
z = ~Z_VAL,
color = ~SCATTER_COL,
colors = c('red', 'grey')) %>%
#Here the trouble starts
add_trace(type = 'mesh3d',
data = df_mesh,
x = ~X_VAL,
y = ~Y_VAL,
z = ~Z_VAL,
i = c(7, 0, 0, 0, 4, 4, 6, 1, 4, 0, 3, 6),
j = c(3, 4, 1, 2, 5, 6, 5, 2, 0, 1, 6, 3),
k = c(0, 7, 2, 3, 6, 7, 1, 6, 5, 5, 7, 2),
color = ~MESH_COL,
colors = c("blue"),
inherit = FALSE,
opacity = 0.1
)
})
}
shinyApp(ui = ui, server=server)
Any help is greatly appreciated.
Try facecolor:
library(shiny)
library(plotly)
#> Loading required package: ggplot2
#>
#> Attaching package: 'plotly'
#> The following object is masked from 'package:ggplot2':
#>
#> last_plot
#> The following object is masked from 'package:stats':
#>
#> filter
#> The following object is masked from 'package:graphics':
#>
#> layout
mycolors <- colours()[2:10]
ui <- fluidPage(
tags$h2("This is my 3D plot."),
plotlyOutput("Plot3d", width = "1000px", height = "1000px")
)
server <- function(input, output, session){
output$Plot3d <- renderPlotly ({
#Defining data frame for scatter
df_scatter <- data.frame(X_VAL = rnorm(50, mean = 0.5, sd = 0.15),
Y_VAL = rnorm(50, mean = 0.5, sd = 0.15),
Z_VAL = rnorm(50, mean = 0.5, sd = 0.15),
SCATTER_COL = rep("unselected", 50))
#Every point inside of the cube is labeled "selected"
for (i in 1:nrow(df_scatter)){
if (df_scatter$X_VAL[i] < 0.5 && df_scatter$Y_VAL[i] < 0.5 && df_scatter$Z_VAL[i]< 0.5) {
df_scatter$SCATTER_COL[i] <- "selected"
}
}
df_scatter$SCATTER_COL <- factor(df_scatter$SCATTER_COL, levels = c("selected", "unselected"))
#Defining data frame for mesh
df_mesh <- data.frame(X_VAL = c(0, 0, 0.5, 0.5, 0, 0, 0.5, 0.5),
Y_VAL = c(0, 0.5, 0.5, 0, 0, 0.5, 0.5, 0),
Z_VAL = c(0, 0, 0, 0, 0.5, 0.5, 0.5, 0.5))
plot_ly()%>%
add_markers(type = "scatter3d",
mode = "markers",
data = df_scatter,
x = ~X_VAL,
y = ~Y_VAL,
z = ~Z_VAL,
color = ~SCATTER_COL,
colors = c('red', 'grey')) %>%
add_trace(type = 'mesh3d',
data = df_mesh,
x = ~X_VAL,
y = ~Y_VAL,
z = ~Z_VAL,
i = c(7, 0, 0, 0, 4, 4, 6, 1, 4, 0, 3, 6),
j = c(3, 4, 1, 2, 5, 6, 5, 2, 0, 1, 6, 3),
k = c(0, 7, 2, 3, 6, 7, 1, 6, 5, 5, 7, 2),
facecolor = rep("blue", 12),
opacity = 0.1
)
})
}
shinyApp(ui = ui, server=server)
Created on 2020-07-02 by the reprex package (v0.3.0)

How to label individual points with vectors in R

I'm pretty new to coding and R in general. I'm trying to figure out how to create plots both as individual points as well as vectors. I should be getting the same result for both options, but I can't seem to figure out how to correlate the labels for the points when using vectors.
Here's the table I was given
Here's my code for the individual plotting and the plot
plot(
x = NULL,
xlim = c(0, 8),
ylim = c(0, 10),
main = "Problem 3a- Individual Points Fuction",
xlab = "x",
ylab = "y",
las = 1
)
text( 0.6, 7.5, "A" )
points( 1, 7, pch = 19, cex = 3, col = "navy" )
text( 3.4, 2.5, "B" )
points( 4, 3, pch = 15, cex = 6, col = "blueviolet" )
text( 5.6, 4.0, "C" )
points( 6, 5, pch = 17, cex = 4, col = "firebrick2" )
text( 1.6, 1.5, "D" )
points( 2, 2, pch = 18, cex = 5, col = "cyan3" )
text( 6.8, 3.5, "E" )
points( 7, 4, pch = 16, cex = 2, col = "seagreen3" )
Here's my code for the vector method, with the plot:
plot(
x = NULL,
xlim = c(0, 8),
ylim = c(0, 10),
main = "Problem 3b- Vector Points Fuction",
xlab = "x",
ylab = "y",
las = 1
)
points(
x = c(1, 4, 6, 2, 7),
y = c(7, 3, 5, 2, 4),
pch = c(19, 15, 17, 18, 16),
cex = c(3, 6, 4, 5, 2),
col = c("navy", "blueviolet", "firebrick2", "cyan3", "seagreen3"),
)
I can't seem to figure out how to label the points on the vector, and have it labeled at certain coordinates. I've tried just putting Text = ("A", "B", etc) as well as trying to make that a vector too (text = c("A",etc), but I keep getting errors. Any advice and resources would be appreciated.
You can use the text function as shown below. I added the xDisp variable to easily setup the labels position (if needed you can add a yDisp variable as well for vertical position).
xDisp = -0.5
plot(
x = NULL,
xlim = c(0, 8),
ylim = c(0, 10),
main = "Problem 3b- Vector Points Fuction",
xlab = "x",
ylab = "y",
las = 1
)
points(
x = c(1, 4, 6, 2, 7),
y = c(7, 3, 5, 2, 4),
pch = c(19, 15, 17, 18, 16),
cex = c(3, 6, 4, 5, 2),
col = c("navy", "blueviolet", "firebrick2", "cyan3", "seagreen3")
)
text(
x = c(1+xDisp, 4+xDisp, 6+xDisp, 2+xDisp, 7+xDisp), y = c(7, 3, 5, 2, 4), labels = c("A","B","C","D","E")
)

Grey Background in R When Using qcc (quality control charts) Plot

I'm having a problem where my graph is always on a light grey background which looks awful in LaTeX. I've tried using par(bg=NA), par(bg="white") which is what everyone suggests but that literally does nothing...
Here's the code:
# install.packages('qcc')
library(qcc)
nonconforming <- c(3, 4, 6, 5, 2, 8, 9, 4, 2, 6, 4, 8, 0, 7, 20, 6, 1, 5, 7)
samplesize <- rep(50, 19)
control <- qcc(nonconforming, type = "p", samplesize, plot = "FALSE")
warn.limits <- limits.p(control$center, control$std.dev, control$sizes, 2)
par(mar = c(5, 3, 1, 3), bg = "blue")
plot(control, restore.par = FALSE, title = "P Chart for Medical Insurance Claims",
xlab = "Day", ylab = "Proportion Defective")
abline(h = warn.limits, lty = 3, col = "blue")
v2 <- c("LWL", "UWL") # the labels for warn.limits
mtext(side = 4, text = v2, at = warn.limits, col = "blue", las = 2)
Check out ?qcc.options() -- specifically, the bg.margin option. The following will change your plot to have a lightgreen background (note: probably not a good choice for LaTeX, but it illustrates the point):
library(qcc)
nonconforming <- c(3, 4, 6, 5, 2, 8, 9, 4, 2, 6, 4, 8, 0, 7, 20, 6, 1, 5, 7)
samplesize <- rep(50, 19)
old <- qcc.options() # save the original options
qcc.options(bg.margin = "lightgreen")
par(mar = c(5, 3, 1, 3))
control <- qcc(nonconforming, type = "p", samplesize, plot = "FALSE")
warn.limits <- limits.p(control$center, control$std.dev, control$sizes, 2)
plot(control, restore.par = FALSE, title = "P Chart for Medical Insurance Claims",
xlab = "Day", ylab = "Proportion Defective")
abline(h = warn.limits, lty = 3, col = "blue")
v2 <- c("LWL", "UWL") # the labels for warn.limits
mtext(side = 4, text = v2, at = warn.limits, col = "blue", las = 2)
qcc.options(old) # reset the old options

how to make barplot bars same size in plot window in R using barplot function

I would like to plot 3 plots in the same window. Each will have a different amount of bar plots. How could I make them all the same size and close together (same distance from each other) without doing NAs in the smaller barplots. example code below. I do want to point out my real data will be plotting numbers from dataframes$columns not a vector of numbers as shown below. I am sure there is magic way to do this but cant seem to find helpful info on the net. thanks
pdf(file="PATH".pdf");
par(mfrow=c(1,3));
par(mar=c(9,6,4,2)+0.1);
barcenter1<- barplot(c(1,2,3,4,5));
mtext("Average Emergent", side=2, line=4);
par(mar=c(9,2,4,2)+0.1);
barcenter2<- barplot(c(1,2,3));
par(mar=c(9,2,4,2)+0.1);
barcenter3<- barplot(c(1,2,3,4,5,6,7));
Or would there be a way instead of using the par(mfrow....) to make a plot window, could we group the barcenter data on a single plot with an empty space between the bars? This way everything is spaced and looks the same?
Using the parameters xlim and width:
par(mfrow = c(1, 3))
par(mar = c(9, 6, 4, 2) + 0.1)
barcenter1 <- barplot(c(1, 2, 3, 4, 5), xlim = c(0, 1), width = 0.1)
mtext("Average Emergent", side = 2, line = 4)
par(mar = c(9, 2, 4, 2) + 0.1)
barcenter2 <- barplot(c(1, 2, 3), xlim = c(0, 1), width = 0.1)
par(mar = c(9, 2, 4, 2) + 0.1)
barcenter1 <- barplot(c(1, 2, 3, 4, 5, 6, 7), xlim = c(0, 1), width = 0.1)
Introducing zeroes:
df <- data.frame(barcenter1 = c(1, 2, 3, 4, 5, 0, 0),
barcenter2 = c(1, 2, 3, 0, 0, 0, 0),
barcenter3 = c(1, 2, 3, 4, 5, 6, 7))
barplot(as.matrix(df), beside = TRUE)
With ggplot2 you can get something like this:
df <- data.frame(x=c(1, 2, 3, 4, 5,1, 2, 3,1, 2, 3, 4, 5, 6, 7),
y=c(rep("bar1",5), rep("bar2",3),rep("bar3",7)))
library(ggplot2)
ggplot(data=df, aes(x = x, y = x)) +
geom_bar(stat = "identity")+
facet_grid(~ y)
For the option you mentioned in your second comment you would need:
x <- c(1, 2, 3, 4, 5, NA, 1, 2, 3, NA, 1, 2, 3, 4, 5, 6, 7)
barplot(x)

Resources