绘图中两个 y 轴的一条零线

Fel*_*ann 5 r plotly

在此输入图像描述

该图是使用以下代码生成的:

library(tidyverse)
library(plotly)

df <- data.frame(
      DEP = c("ABC", "DEF", "GHI")
      , VALUE = c(100, 110, 120)
      , LINE = c(-0.1, 0.7, 0.9)
    )

xAxis <- list(
  title = ""
  , tickangle = 0
  , tickfont = list(size = 10)
)

yAxis <- list(
  side = "left"
  , showgrid = TRUE
  , zeroline = TRUE
  , title = ""
)

yAxis2 <- list(
  side = "right"
  , autotick = FALSE
  , ticks = "outside"
  , tick0 = 0
  , dtick = 0.1
  , showgrid = TRUE
  , zeroline = TRUE
  , overlaying = "y"
)

plot_ly(data = df, x = ~DEP) %>%
  add_trace(data = df, x = ~DEP, y = ~VALUE, name = 'VALUE', type = "bar", yaxis = "y", textposition = "auto") %>%
  add_trace(data = df, x = ~DEP, y = ~LINE, name = 'LINE', mode = "lines", type = "scatter",
            line = list(width = 4), yaxis = "y2") %>%
  layout(
    margin = list(r=50, b = 150)
    , xaxis = xAxis
    , yaxis = yAxis
    , yaxis2 = yAxis2
    , showlegend = FALSE
  )
Run Code Online (Sandbox Code Playgroud)

我想更改图形,以便左 y 轴的零线移动到右 y 轴的零线。因此,条形图也应该移动:

在此输入图像描述

Max*_*ers 7

据我所知,没有办法直接在 Plotly 中做到这一点。但您可以range手动设置两个轴。

对于您的栏,将以下行添加到其布局中:

range = c(max(df$VALUE) / max(df$LINE) * min(df$LINE), max(df$VALUE))
Run Code Online (Sandbox Code Playgroud)

对于你的台词:

range = c(min(df$LINE), max(df$LINE))
Run Code Online (Sandbox Code Playgroud)

这将给出下图。 在此输入图像描述

一种更简单的方法是将下限设置为 0,这会截断折线图。

在下面的代码中axis_buffer添加了一个附加变量,以避免该范围恰好是值的下限和上限。

为了视觉清晰度,我会删除一些网格线或尝试标准化您的数据并将原始数据添加到您的悬停信息中。

library('plotly')
df <- data.frame(
  DEP = c("ABC", "DEF", "GHI")
  , VALUE = c(100, 110, 120)
  , LINE = c(-0.1, 0.7, 0.9)
)

axis_buffer <- 1.1

xAxis <- list(
  title = ""
  , tickangle = 0
  , tickfont = list(size = 10)
)

yAxis <- list(
  side = "left"
  , showgrid = TRUE
  , zeroline = TRUE
  , title = ""
  , range = c(max(df$VALUE) / max(df$LINE) * min(df$LINE) * axis_buffer, max(df$VALUE) * axis_buffer)
)

yAxis2 <- list(
  side = "right"
  , autotick = FALSE
  , ticks = "outside"
  , tick0 = 0
  , dtick = 0.1
  , showgrid = TRUE
  , zeroline = TRUE
  , overlaying = "y"
  , range = c(min(df$LINE) * axis_buffer, max(df$LINE) * axis_buffer)
)

plot_ly(data = df, x = ~DEP) %>%
  add_trace(data = df, x = ~DEP, y = ~VALUE, name = 'VALUE', type = "bar", yaxis = "y", textposition = "auto") %>%
  add_trace(data = df, x = ~DEP, y = ~LINE, name = 'LINE', mode = "lines", type = "scatter",
            line = list(width = 4), yaxis = "y2") %>%
  layout(
    margin = list(r=50, b = 150)
    , xaxis = xAxis
    , yaxis = yAxis
    , yaxis2 = yAxis2
    , showlegend = FALSE
  )
Run Code Online (Sandbox Code Playgroud)