Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing traces when supplying a dual-axis plot to subplot() #954

Open
dfernan opened this issue Apr 20, 2017 · 23 comments
Open

Missing traces when supplying a dual-axis plot to subplot() #954

dfernan opened this issue Apr 20, 2017 · 23 comments
Labels

Comments

@dfernan
Copy link

dfernan commented Apr 20, 2017

If I do:

library(plotly)
ay <- list(
tickfont = list(color = "red"),
overlaying = "y",
side = "right",
title = "second y axis"
)
p <- plot_ly() %>%
add_lines(x = ~1:3, y = ~10*(1:3), name = "slope of 10") %>%
add_lines(x = ~2:4, y = ~1:3, name = "slope of 1", yaxis = "y2") %>%
layout(
title = "Double Y Axis", yaxis2 = ay,
xaxis = list(title="x")
)

It plots both axis.
image

but if I do:
subplot(p)
I loose the secondary axis.
image

This doesn't seem like the intended behavior of subplot unless I am missing something. Thanks!

@cpsievert
Copy link
Collaborator

Try subplot(p, titleY = T)

@dfernan
Copy link
Author

dfernan commented Apr 20, 2017

Thanks. I tried, I see this:
image
so not real change from not putting that option in. Maybe it's a version issue? I am running R on windows, R version 3.3.3 (2017-03-06), and plotly appears to be version 4.5.6. Does 4.5.6 refers to the Rplotly version or to the plotly.js version?

@cpsievert
Copy link
Collaborator

Sorry, I mis-read the problem. This is, in fact, a bug.

@cpsievert cpsievert reopened this Apr 20, 2017
@cpsievert cpsievert changed the title bug in subplot Missing traces when supplying a dual-axis plot to subplot() Apr 20, 2017
@dfernan
Copy link
Author

dfernan commented Apr 20, 2017

such legit tile: Missing traces when supplying a dual-axis plot to subplot() :-)

@cpsievert cpsievert added the bug label Apr 21, 2017
@pepe-enriquez
Copy link

Hi,
I have been trying to use subplot() with dual axis, and face a similar (I think related) problem. I had built an example of my problem, and seeing that there is this open issue, I provide it here in case it is helpful.

I build two double axis plots with economics dataset:

# using "economics" dataset

# Create two 2-axis plots
# Plot 1: pop in y1 and psavert in y2
p1 <- economics %>% plot_ly() %>%  
  add_lines(x = ~date, y = ~pop,name="pop") %>%
  add_lines(x = ~date, y = ~psavert,name="psavert",yaxis = "y2") %>%
  layout(
    title ="Plot1",
    legend=list(x=1.1,y=1.1),
    yaxis = list(title="pop"),
    yaxis2 = list(side = "right",  overlaying = "y",title = "psavert")
  )

# Plot 2: pop in y1 and uempmed in y2
p2 <- economics %>% plot_ly() %>%  
  add_lines(x = ~date, y = ~pop,name="pop2") %>%
  add_lines(x = ~date, y = ~uempmed,name="uempmed2",yaxis = "y2") %>%
  layout(
    title ="Plot2",
    legend=list(x=1.1,y=1.1),
    yaxis = list(title="pop"),
    yaxis2 = list(side = "right",  overlaying = "y",title = "uempmed")
  )

If I compose a subplot with independen X axes

# Render the two together with subplot(), 2 X axes
p3 <- subplot(p1,p2,nrows=2)

imagen

If I set the shareX to TRUE:

# Render the two together with subplot(), 1 X axes
p3 <- subplot(p1,p2,nrows=2,shareX=T)

imagen

Seems like all operation on the second axis go to the same plot inside subplot.
Hope this helps.

@dfernan
Copy link
Author

dfernan commented Jul 21, 2017

@cpsievert any updated with respect to this issue? Thanks!

@msummersgill
Copy link
Contributor

Having the same issue, have a hunch the fix might be some additions to the axis handling in
in subplots.R.

For example, when gathering layout attributes, yaxis2, yaxis3...yaxisN are not included in the existing list, c("mapbox", "geo", "xaxis", "yaxis"). Seems like adding the additional axis objects to this line and all others handling axes might solve this issue (utilizing generated sequences of names and regexes where possible to avoid manually typing all possible iterations of yaxis2, yaxis3...yaxisN, and y2, y3... yN).

@cpsievert Does this seem like the right path to head down? If so I'll open a PR and start working sometime this week.

lines 90-117 of subplots.R:

plots <- list()
  for (i in seq_along(plotz)) {
    p <- plots[[i]] <- plotz[[i]]
    layoutAttrs <- c(names(p$layout), c("mapbox", "geo", "xaxis", "yaxis"))
    xTraceAttrs <- sub("^x", "xaxis", sapply(p$data, function(tr) tr[["subplot"]] %||% tr[["geo"]] %||% tr[["xaxis"]] %||% "x"))
    yTraceAttrs <- sub("^y", "yaxis", sapply(p$data, function(tr) tr[["subplot"]] %||% tr[["geo"]] %||% tr[["yaxis"]] %||% "y"))
    missingAttrs <- setdiff(c(xTraceAttrs, yTraceAttrs), layoutAttrs)
    # move to next iteration if trace references are complete
    if (!length(missingAttrs)) next
    # remove each "missing" trace from this plot
    missingTraces <- xTraceAttrs %in% missingAttrs | yTraceAttrs %in% missingAttrs
    plots[[i]]$data[missingTraces] <- NULL
    # move traces with "similar missingness" to a new plot
    for (j in missingAttrs) {
      newPlot <- list(
        data = p$data[xTraceAttrs %in% j | yTraceAttrs %in% j],
        layout = p$layout
      )
      # reset the anchors
      newPlot$data <- lapply(newPlot$data, function(tr) {
        for (k in c("mapbox", "geo", "xaxis", "yaxis")) {
          tr[[k]] <- sub("[0-9]+", "", tr[[k]]) %||% NULL
        }
        tr
      })
      plots <- c(plots, list(newPlot))
    }
  }

@msummersgill
Copy link
Contributor

Another reprex:

library(plotly)

## Create a data frame with data to be plotted
S <- seq(1,100)
DF <- data.frame(S = S, A = S, B = sin(S), C = S^2)

## Create first plot, 'P_A' with trace 'A'
A_Axis <- list(side = "left", title = "Axis A")

DF %>% 
plot_ly() %>% 
  add_lines(x = ~S , y = ~ A, yaxis = "y", name = "A",color = I("red")) %>%
  layout(yaxis = A_Axis) -> P_A

## Create second plot, 'P_BC', with traces 'B' and 'C'
B_Axis <- list(side = "left", title = "Axis B")
C_Axis <- list(side = "right", title = "Axis C", overlaying = "y")

DF %>% 
plot_ly() %>% 
  add_lines(x = ~S , y = ~ B, yaxis = "y", name = "B", color = I("blue")) %>%
  add_lines(x = ~S , y = ~ C, yaxis = "y2", name = "C", color = I("green")) %>%
  layout(yaxis = B_Axis,
         yaxis2 = C_Axis) -> P_BC

## Create a subplot- Trace 'C' is added to the first plot instead of the second
subplot(list(P_A,P_BC),nrows = 2,titleY = TRUE, shareX = TRUE)

image

@cpsievert
Copy link
Collaborator

@msummersgill for some reason, subplot() is incorrectly changing the trace anchor numbering. To see that, take the first example and do:

diffObj::diffObj(plotly_build(p)$x$data, subplot(p)$x$data)

I'm not sure why this is happening, but if you think you have a solution, I'd love to see a pull request!

@nc-savoy
Copy link

nc-savoy commented Nov 8, 2017

Hi,
fairly new to github, coding and plotly.

Faced with a similar issue replacing
overlaying="y"
with
overlaying="y2"
in the axis definition solved my issue.

I hope it helps

@msummersgill
Copy link
Contributor

Thank you very much @nc-savoy ! I feel like I still have a tenuous grasp of exactly how this is working, but that method also works for more than two plots in a subplots. (After some trial and error)

library(plotly)

## Create a data frame with data to be plotted
S <- seq(1,100)
DF <- data.frame(S = S, A = S, B = sin(S), C = S^2, D = 1/S, E = S^3 + S^3*cos(S))

## Create first plot, 'P_A' with trace 'A'
A_Axis <- list(side = "left", title = "Axis A")

DF %>% 
plot_ly() %>% 
  add_lines(x = ~S , y = ~ A, yaxis = "y", name = "A",color = I("red")) %>%
  layout(yaxis = A_Axis) -> P_A

## Create second plot, 'P_BC', with traces 'B' and 'C'
B_Axis <- list(side = "left", title = "Axis B")
C_Axis <- list(side = "right", title = "Axis C", overlaying = "y2")


DF %>% 
plot_ly() %>% 
  add_lines(x = ~S , y = ~ B, yaxis = "y", name = "B", color = I("blue")) %>%
  add_lines(x = ~S , y = ~ C, yaxis = "y2", name = "C", color = I("green")) %>%
  layout(yaxis = B_Axis,
         yaxis2 = C_Axis) -> P_BC


## Create third plot, 'P_DE', with traces 'D' and 'E'
D_Axis <- list(side = "left", title = "Axis D")
E_Axis <- list(side = "right", title = "Axis E", overlaying = "y4")

DF %>% 
plot_ly() %>% 
  add_lines(x = ~S , y = ~ D, yaxis = "y", name = "D", color = I("orange")) %>%
  add_lines(x = ~S , y = ~ E, yaxis = "y5", name = "E", color = I("purple")) %>% 
  layout(yaxis = D_Axis,
         yaxis5 = E_Axis) -> P_DE

## Create a subplot
subplot(list(P_A,P_BC,P_DE),nrows = 3,titleY = TRUE, shareX = TRUE)

image

@ghost
Copy link

ghost commented Apr 19, 2018

Trying to make sense of this example. Why are data and title for series E linked to y4 and y5, rather than both to the same y, or even both to y2? And related to that; why is series C linked to y2 (in contrast to E on y4/y5) and not for instance y3 or y5 for that matter. Are the axis counted on the left all y1 and on the right as y2 or is it a series of y1-y6?

In an approach I used, I create the panels automatically in a purrr::map structure so its hard to assign y'n' to each plots secondary axis. Coding it to append y2 to all secondary axes put all those traces and ticks on top of each other in the first row of panels in a 3*3 subplot page

@slfan2013
Copy link

facing same bug

@ghost
Copy link

ghost commented May 30, 2018

Any more insight on how to make this work in a generic fashion?

I'm doing a lapply on a plotting function that does this different number of subplots depending on the data. (with an upper end of 5 sub plots each with their own dual axes)

@gponce-ars
Copy link

I'm trying to make a similar plot related to this post and similar to the image below.

image

The interesting part is in the second-y-axis... it was split into two scales while the left y-axis is shared for all datasets.

  • The brown line corresponds to the left-y-axis.
  • The pink bars are linked to the top-right y-axis and bottom blue bars to the bottom right y-axis.
  • All plots share X-axis.

Is it possible in plotly to make the left y-axis and x-axis shared?

@mabreidi
Copy link

mabreidi commented Jan 13, 2019

For anyone facing this issue, this is the approach that worked for me

Setting all the yaxis arguments in add_trace() for the left y axis to "y".
Setting all the yaxis arguments in add_trac() for the right y axis to "y2"
Setting the "overlaying" argument in the layout for the second y axis to "y" for the first subplot, "y3" for the second, "y5" for the third and so on.

It's also important to assign the "left" attribute to the left y-axes, even though that's the default. I've found it won't work otherwise.

y <- rnorm(20,5,1)
y2 <- rnorm(20,10,2)

df <- data.frame(x,y,y2)

library(plotly)
p1 <- plot_ly() %>% add_trace(x=df$x,y=df$y,type="scatter",mode="lines",yaxis="y") %>%
                    add_trace(x=df$x,y=df$y2,type="scatter",mode="lines",yaxis="y2") %>%
                    layout(yaxis=list(side="left"),
                           yaxis2=list(side="right",overlaying="y"),
                           showlegend=FALSE)

p2 <-plot_ly() %>% add_trace(x=df$x,y=df$y+df$y2,type="scatter",mode="lines",yaxis="y") %>%
                 add_trace(x=df$x,y=df$y2*df$y,type="scatter",mode="lines",yaxis="y2") %>%
                layout(yaxis=list(side="left"),
                       yaxis2=list(side="right",overlaying="y3"),
                       showlegend=FALSE)

p <- subplot(p1,p2,nrows = 2)

image

@JulianStopp
Copy link

For one of my apps I had to use multiple y axis and discovered that using "anchor='free'" will lead to the issue that subplot will not display the plot at all. Hence, once can not manually rearrange the axis when you have more than 2.

@PAllen0518
Copy link

PAllen0518 commented Nov 30, 2021

It seems this bug is still alive. I needed to use the workaround provided by mabreidi to address loss of data with 4 dual yaxis subplots.

@nitram9
Copy link

nitram9 commented Jan 7, 2022

I wish this would be in the official documentation because I would otherwise have never found out about this!

@dishutin
Copy link

@mabreidi thank you so much for this! I've literally spent more than 2 hours trying to figure out what was going on with my charts
🙏🙏🙏

@Padiol
Copy link

Padiol commented Mar 8, 2022

Hey guys,

I was running into the same problem. Found a way to solve it (basically the same @mabreidi proposed) but the axis titles are not showing up.
If you guys found a way to make them appear I'm up for the tip!

Cheers

Found it ==> subplot(........ titleY=T)

@fabianjkrueger
Copy link

Hey, @mabreidi ! Thanks so much! This is incredible! You saved us all so much time and frustration!

@romanzenka
Copy link

I have submitted PR #2401 that makes @mabreidi August 7th reprex look like this:

Image

... I think that is what was desired.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests