在 R plotly 中使用线迹为堆叠条形图创建次轴
Create secondary axis for stacked barplot with line trace in R plotly
我正在实现一个函数,该函数构建一个带有附加线迹的堆叠 % 条形图。我可以使用宽格式或长格式数据框创建堆积条形图。下面的两个代码部分生成的图看起来基本相同:
使用宽格式数据框:
library(dplyr)
library(plotly) # install.packages("plotly")
# simple example data for SO post
some_dates = c(as.Date('2021-01-01'), as.Date('2021-02-01'),
as.Date('2021-03-01'), as.Date('2021-04-01'))
bar1 = c(0.25,0.45,0.65,0.75)
bar2 = c(0.60,0.40,0.20,0.10)
bar3 = c(0.15,0.15,0.15,0.15)
line_data = c(0,1,2,3)
# wide form dataframe
df_bars = data.frame("db" = some_dates, "b1" = bar1,
"b2" = bar2, "b3" = bar3)
df_line = data.frame("line_dates" = some_dates, "line" = line_data)
plot_so1 = plot_ly(x = df_bars$db,
y = df_bars[[colnames(df_bars)[2]]],
type = 'bar',
name = colnames(df_bars)[2]) %>%
layout(title = 'My plot title',
xaxis = list(title = 'db'),
yaxis = list(title = 'CatProportions'),
barmode = 'stack',
showlegend = TRUE)
# Now loop through the rest of the columns except for the ones already used.
# This is done because "in the wild", the plot is being built in a function
# that has data which is passed to it so the number and names of the columns
# that are used to build the plot are not know in advance.
for (col_index in 3:length(some_dates)) {
plot_so1 =
add_trace(plot_so1,
x = df_bars$db,
y = df_bars[[colnames(df_bars)[col_index]]],
name = colnames(df_bars)[col_index])
}
使用长格式数据框:
## long form of dataframe #########################
df_bars_long = df_bars %>%
pivot_longer(!db, names_to = "Categories", values_to = "CatProportions")
# build same plot from long form dataframe
plot_so2 = plot_ly(data = df_bars_long,
x = ~db, y = ~CatProportions,
color = ~Categories,
type = "bar") %>%
layout(barmode = "stack")
## above works, now try to add the line trace #####
plot_so2 = plot_ly(data = df_bars_long,
x = ~db, y = ~CatProportions,
color = ~Categories,
type = "bar") %>%
# add_trace(x = df_line$line_dates,
# y = df_line$line,
# type = 'scatter', mode = 'lines', name = 'my line',
# line = list(color = '#000000')) %>%
layout(title = 'My plot title',
xaxis = list(title = 'db'),
yaxis = list(title = 'CatProportions'),
barmode = 'stack',
showlegend = TRUE)
我知道使用长格式来创建像这样的图是最佳做法,但我在上面展示了两种方法,因为我想使用来自另一个数据框的数据添加线迹,该数据框有一列用于 x 值,一列用于 x 值y 值的列,并且只能使用宽格式添加此跟踪,我可以通过将以下代码段添加到宽格式代码来完成:
plot_so1 = add_trace(plot_so1,
x = df_line$line_dates,
y = df_line$line,
type = 'scatter', mode = 'lines', name = 'my line',
line = list(color = '#000000'))
这会产生以下情节:
我的主要问题是,如何从数据帧代码中为宽线跟踪创建辅助 y 轴?我的第二个问题是:我正在寻找的最终情节可以用长格式数据框完成吗?如果可以,怎么做?
这 post 让我开始解决这个问题:
但它没有涉及堆叠条形图,这似乎让生活更有趣。
这部分没有变化:
some_dates = c(as.Date('2021-01-01'), as.Date('2021-02-01'),
as.Date('2021-03-01'), as.Date('2021-04-01'))
line_data = c(0,1,2,3)
# wide form dataframe
df_bars = data.frame("db" = some_dates, "b1" = bar1,
"b2" = bar2, "b3" = bar3)
df_line = data.frame("line_dates" = some_dates, "line" = line_data)
如果我们想在图中包含一条线,我们需要知道该线在每个日期的 y 值,因此我们使用 merge()
将 df_line
与 df_bars_long
合并:
df_bars_long = df_bars %>%
pivot_longer(!db, names_to = "Categories", values_to = "CatProportions") %>%
merge(df_line, by.y = "line_dates", by.x = "db") %>%
group_by(db) %>%
dplyr::mutate(line = ifelse(duplicated(line), NA, line))
> df_bars_long
db Categories CatProportions line
1 2021-01-01 b1 0.25 0
2 2021-01-01 b2 0.60 NA
3 2021-01-01 b3 0.15 NA
4 2021-02-01 b1 0.45 1
.. .. .. .. ..
然后,剧情:
plot_so2 <- plot_ly(data = df_bars_long,
x = ~db, y = ~CatProportions,
color = ~Categories,
type = "bar") %>%
add_lines(y = ~line,
name = "my line",
line = list(color = '#000000'),
showlegend = TRUE,
yaxis = "y2") %>%
layout(title = 'My plot title',
xaxis = list(title = 'db'),
yaxis = list(title = 'CatProportions'),
barmode = 'stack',
yaxis2 = list(overlaying = "y",
side = "right", range = range(na.omit(df_bars_long$line))))
> plot_so2
我正在实现一个函数,该函数构建一个带有附加线迹的堆叠 % 条形图。我可以使用宽格式或长格式数据框创建堆积条形图。下面的两个代码部分生成的图看起来基本相同:
使用宽格式数据框:
library(dplyr)
library(plotly) # install.packages("plotly")
# simple example data for SO post
some_dates = c(as.Date('2021-01-01'), as.Date('2021-02-01'),
as.Date('2021-03-01'), as.Date('2021-04-01'))
bar1 = c(0.25,0.45,0.65,0.75)
bar2 = c(0.60,0.40,0.20,0.10)
bar3 = c(0.15,0.15,0.15,0.15)
line_data = c(0,1,2,3)
# wide form dataframe
df_bars = data.frame("db" = some_dates, "b1" = bar1,
"b2" = bar2, "b3" = bar3)
df_line = data.frame("line_dates" = some_dates, "line" = line_data)
plot_so1 = plot_ly(x = df_bars$db,
y = df_bars[[colnames(df_bars)[2]]],
type = 'bar',
name = colnames(df_bars)[2]) %>%
layout(title = 'My plot title',
xaxis = list(title = 'db'),
yaxis = list(title = 'CatProportions'),
barmode = 'stack',
showlegend = TRUE)
# Now loop through the rest of the columns except for the ones already used.
# This is done because "in the wild", the plot is being built in a function
# that has data which is passed to it so the number and names of the columns
# that are used to build the plot are not know in advance.
for (col_index in 3:length(some_dates)) {
plot_so1 =
add_trace(plot_so1,
x = df_bars$db,
y = df_bars[[colnames(df_bars)[col_index]]],
name = colnames(df_bars)[col_index])
}
使用长格式数据框:
## long form of dataframe #########################
df_bars_long = df_bars %>%
pivot_longer(!db, names_to = "Categories", values_to = "CatProportions")
# build same plot from long form dataframe
plot_so2 = plot_ly(data = df_bars_long,
x = ~db, y = ~CatProportions,
color = ~Categories,
type = "bar") %>%
layout(barmode = "stack")
## above works, now try to add the line trace #####
plot_so2 = plot_ly(data = df_bars_long,
x = ~db, y = ~CatProportions,
color = ~Categories,
type = "bar") %>%
# add_trace(x = df_line$line_dates,
# y = df_line$line,
# type = 'scatter', mode = 'lines', name = 'my line',
# line = list(color = '#000000')) %>%
layout(title = 'My plot title',
xaxis = list(title = 'db'),
yaxis = list(title = 'CatProportions'),
barmode = 'stack',
showlegend = TRUE)
我知道使用长格式来创建像这样的图是最佳做法,但我在上面展示了两种方法,因为我想使用来自另一个数据框的数据添加线迹,该数据框有一列用于 x 值,一列用于 x 值y 值的列,并且只能使用宽格式添加此跟踪,我可以通过将以下代码段添加到宽格式代码来完成:
plot_so1 = add_trace(plot_so1,
x = df_line$line_dates,
y = df_line$line,
type = 'scatter', mode = 'lines', name = 'my line',
line = list(color = '#000000'))
这会产生以下情节:
我的主要问题是,如何从数据帧代码中为宽线跟踪创建辅助 y 轴?我的第二个问题是:我正在寻找的最终情节可以用长格式数据框完成吗?如果可以,怎么做?
这 post 让我开始解决这个问题:
但它没有涉及堆叠条形图,这似乎让生活更有趣。
这部分没有变化:
some_dates = c(as.Date('2021-01-01'), as.Date('2021-02-01'),
as.Date('2021-03-01'), as.Date('2021-04-01'))
line_data = c(0,1,2,3)
# wide form dataframe
df_bars = data.frame("db" = some_dates, "b1" = bar1,
"b2" = bar2, "b3" = bar3)
df_line = data.frame("line_dates" = some_dates, "line" = line_data)
如果我们想在图中包含一条线,我们需要知道该线在每个日期的 y 值,因此我们使用 merge()
将 df_line
与 df_bars_long
合并:
df_bars_long = df_bars %>%
pivot_longer(!db, names_to = "Categories", values_to = "CatProportions") %>%
merge(df_line, by.y = "line_dates", by.x = "db") %>%
group_by(db) %>%
dplyr::mutate(line = ifelse(duplicated(line), NA, line))
> df_bars_long
db Categories CatProportions line
1 2021-01-01 b1 0.25 0
2 2021-01-01 b2 0.60 NA
3 2021-01-01 b3 0.15 NA
4 2021-02-01 b1 0.45 1
.. .. .. .. ..
然后,剧情:
plot_so2 <- plot_ly(data = df_bars_long,
x = ~db, y = ~CatProportions,
color = ~Categories,
type = "bar") %>%
add_lines(y = ~line,
name = "my line",
line = list(color = '#000000'),
showlegend = TRUE,
yaxis = "y2") %>%
layout(title = 'My plot title',
xaxis = list(title = 'db'),
yaxis = list(title = 'CatProportions'),
barmode = 'stack',
yaxis2 = list(overlaying = "y",
side = "right", range = range(na.omit(df_bars_long$line))))
> plot_so2