I am trying to plot 2 solids of revolution using plotly in R, and would like to obtain an image with both of the plots side by side. However, the plots seem to appear on top of each others instead.
I start creating a 3D scatter plot following the very useful example found in this answer.
In my case, I wanted to use a gaussian curve and rotate it around the Y axis, instead of X axis as in the example, so I modified the code as below:
#my test with gaussian
r <- function(x,sigma,mu) 1/(sqrt(2*pi)*sigma)*(exp(-1*(x-mu)^2/2/(sigma^2)))
#centre distribution on 0
mu=0
#choose a sigma
sigma=1
#interval of interest on the x
int <- c(-5, 5)
# number of points along the x-axis
nx <- 1000
# number of points along the rotation
ntheta <- 100
# set x points and get corresponding radii = calculates the value of the function for all x points
coords <- data_frame(x = seq(int[1], int[2], length.out = nx), r = r(x, sigma, mu))
# for each r: rotate x to get xi and z coordinates
# edit: ensure 0 and pi are both amongst the angles used
coords %<>%
rowwise() %>%
do(data_frame(r = .$r, x = .$x,
theta = seq(0, pi, length.out = ntheta / 2 + 1) %>%
c(pi + .[-c(1, length(.))]))) %>%
ungroup %>%
mutate(xi = x * sin(theta), z = x * cos(theta))
# plot points to make sure the coordinates define the desired shape
coords %>%
plot_ly(x = ~xi, y = ~r, z = ~z, color = ~r)
#make a clean data frame with the things I need to plot so I don't get confused
X <- coords$xi
Y <- coords$r
Z <- coords$z
df1 <- data.frame(X, Y, Z)
head(df1)
#create the 3D plot with plotly
figsigma1 <- plot_ly(df1,
type = 'scatter3d',
mode='markers',
x = ~X,
y = ~Y,
z = ~Z,
marker = list(
color= ~Y,
colorscale = "Viridis",
cmax = 0.4,
cmin = 0,
colorbar=list(
title='Intensity (AU)'
),
reversescale =F
)
)
figsigma1
#now everything is repeated to create another plot where the function has sigma=2
r <- function(x,sigma,mu) 1/(sqrt(2*pi)*sigma)*(exp(-1*(x-mu)^2/2/(sigma^2)))
#centre distribution on 0
mu=0
#choose a sigma
sigma=2
#interval of interest on the x
int <- c(-5, 5)
# number of points along the x-axis
nx <- 1000
# number of points along the rotation
ntheta <- 100
# set x points and get corresponding radii = calculates the value of the function for all x points
coords <- data_frame(x = seq(int[1], int[2], length.out = nx), r = r(x, sigma, mu))
# for each r: rotate x to get xi and z coordinates
# edit: ensure 0 and pi are both amongst the angles used
coords %<>%
rowwise() %>%
do(data_frame(r = .$r, x = .$x,
theta = seq(0, pi, length.out = ntheta / 2 + 1) %>%
c(pi + .[-c(1, length(.))]))) %>%
ungroup %>%
mutate(xi = x * sin(theta), z = x * cos(theta))
# plot points to make sure the coordinates define the desired shape
coords %>%
plot_ly(x = ~xi, y = ~r, z = ~z, color = ~r)
#make a clean data frame with the things I need to plot so I don't get confused
X <- coords$xi
Y <- coords$r
Z <- coords$z
df2 <- data.frame(X, Y, Z)
head(df2)
figsigma2 <- plot_ly(df2,
type = 'scatter3d',
mode='markers',
x = ~X,
y = ~Y,
z = ~Z,
marker = list(
color= ~Y,
colorscale = "Viridis",
cmax = 0.4,
cmin = 0,
colorbar=list(
title='Intensity (AU)'
),
reversescale =F
)
)
figsigma2
This gives me the plots I wanted
At this point I wanted to have the two plots side by side, so I tried the below:
main_plot <- subplot(figsigma1, figsigma2)
main_plot
However, this seems to plot them on top of each other instead of side by side... any suggestion?
I am trying to plot 2 solids of revolution using plotly in R, and would like to obtain an image with both of the plots side by side. However, the plots seem to appear on top of each others instead.
I start creating a 3D scatter plot following the very useful example found in this answer.
In my case, I wanted to use a gaussian curve and rotate it around the Y axis, instead of X axis as in the example, so I modified the code as below:
#my test with gaussian
r <- function(x,sigma,mu) 1/(sqrt(2*pi)*sigma)*(exp(-1*(x-mu)^2/2/(sigma^2)))
#centre distribution on 0
mu=0
#choose a sigma
sigma=1
#interval of interest on the x
int <- c(-5, 5)
# number of points along the x-axis
nx <- 1000
# number of points along the rotation
ntheta <- 100
# set x points and get corresponding radii = calculates the value of the function for all x points
coords <- data_frame(x = seq(int[1], int[2], length.out = nx), r = r(x, sigma, mu))
# for each r: rotate x to get xi and z coordinates
# edit: ensure 0 and pi are both amongst the angles used
coords %<>%
rowwise() %>%
do(data_frame(r = .$r, x = .$x,
theta = seq(0, pi, length.out = ntheta / 2 + 1) %>%
c(pi + .[-c(1, length(.))]))) %>%
ungroup %>%
mutate(xi = x * sin(theta), z = x * cos(theta))
# plot points to make sure the coordinates define the desired shape
coords %>%
plot_ly(x = ~xi, y = ~r, z = ~z, color = ~r)
#make a clean data frame with the things I need to plot so I don't get confused
X <- coords$xi
Y <- coords$r
Z <- coords$z
df1 <- data.frame(X, Y, Z)
head(df1)
#create the 3D plot with plotly
figsigma1 <- plot_ly(df1,
type = 'scatter3d',
mode='markers',
x = ~X,
y = ~Y,
z = ~Z,
marker = list(
color= ~Y,
colorscale = "Viridis",
cmax = 0.4,
cmin = 0,
colorbar=list(
title='Intensity (AU)'
),
reversescale =F
)
)
figsigma1
#now everything is repeated to create another plot where the function has sigma=2
r <- function(x,sigma,mu) 1/(sqrt(2*pi)*sigma)*(exp(-1*(x-mu)^2/2/(sigma^2)))
#centre distribution on 0
mu=0
#choose a sigma
sigma=2
#interval of interest on the x
int <- c(-5, 5)
# number of points along the x-axis
nx <- 1000
# number of points along the rotation
ntheta <- 100
# set x points and get corresponding radii = calculates the value of the function for all x points
coords <- data_frame(x = seq(int[1], int[2], length.out = nx), r = r(x, sigma, mu))
# for each r: rotate x to get xi and z coordinates
# edit: ensure 0 and pi are both amongst the angles used
coords %<>%
rowwise() %>%
do(data_frame(r = .$r, x = .$x,
theta = seq(0, pi, length.out = ntheta / 2 + 1) %>%
c(pi + .[-c(1, length(.))]))) %>%
ungroup %>%
mutate(xi = x * sin(theta), z = x * cos(theta))
# plot points to make sure the coordinates define the desired shape
coords %>%
plot_ly(x = ~xi, y = ~r, z = ~z, color = ~r)
#make a clean data frame with the things I need to plot so I don't get confused
X <- coords$xi
Y <- coords$r
Z <- coords$z
df2 <- data.frame(X, Y, Z)
head(df2)
figsigma2 <- plot_ly(df2,
type = 'scatter3d',
mode='markers',
x = ~X,
y = ~Y,
z = ~Z,
marker = list(
color= ~Y,
colorscale = "Viridis",
cmax = 0.4,
cmin = 0,
colorbar=list(
title='Intensity (AU)'
),
reversescale =F
)
)
figsigma2
This gives me the plots I wanted
At this point I wanted to have the two plots side by side, so I tried the below:
main_plot <- subplot(figsigma1, figsigma2)
main_plot
However, this seems to plot them on top of each other instead of side by side... any suggestion?
Share Improve this question asked Mar 26 at 11:36 Annalisa BellandiAnnalisa Bellandi 275 bronze badges 2 |1 Answer
Reset to default 1You can do
library(htmltools)
browsable(
div(style = "display: flex; flex-wrap: wrap; justify-content: center",
div(figsigma1, style = "width: 50%;"),
div(figsigma2, style = "width: 50%;")
)
)
as described here - it's more flexible if you know your css.
Or a bit more concise
install.packages("manipulateWidget")
manipulateWidget::combineWidgets(figsigma1, figsigma2, nrow = 1)
as per this great answer.
library(htmltools); browsable(div(style = "display: flex; flex-wrap: wrap; justify-content: center", div(figsigma1, style = "width: 50%;"), div(figsigma2, style = "width: 50%;")))
should do it - as described here. This is similar to this post. Also funny shape ;) – Tim G Commented Mar 26 at 11:57install.packages("manipulateWidget"); manipulateWidget::combineWidgets(figsigma1, figsigma2, nrow = 1)
as per this – Tim G Commented Mar 26 at 12:12