plotly / plotly.js

Open-source JavaScript charting library behind Plotly and Dash
https://plotly.com/javascript/
MIT License
16.93k stars 1.85k forks source link

axisDraw: Hitting ax.domain[1] < ax.domain[0] #6499

Open zeehio opened 1 year ago

zeehio commented 1 year ago

Using plotly from R, I have a complex plot that creates a long legend (I'm having issues hiding it). Anyway, I guess spacing becomes so tight that I end up getting a scenario where ax.domain[1] < ax.domain[0] when titleHeight / gs.h is subtracted from ax.domain[1]. This ends up giving me pain with a negative ax._length that throws the error 'Something went wrong with axis scaling'.

https://github.com/plotly/plotly.js/blob/7427f14ad1b175ca1f4bda23c0ce763fa88791b8/src/components/colorbar/draw.js#L469

A more robust alternative could be:

ax.domain[1] = Math.max(ax.domain[1] - titleHeight / gs.h, ax.domain[0]);

Or maybe we need ax.domain[0] be strictly less than ax.domain[1]. I have no idea

Apologies for not being able to provide a reproducible example. I will do my best, to provide it, but it's not easy due to all the layers (my plot, ggplot, plotly (R), plotly (javascript)).

zeehio commented 1 year ago

Here is my code simplified:

library(ggplot2)
library(plotly)

set.seed(42)
# We generate a plot with two legends, one of them being that long that the whole plot fails.
# The threshold where the whole plot fails depends on the size of the window where the plot is rendered.

# First we generate some data:
num_rect <- 34
rectangles <- data.frame(
  PeakID = sprintf("Peak%02d", seq_len(num_rect)),
  xmin = runif(num_rect, 0, 12),
  ymin = runif(num_rect, 0, 900)
)
rectangles$xmax <- rectangles$xmin + runif(num_rect, 1, 3)
rectangles$ymax <- rectangles$ymin + runif(num_rect, 50, 200)

# Then we generate a plot with all those rectangles
gplt1 <- ggplot() +
  geom_rect(
    data = rectangles,
    mapping = aes(
      xmin = xmin, 
      xmax = xmax,
      ymin = ymin,
      ymax = ymax,
      color = PeakID,
      fill = xmax
    )
  )

# This is how the plot looks like:
gplt1

imatge

# This is what I can see at the console, besides  a blank plot
ggplotly(gplt1)

imatge

I converted the plot to json and here is attached as a zip file:

gplt_list <- plotly::gg2list(gplt1)
plotly:::to_JSON(gplt_list)

plot.json.zip

gvwilson commented 3 months ago

Hi - we are trying to tidy up the stale issues and PRs in Plotly's public repositories so that we can focus on things that are still important to our community. Since this one has been sitting for several years, I'm going to close it; if it is still a concern, please add a comment letting us know what recent version of our software you've checked it with so that I can reopen it and add it to our backlog. Thanks for your help - @gvwilson

zeehio commented 3 months ago

The reproducible example is still reproducible, so please reopen @gvwilson