在 plotly 中自动创建子图(例如 R 中的 Facetting)
Posted
技术标签:
【中文标题】在 plotly 中自动创建子图(例如 R 中的 Facetting)【英文标题】:Automatically creating subplots in plotly (e.g. Facetting in R) 【发布时间】:2022-01-08 21:06:33 【问题描述】:我很喜欢使用 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 选项。我还在另一篇文章中获得了一段代码:
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
列。但是,我的真实列包含数字和字符,使用上述示例代码时会产生错误。变量列也以更奇怪的方式显示。是否有解决此问题的方法,或者是真正为每个绘图手动编写代码的最佳方法?
【问题讨论】:
【参考方案1】:根据您的第一个示例(我刚刚删除了您的主题样式),它的工作原理是这样的。
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"))
【讨论】:
谢谢!我想我可以试试这样。我对 ggplotly 的问题是它有时会以一种奇怪的方式格式化绘图。主要是我似乎无法找到如何正确格式化悬停文本,使其显示类似paste("£", price)
您可以重写工具提示的文本,给我一秒钟将其添加到我的答案中。
哦,谢谢,这真是太棒了,我整个星期都在为这个工具提示问题苦苦挣扎。我不知道您必须将其传递给绘图类型aes()
。非常感谢您的解决方案,我将尝试稍微编辑我的问题,以便它反映您的答案。唯一的问题是我的构面图的格式很奇怪。我在方面有 22 个子图。第一行正常显示,最后一行也正常显示。但是中间的三排被压缩得扁平且难以辨认。你知道为什么吗?
是使用 ggplot 代码,然后将其设为 ggplotly,还是使用子图得到刻面问题?
不,我正在使用 ggplot2 创建与上面相同的构面图,然后通过 ggplotly 将其传递给 plotly。如果我为一个产品做一个点图,它工作得很好,但是当我面对所有这些时,格式是随机的。我将尝试以重现我的问题为例。以上是关于在 plotly 中自动创建子图(例如 R 中的 Facetting)的主要内容,如果未能解决你的问题,请参考以下文章