在 plotly 中自动创建子图(例如 R 中的分面)
Automatically creating subplots in plotly (e.g. Facetting in R)
我对使用 tidyverse 和 ggplot 非常满意。我正在尝试生成一个交互式图形以使用 flexdashboard 进行部署。因此,我试图在 plotly 中生成我常用的 ggplots。
假设我有以下数据框:
data.frame(id = c(1:5),
product = c("product1","product2","product1","product3","product2"),
variable = c("var1","var1","var3","var2","var1"),
price = c(100,120,140,90,80))
输出:
id product variable price
1 1 product1 var1 100
2 2 product2 var1 120
3 3 product1 var3 140
4 4 product3 var2 90
5 5 product2 var1 80
如果我想在绘图上显示所有这些,我会在 ggplot 中执行以下操作:
library(tidyverse)
library(hrbrthemes)
data.frame(id = c(1:5),
product = c("product1","product2","product1","product3","product2"),
variable = c("var1","var1","var3","var2","var1"),
price = c(100,120,140,90,80)) %>%
ggplot(aes(x = id, y = price, color = variable)) +
geom_point() +
facet_wrap(~product) +
theme_ft_rc()
哪个会产生:
我知道我可以通过使用 subplot()
功能。问题是我有 14-28 个类别可以绘制为构面。据我所知,这意味着我必须制作 14-28 个地块,然后将它们排列在一个网格中。这似乎有点乏味,我想知道是否有更有效的方法来实现这一点,例如 ggplot 中的 facet 选项。我还在另一个 post:
上得到了一段代码
library(plotly)
dataframe <- data.frame(id = c(1:5),
product = c("product1","product2","product1","product3","product2"),
variable = c("var1","var1","var3","var2","var1"),
price = c(100,120,140,90,80)) %>%
pivot_wider(names_from = "product", values_from = "price")
vars <- setdiff(names(dataframe),"id")
plots <- lapply(vars, function(var){
plot_ly(dataframe, x = ~id, color =~variable, y = as.formula(paste0("~",var))) %>%
add_bars(name = var)
})
subplot(plots, nrows = length(plots), shareX = TRUE, titleX = FALSE)
产生:
并且需要将 tidyr 的 pivot_wider()
函数与示例框架中的 product
列一起使用。但是,我的真实列包含数字和字符,在使用上述示例代码时会产生错误。变量列也以一种奇怪的方式显示。这个问题是否有解决方法,或者真正为每个图手动编写代码的最佳方法是什么?
根据您的第一个示例(我刚刚删除了您的主题样式),它是这样工作的。
df <- data.frame(
id = c(1:5),
product = c("product1","product2","product1","product3","product2"),
variable = c("var1","var1","var3","var2","var1"),
price = c(100,120,140,90,80)
)
plot <- ggplot(df, aes(x = id, y = price, color = variable)) +
geom_point() +
facet_wrap(~product)
ggplotly(plot)
唯一的区别是我没有用 %>% 链接,因为当我在下面尝试这个时似乎会阴谋地抛出一个错误:
data.frame(
id = c(1:5),
product = c("product1","product2","product1","product3","product2"),
variable = c("var1","var1","var3","var2","var1"),
price = c(100,120,140,90,80)
) %>% ggplot(aes(x = id, y = price, color = variable)) +
geom_point() +
facet_wrap(~product) %>% ggplotly()
# Error in UseMethod("ggplotly", p) :
# no applicable method for 'ggplotly' applied to an object of class "c('FacetWrap', 'Facet', 'ggproto', 'gg')"
带有自定义工具提示的扩展示例
你可以随心所欲地设计它,我添加了价格格式,为了好玩,它在工具提示中将产品和变量合并为一行。
custom_tooltip <- paste0("ID: ", df$id, "\n", "Product: ", df$product, " (", df$variable, ")\n", "Sold for: £ ", df$price)
plot <- ggplot(df, aes(x = id, y = price, color = variable)) +
geom_point(aes(text = custom_tooltip)) +
facet_wrap(~product)
ggplotly(plot, tooltip = c("text"))
我对使用 tidyverse 和 ggplot 非常满意。我正在尝试生成一个交互式图形以使用 flexdashboard 进行部署。因此,我试图在 plotly 中生成我常用的 ggplots。
假设我有以下数据框:
data.frame(id = c(1:5),
product = c("product1","product2","product1","product3","product2"),
variable = c("var1","var1","var3","var2","var1"),
price = c(100,120,140,90,80))
输出:
id product variable price
1 1 product1 var1 100
2 2 product2 var1 120
3 3 product1 var3 140
4 4 product3 var2 90
5 5 product2 var1 80
如果我想在绘图上显示所有这些,我会在 ggplot 中执行以下操作:
library(tidyverse)
library(hrbrthemes)
data.frame(id = c(1:5),
product = c("product1","product2","product1","product3","product2"),
variable = c("var1","var1","var3","var2","var1"),
price = c(100,120,140,90,80)) %>%
ggplot(aes(x = id, y = price, color = variable)) +
geom_point() +
facet_wrap(~product) +
theme_ft_rc()
哪个会产生:
我知道我可以通过使用 subplot()
功能。问题是我有 14-28 个类别可以绘制为构面。据我所知,这意味着我必须制作 14-28 个地块,然后将它们排列在一个网格中。这似乎有点乏味,我想知道是否有更有效的方法来实现这一点,例如 ggplot 中的 facet 选项。我还在另一个 post:
library(plotly)
dataframe <- data.frame(id = c(1:5),
product = c("product1","product2","product1","product3","product2"),
variable = c("var1","var1","var3","var2","var1"),
price = c(100,120,140,90,80)) %>%
pivot_wider(names_from = "product", values_from = "price")
vars <- setdiff(names(dataframe),"id")
plots <- lapply(vars, function(var){
plot_ly(dataframe, x = ~id, color =~variable, y = as.formula(paste0("~",var))) %>%
add_bars(name = var)
})
subplot(plots, nrows = length(plots), shareX = TRUE, titleX = FALSE)
产生:
并且需要将 tidyr 的 pivot_wider()
函数与示例框架中的 product
列一起使用。但是,我的真实列包含数字和字符,在使用上述示例代码时会产生错误。变量列也以一种奇怪的方式显示。这个问题是否有解决方法,或者真正为每个图手动编写代码的最佳方法是什么?
根据您的第一个示例(我刚刚删除了您的主题样式),它是这样工作的。
df <- data.frame(
id = c(1:5),
product = c("product1","product2","product1","product3","product2"),
variable = c("var1","var1","var3","var2","var1"),
price = c(100,120,140,90,80)
)
plot <- ggplot(df, aes(x = id, y = price, color = variable)) +
geom_point() +
facet_wrap(~product)
ggplotly(plot)
唯一的区别是我没有用 %>% 链接,因为当我在下面尝试这个时似乎会阴谋地抛出一个错误:
data.frame(
id = c(1:5),
product = c("product1","product2","product1","product3","product2"),
variable = c("var1","var1","var3","var2","var1"),
price = c(100,120,140,90,80)
) %>% ggplot(aes(x = id, y = price, color = variable)) +
geom_point() +
facet_wrap(~product) %>% ggplotly()
# Error in UseMethod("ggplotly", p) :
# no applicable method for 'ggplotly' applied to an object of class "c('FacetWrap', 'Facet', 'ggproto', 'gg')"
带有自定义工具提示的扩展示例
你可以随心所欲地设计它,我添加了价格格式,为了好玩,它在工具提示中将产品和变量合并为一行。
custom_tooltip <- paste0("ID: ", df$id, "\n", "Product: ", df$product, " (", df$variable, ")\n", "Sold for: £ ", df$price)
plot <- ggplot(df, aes(x = id, y = price, color = variable)) +
geom_point(aes(text = custom_tooltip)) +
facet_wrap(~product)
ggplotly(plot, tooltip = c("text"))