I created following 3d plot using plotly in R.
library(plotly)
library(MASS)
mu_v=c(0.5,0.4,0.5,0.2)
sigma_m=matrix(data = c(1,0.5,0.7,0.4,0.5,1,0.8,0.9,0.7,0.8,1,0.5,0.4,0.9,0.5,1),nrow = 4,byrow = T)
data1=mvrnorm( 10000,mu = mu_v , Sigma = sigma_m )
data1=as.data.frame(data1)
colnames(data1)=c("X1","X2","X3","X4")
plot_ly(x=~X1, y=~X2, z=~X3, type="scatter3d", color=~(X4), mode="markers",data = data1
, marker = list(
size = 5,
opacity = 10)) %>% layout(plot_bgcolor = "#bababa")
Is there a way to change the labels of axis and the coloring variable ? Also Can I change the background of the xy,yz and xz surface and increase the plotting area?
Update
I tried to edit the legend and change the background color as follows:
plot_ly(x=~X1, y=~X2, z=~X3, type="scatter3d", color=~(X4), mode="markers",data = data1
, marker = list(
size = 5,
opacity = 10)) %>%
layout(scene = list(legend = list(title = "legend"),plot_bgcolor='#e5ecf6'))
But it didnt work
Here is an option to address your first 2 questions (change x/y/z axis and color legend titles).
plot_ly(
x = ~X1,
y = ~X2,
z = ~X3,
type = "scatter3d",
mode = "markers",
data = data1,
marker = list(
color = ~X4,
colorbar = list(title = "Legend"), # Change colour legend title
colorscale = "Blues", # Change colour palette
size = 5,
opacity = 10)) %>%
layout(
plot_bgcolor = "#bababa",
scene = list(
xaxis = list(title = "Axis 1"), # Change x/y/z axis title
yaxis = list(title = "Axis 2"),
zaxis = list(title = "Axis 3")))
I'm trying to set the colour in R for "points" or markers in plotly with a custom palette. It doesn't work. I'm also trying to add a title to the graph, but it won't appear. In addition, I'd like to remove some elements of the legend (like the extra "z") and add a title to the legend elements. Nothing seems to work, even if it is present in the code.
library(plotly)
library(tidyverse)
set.seed(123456)
pal <- c("black", "orange", "darkgreen", "pink")
pal <- setNames(pal, levels(as.factor(c("gr1","gr2","gr3","gr4"))))
linedat = data.frame(x = rep(mean(1:50),2),
y = rep(mean(1:50),2),
z = c(0,1))
zoom = 3
pg = plotly::plot_ly(x = 1:50,
y = 1:50,
z = outer(1:50,1:50,"+")/100) %>%
add_surface(contours = list(
z = list(show = TRUE, start = 0, end = 1, size = 0.05)),
opacity = 1) %>%
add_markers(x = rnorm(50,25,5),
y = rnorm(50,25,5),
marker = list(opacity = 0.9),
type="scatter3d",
mode = "markers",inherit = FALSE,
colors = pal,
color = as.factor(sample(1:4,50,replace = T)),
z = rbinom(50,1,.5)) %>%
layout(scene=list(title = "Title won't show up????",
xaxis = list(title = 'trait1'),
yaxis = list(title = 'trait1',autorange = "reversed"),
camera = list(eye = list(x = cos(0.8*pi)*zoom, y = sin(pi*1.3)*zoom, z= 2.00)),
legend = list(title=list(text='<b> Groups </b>')))) %>%
add_trace(data=linedat, x=~x, y=~y, z=~z,
type="scatter3d", mode="lines",
line = list(color = pal[1],
width = 14),name = "Avg. data1")%>%
add_trace(data=linedat, x=~x+20, y=~y+20, z=~z,
type="scatter3d", mode="lines",
line = list(color = pal[4],
width = 14),name = "Avg. data2")
pg
See how here I'm able to set the colour of the points, but I'm not able to get the names of the colours to show in the legend (I modified the code to match what #Kat suggested):
library(plotly)
library(tidyverse)
set.seed(123456)
pal <- c("black", "orange", "darkgreen", "pink")
pal <- setNames(pal, levels(as.factor(c("gr1","gr2","gr3","gr4"))))
linedat = data.frame(x = rep(mean(1:50),2),
y = rep(mean(1:50),2),
z = c(0,1))
zoom = 3
pg = plotly::plot_ly(x = 1:50,
y = 1:50,
z = outer(1:50,1:50,"+")/100) %>%
add_surface(contours = list(
z = list(show = TRUE, start = 0, end = 1, size = 0.05)),
opacity = 1, colorbar = list(title = "Only one Z")) %>%
add_markers(x = rnorm(50,25,5),
y = rnorm(50,25,5),
marker = list(color = pal[as.factor(sample(1:4,50,replace = T))],opacity = 0.9),
type="scatter3d",
mode = "markers",inherit = FALSE,
colors = pal,
z = rbinom(50,1,.5)) %>%
layout(title = "Title that won't show",
margin = list(t = 40),
legend = list(title = list(
text = "<br>Legends deserve names, too")),
scene=list(xaxis = list(title = 'trait1'),
yaxis = list(title = 'trait1',autorange = "reversed"),
camera = list(eye = list(x = cos(0.8*pi)*zoom,
y = sin(pi*1.3)*zoom, z= 2.00)))) %>%
add_trace(data=linedat, x=~x, y=~y, z=~z,
type="scatter3d", mode="lines",
line = list(color = pal[1],
width = 14),name = "Avg. data1")%>%
add_trace(data=linedat, x=~x+20, y=~y+20, z=~z,
type="scatter3d", mode="lines",
line = list(color = pal[4],
width = 14),name = "Avg. data2");pg
Your original plot_ly call and add_trace calls can remain as is. I've included the changes needed for the layout call and added the call needed for colorbar.
The layout first.
layout(title = "Title that won't show", # <------ give my plot a name
margin = list(t = 40), # don't smash that title, either
legend = list(title = list(
text = "<br>Legends deserve names, too")), # <--- name my legend
scene=list(title = "Title won't show up????", # <- this can go away
xaxis = list(title = 'trait1'),
yaxis = list(title = 'trait1',autorange = "reversed"),
camera = list(eye = list(x = cos(0.8*pi)*zoom,
y = sin(pi*1.3)*zoom, z= 2.00)),
legend = list(title=list(text='<b> Groups </b>')))) %>%
colorbar(title = "Only one Z") # <--- give me one z colorbar title
(Some colors are different in the image; I didn't realize I had the pal object...sigh)
Update
This addresses your additional questions.
First, I'm not getting an error from the method in which I title the color bar. You'll have to share what error you're getting.
I didn't realize that it was ignoring the colors you set in markers, either. The easiest way to address this is to call that trace first. Since nothing else was declared within markers, I called opacity outside of the list, but it's fine the way you have it.
First, I commented out the setNames call, because that won't work for the marker's trace and it doesn't matter to the other traces.
library(plotly)
set.seed(123456)
pal <- c("black", "orange", "darkgreen", "pink")
# pal <- setNames(pal, levels(as.factor(c("gr1","gr2","gr3","gr4"))))
linedat = data.frame(x = rep(mean(1:50),2),
y = rep(mean(1:50),2),
z = c(0,1))
zoom = 3
I made plot_ly() empty and put all the data for the surface in that trace. I also added inherit = false so that the layout could go at the end without the data errors.
set.seed(123456)
pg = plotly::plot_ly() %>%
add_trace(inherit = F,
x = rnorm(50,25,5),
y = rnorm(50,25,5),
type="scatter3d",
mode = "markers",
opacity = .8,
colors = pal,
color = as.factor(sample(1:4, 50, replace = T)),
z = rbinom(50,1,.5)) %>%
add_surface(x = 1:50,
y = 1:50,
z = outer(1:50,1:50,"+")/100,
colorscale = "Viridis",
contours = list(
z = list(show = TRUE, start = 0, end = 1, size = 0.05)),
opacity = 1) %>%
add_trace(data=linedat, x=~x, y=~y, z=~z,
type="scatter3d", mode="lines",
line = list(color = pal[1],
width = 14),name = "Avg. data1", inherit = F) %>%
add_trace(data=linedat, x=~x+20, y=~y+20, z=~z,
type="scatter3d", mode="lines",
line = list(color = pal[4],
width = 14),name = "Avg. data2", inherit = F) %>%
The last part is the layout, but this is not different than my original answer.
layout(title = "Title that won't show", # <------ give my plot a name!
margin = list(t = 40), # don't smash that title, either
legend = list(title = list(
text = "<br>Legends deserve names, too"),
tracegroupgap = 350), # <--- name my legend!
scene=list(title = "Title won't show up????", # <--- this can go away!
xaxis = list(title = 'trait1'),
yaxis = list(title = 'trait1',autorange = "reversed"),
camera = list(eye = list(x = cos(0.8*pi)*zoom,
y = sin(pi*1.3)*zoom, z= 2.00)),
legend = list(title=list(text='<b> Groups </b>')))) %>%
colorbar(title = "Only one Z") # <--- give me one z for the title!
pg
I have a list of figures created with R's plotly, just as an example:
library(plotly)
library(dplyr)
set.seed(1)
data.df <- data.frame(val = c(rnorm(100,0,1),rnorm(100,1,1)), group = c(rep("A",100),rep("B",100)))
density.df <- do.call(rbind,lapply(levels(data.df$group),function(g){
dens <- density(dplyr::filter(data.df,group == g)$val)
data.frame(x = dens$x, y = dens$y, group = g)
}))
plot.list <- lapply(1:5,function(x)
plot_ly(x = density.df$x, y = density.df$y, type = 'scatter', mode = 'lines',color = density.df$group, showlegend = (x == 5)) %>%
layout(xaxis = list(title= "Value", zeroline = F), yaxis = list(title = "Density", zeroline = F))
)
Which I'd like to put together horizontally, where there will be only a single shared x-axis label and a single shared y-axis label.
I'm using:
plotly::subplot(plot.list, nrows = 1, shareX = T, shareY = T, titleX = T, titleY = T)
And getting:
Is it not possible to get a single x-axis label in a horizontal plot?
The same occurs for the y-axis label if I change the nrows argument value from 1 to 5.
You can manually add an annotation
https://community.plot.ly/t/subplots-how-to-add-master-axis-titles/13927/5
myplotly(df) %>%
add_annotations(
text = "my x title",
x = 0.5,
y = 0,
yref = "paper",
xref = "paper",
xanchor = "center",
yanchor = "bottom",
yshift = -35,
showarrow = FALSE,
font = list(size = 15)
)
I made a boxplot:
dat %>%
plot_ly(y = ~xval, color = ~get(col), type = "box",
boxpoints = "all", jitter = 0.7,
pointpos = 0, marker = list(size = 3),
source = shiny_source, key = shiny_key,
hoverinfo = 'text', text = txt)
but problem is that jittered points are not interactive and cannot be marked separately, so I came with an idea to add those points using add_markers:
dat %>%
plot_ly(y = ~xval, color = ~get(col), type = "box",
boxpoints = FALSE, jitter = 0.7,
pointpos = 0, marker = list(size = 3),
source = shiny_source, key = shiny_key,
hoverinfo = 'col', text = txt
) %>%
add_markers(x = ~get(col), y = ~varval, size = I(6))
but now points are in straight line and I'd like to add some jitter (for example by using beeswarm package). But I don't know how to get coordinates of qualitative variable IC0 on X axis. Any ideas?
I find myself in the same potential case often with plotly and ggplot2-- 3 lines of code to get 90% of what I want, and 30 lines of code to get the aesthetics just right.
One potential solution/workaround: Take advantage of R's "factors are coded with integers" paradigm, plot everything on a numeric scale, and then cover your tracks by hiding x labels and x hover values.
dat <- data.frame(xval = sample(100,1000,replace = TRUE),
group = as.factor(sample(c("a","b","c"),1000,replace = TRUE)))
dat %>%
plot_ly() %>%
add_trace(x = ~as.numeric(group),y = ~xval, color = ~group, type = "box",
hoverinfo = 'name+y') %>%
add_markers(x = ~jitter(as.numeric(group)), y = ~xval, color = ~group,
marker = list(size = 6),
hoverinfo = "text",
text = ~paste0("Group: ",group,
"<br>xval: ",xval),
showlegend = FALSE) %>%
layout(legend = list(orientation = "h",
x =0.5, xanchor = "center",
y = 1, yanchor = "bottom"
),
xaxis = list(title = "Group",
showticklabels = FALSE))
Yields the following
I am plotting bubble chart using Plotly in R. But when I give labels using add_annotations labels overlap and its very difficult to read them. how to prevent this overlapping in plotly. I have tried "geom_label_repel" but its not working with plotly as it gives error.
My Code is
plot_ly(bubbleChartData, x = ~Category1, y = ~Category2, type = 'scatter', mode = 'markers', size = ~BubbleSize,
color = ~Category3, colors = brewer.pal(8,"Dark2"),
marker = list( sizemode = 'diameter'), text=~Category4) %>%
add_annotations( showarrow=F,xanchor="right",xref = "x",ax = 20,
ay = -40,
yref = "y",x = ~Category1, y = ~Category2, text=~Category4,font = list(size = 10))%>%
layout(title = '',font=list(size=10),
xaxis = list(
title = "",
showgrid=FALSE,
showline=FALSE,
tickfont = list(
size = 16,
color = 'rgb(0,0,0)'),
titlefont = list(
size = 18,
color = 'rgb(0,0,0)')),
yaxis = list(
title = "",
showgrid=FALSE,
showline=FALSE,
titlefont = list(
size = 18,
color = 'rgb(0,0,0)'),
tickfont = list(
size = 16,
color = 'rgb(0,0,0)')),
showlegend = F)