一条零线对应两个y轴 [英] One zeroline for two y axis in 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
)
我想更改图形,以使左侧y的零线 轴移到右y轴的零线.因此, 小节也应该移动:
据我所知,无法在Plotly中直接进行此操作.但是您可以手动设置两个轴的 range
.>
对于您的栏,将以下行添加到其布局中:
range = c(max(df$VALUE) / max(df$LINE) * min(df$LINE), max(df$VALUE))
和您的台词:
range = c(min(df$LINE), max(df$LINE))
这将给出以下图形.
一种更简单的方法是将下限设置为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
)
This graph is generated with the following code:
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
)
I would like to change the graph so that the zeroline of the left y axis is shifted to the zeroline of the right y axis. Consequently the bars should be shifted too:
As far as I know there is no way of directly doing it in Plotly. But you could set the range
for both axes manually.
For your bars add the following line to its layout:
range = c(max(df$VALUE) / max(df$LINE) * min(df$LINE), max(df$VALUE))
and for your lines:
range = c(min(df$LINE), max(df$LINE))
which would give the followin graph.
An easier approach would be to set the lower limit to 0 which truncates the line graph.
In the code below an additional variable axis_buffer
was added to avoid that the range is exactly the lower and upper limit of your values.
For the sake of visual clarity I would remove some of the grid lines or try normalizing your data and adding the raw data to your hover info.
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
)
这篇关于一条零线对应两个y轴的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!