I created a graph through R's Plotly library.
The graph has 2 y-axis's and everything looks fine, except that the y-axis's are misaligned.
How do I "realign" it?
Python answer here
Had the same issue, add rangemode = "tozero" to your overlaying axis
plot_ly(data = dat,
x = x,
y = y,
type = "bar",
name = "Y") %>%
add_trace(data = par,
x = x,
y = Z,
name = "Z",
yaxis = "y2") %>%
layout(yaxis2 = list(overlaying = "y",
side = "right",
rangemode = "tozero"))
In the layout function, you can set axis ranges manually. You can use this to align them. Often, the scale of your two traces will be very different, though.
plot_ly(...) %>%
add_trace(..., yaxis = "y2") %>%
layout(
yaxis = list(
range = c(-2, 2)
),
yaxis2 = list(
range = c(-2, 2)
)
)
You can actually align primary and secondary y axes at any value (not just at 0) and for any plotting function by calculating new y axis limits. Here's a link to some code for a function that can handle any scenario: https://github.com/davidblakneymoore/A-Function-for-Aligning-Values-on-Primary-and-Secondary-Y-Axes-on-Plots-in-R.
This answer in python took JohnCoene's answer one step further:
https://community.plotly.com/t/align-multiple-y-axis-to-one-value-in-plotly/44500/2
The parameters scaleratio can be seen in further detail in the Plotly manual.
By constraining the left and right y-axes to one another you can adjust the scale at which they increase.
plot_ly(data = dat,
x = x,
y = y,
type = "bar",
name = "Y") %>%
add_trace(data = par,
x = x,
y = Z,
name = "Z",
yaxis = "y2") %>%
layout(yaxis = list(scaleanchor = 'y2',
scaleratio = 1, # Or perhaps 0.5 or 2, dep on your figure
constraintoward = 'bottom',
rangemode = "tozero"),
yaxis2 = list(scaleanchor = 'y',
scaleratio = 1, # Or perhaps 0.5 or 2, dep on your figure
overlaying = "y",
constraintoward = 'bottom'
side = "right",
rangemode = "tozero"))
Related
This question already has an answer here:
Add jitter to box plot using markers in plotly
(1 answer)
Closed 9 days ago.
I would like to obtain exactly the same result as the one presented here in the best answer of this post: Add jitter to box plot using markers in plotly, but without the boxplot itself keeping only the jitter points.
Is there a way to achieve this?
thank you for your answers.
Remove the add_trace. Using the literal code from that answer,
library(plotly)
set.seed(42)
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))
We see:
I'm trying to plot a 3D scatter using Plotly and R. Other than x, y and z I also would like to set the color of each point depending on a fourth variable.
I manage to set the plot correctly (the use of name = ~res is to show the value of res while hovering), but I am not able to change the name of the colorbar.
This is a mock code of what I've done:
library(tidyverse)
library(plotly)
a = seq(1,10,1)
b = seq(100,1000,100)
c = seq(1,4.9,0.4)
data = tibble(a,b,c)
data <- data %>% mutate(res = a+b+c)
layout_details <- list(xaxis = list(title = 'a [-]'),
yaxis = list(title = 'b [-]'),
zaxis = list(title = 'c [-]'),
coloraxis=list(colorbar=list(title=list(text='Here are the results'))))
p = plot_ly(data, x = ~a, y = ~b, z = ~c, color = ~res, type = 'scatter3d',
mode = 'markers', name = ~res, showlegend = FALSE, scene = 'scene1')
p <- p %>% layout(scene1 = layout_details)
p
I've noticed that a quite similar question was asked (R plotly to legend title value ignored for continuous color scatter plot), but without any answers.
Does anyone know how to solve this?
Thanks
You can define your colorbar inside the marker argument.
The name argument is interfering with the colorbar therefore I moved res from the name argument to the hovertemplate and the customdata.
Code
p = plot_ly(data, x = ~a, y = ~b, z = ~c,
name = "",
scene = 'scene1',
type = 'scatter3d',
mode = 'markers',
customdata = as.list(data$res),
hovertemplate = paste('x: %{x}',
'y: %{y}',
'z: %{z}',
'name: %{customdata}',
sep = "\n"),
marker = list(color = ~res,
colorbar = list(title = "Here are the results"),
colorscale='Viridis',
showscale = TRUE))
p <- p %>% layout(scene1 = layout_details)
p
Plot
I have 5 continuous variables that I'd like to graph together in R plotly.
I wrote the following code and got the plot to run as expected, but I cannot figure out how to deal with the legends. As is, the color legend appears, but the size legend does not.
I would like to plot both legends and control their locations within the plot. Suggestions from a similar post Adding color and bubble size legend in R plotly do not solve the problem.
Here's the code and sample data:
x<-sample(30)
y<-sample(30)
z<-sample(30)
c<-sample(30)
s<-sample(30)
fig <- plot_ly (x = x, y = y, z = z, color = c,
colors = c("#440154FF", "#1F968BFF", "#FDE725FF"), size = s,
marker = list(symbol = 'circle', sizemode = 'diameter'), sizes = c(1, 30))
fig <- fig %>% add_markers()
fig <- fig %>% layout(scene = list(xaxis = list (title = 'X'),
yaxis = list(title = 'Y'),
zaxis = list(title = 'Z'),
annotations = list(x = 1.05, y =1.02,
text = 'Gradient title',
xref = 'paper', yref = 'paper',
showarrow=FALSE, showlegend=TRUE)))
fig
It's been a while since this question was asked, but I have an answer. Initially, I tried to make the legend a subplot, but the legend from the 3D markers is offset from the plot-as-a-legend of bubble sizes. To fix that issue, I created an image of the bubbles and added it to the original plot as an image.
Using the information from fig in your original code, I created another figure (the bubbles and sizes).
figB <- plot_ly(x = 1, y = seq(30, 5, by = -5),
size = seq(30, 5, by = -5),
sizes = c(1, 30),
type = "scatter",
mode = "markers",
color = seq(30, 5, by = -5),
colors = c("#440154FF", "#1F968BFF", "#FDE725FF"),
marker = list(sizeref = 0.1,
sizemode = "area"),
height = 275, width = 100) %>%
layout(
xaxis = list(zeroline = F, showline = F, showticklabels = F, showgrid = F),
yaxis = list(showgrid = F, side = "right")) %>% # numbers on right (as fig legend)
hide_colorbar()
figB
I used three different libraries for this next part: htmlwidgets, webshot, and magick.
# create temp files
tmp <- tempfile(fileext = ".html") # plotly to html
tmp2 <- tempfile(fileext = ".png") # html to png
# create html
htmlwidgets::saveWidget(figB, tmp, background = "transparent")
# create png
webshot::webshot(tmp, tmp2, zoom = 2, vwidth = 150, vheight = 275) # to get great res
# make the png an object
itsBack <- magick::image_read(tmp2)
# check the amount of white space
magick::image_border(itsBack, "gray") # not too much white space; good res
unlink(tmp) # remove tempfile connection
unlink(tmp2)
For this last step, I copied the code from your original figure. The image needs to be added to layout. I removed code that didn't impact the figure, as well.
# set up placement of image below the initial legend
imgr = list(
source = raster2uri(as.raster(itsBack)),
xref = "paper",
yref = "paper",
y = .5, # paper domain is 0 to 1, this puts the top in the middle
x = .95, # almost all the way right
sizex = .45, # scale image down (0-1)
sizey = .45, # scale image down (0-1)
opacity = 1,
layer = "above")
# Rebuild fig without the initial legend - then add imgr to the legend
fig <- plot_ly (x = x, y = y, z = z, color = c,
colors = c("#440154FF", "#1F968BFF", "#FDE725FF"),
size = s,
marker = list(symbol = 'circle',
sizemode = 'diameter'),
sizes = c(1, 30))
fig <- fig %>% layout(
scene = list(xaxis = list(title = 'X'),
yaxis = list(title = 'Y'),
zaxis = list(title = 'Z')),
images = imgr) # adding bubbles here
fig
Depending on what you're doing with the graph, the placement and scaling may need to be adjusted. While plotly objects scale dynamically, the png won't be nearly as dynamic-friendly. The image is scaled down to 45% of its original size, so you have a lot of room to grow, but you may have to adjust those parameters (sizex and sizey). If you rescale your viewer window, you may also need to refresh the view. (Use the refresh icon in the Viewer pane.)
I'm trying to overlay a line chart and bar chart in plotly (with a vertical line designating an important date) and I'm encountering this issue where the two zero lines are offset instead of on the same line. I've tried messing around with the overlaying = 'y' option within layout and tried changing the order of the three trace components but nothing seems to help. Any ideas how to fix? Below is my code with dummy data:
(Also, bonus points if you can fix my legend-overlapping-y2axis issue)
date <- seq(as.Date("2015/6/1"), by = "month", length.out = 19)
wires_mnth <- c(rep(0,8),100000,750000,1200000,2500000,3100000,5500000,7500000,8000000,9900000,11300000,11000000)
wires_cnt <- c(rep(0,8),100,200,250,325,475,600,750,800,1000,1150,1200)
data <- data.frame(date, wires_mnth)
plot_ly(data) %>%
add_trace(x = ~date, y = ~wires_cnt, type = 'bar', name = 'Wires Count',
yaxis = 'y2', opacity = .5) %>%
add_trace(x = ~date, y = ~wires_mnth, type = 'scatter', mode = 'lines', name
= 'Monthly Wires') %>%
add_trace(x = c(2016,2016), y = c(0, 12000000), type = 'scatter', mode =
"lines", name = 'Sanctions Removed') %>%
layout(title = 'Monthly Aggregate Wire Transfers to Iran',
xaxis = list(title = ''),
yaxis = list(side = 'left', title = 'Wire Amounts (USD)', showgrid =
FALSE, zeroline = FALSE),
yaxis2 = list(side = 'right', overlaying = 'y', title = 'Wires Count',
showgrid = FALSE, zeroline = FALSE)
)
You could add rangemode='nonnegative' to your layout or specify the range manually via range=list(0, max(wires_mnth).
For your bonus question, you can set the x-position of the legend, e.g.
legend = list(x = 1.2)
I have a plotly graph in R with a reversed x-axis. I want to be able to play with its ranges. I know it is normal because by design, setting "range" turns "autorange" to "FALSE". https://plot.ly/r/reference/#layout-xaxis-range
But I still need to play with ranges of this reversed axes. Any workarounds, anyone?
Greetings
library(plotly)
s <- seq(1, 8)
plot_ly(x = s, y = s) %>%
add_trace(y = rev(s)) %>%
layout(
xaxis = list(range = c(3,5), autorange="reversed"),
yaxis = list(range = c(2, 5)))
Just retyping my comment above. Using plotly_3.4.3 (development version) and ggplot2_2.1.0. Remove autorange="reversed" from your code and try:
s <- seq(1, 8)
plot_ly(x = s, y = s) %>%
add_trace(y = rev(s)) %>%
layout( xaxis = list(range = c(5,3)), yaxis = list(range = c(2, 5)))