该图像是来自
iris
数据集的 9 条记录的简单平行坐标图,在 ggplot2
中创建,并通过 ggplotly
翻转为绘图。该图由物种 colour
和观测 ID group
组成(以便每个观测都有自己的线系列),并且自定义工具提示 text
属性包含此 ID(但实际上可能包含各种信息)。
在“悬停时显示最接近的数据”模式下,所有 9 个工具提示都可供单独选择。但在“悬停时比较数据”模式(如图所示)中,每种颜色仅显示一个点并带有工具提示,特别是每个颜色组(3、6 和 9)中的最后一个观察值。 我的期望/经验是“比较悬停时的数据”
模式显示图中共享 x 坐标的所有数据点的工具提示(这是我想要的行为)。然而,这种期望在本案中显然是错误的。我推测这与colour
调用中存在的两种“分组”美学(group
和
ggplot2
)以及它们由
ggplotly
翻译成一个情节对象有关,但我没有进一步探索的知识却一片空白。
重现此示例的代码如下。我将不胜感激对观察到的行为的任何解释,最好是生成所需行为的解决方案或解决方法。
# data: first 3 rows of each iris species, add observation ID, reshape to long
library(data.table)
df <- data.table(iris)[, head(.SD, 3), by=Species][, ID := seq(.N)] |> melt(id.vars=c("ID", "Species")) |> as.data.frame()
# manual parallel coordinates plot in ggplot2
library(ggplot2)
gg <- ggplot(df, aes(x=variable, y=value, colour=Species, group=ID)) +
geom_point(aes(text=ID)) + geom_line()
# flip to plotly
library(plotly)
gg |> ggplotly(tooltip="text")
事实证明,ggplotly()
仅在
“悬停时比较数据”模式下为每种颜色显示一个工具提示,因为
colour
的美观决定了迹线的数量,并且最多只有一个在此模式下,每个跟踪都会显示工具提示。我在下面解释了这种常规行为(我努力在一个地方找到记录)并展示了问题中案例的解决方法。
观察到的行为的解释
在尝试各种 ggplot()
调用并用
plotly_json()
直观地检查生成的绘图对象后,该行为与以下解释一致:a)
ggplotly
如何翻译 ggplot2
美观以及 b) 绘图对象如何显示工具提示:
ggplot2
colour
美学转化为group
美学确实df <- data.frame(x = c(1,2,2,3),
y = c(2,1,3,2),
ID = LETTERS[1:4])
(ggplot(df, aes(x=x, y=y)) + geom_point(aes(text=ID))) |> ggplotly(tooltip="text")
在问题中使用的平行坐标示例中:
geom_point()
colour=Species
geom_line()
与 colour=Species
group=ID
美学相结合
结果产生 3 条绘图线迹线(每个物种一条),每条线迹有 14 个点
(4 个 x 值处的 3 个逻辑观察值,加上分隔集合的 2 个空点)text=ID
美学附加于 geom_point()
ggplotly()
调用结果显示每个物种的最后一个点
“比较悬停时的数据”模式下的工具提示与任何特定的 x 坐标 换句话说,尽管图中出现了 9 个系列(每个逻辑观察一个),但实际上只有 3 个(对)轨迹,并且使用 “比较悬停数据”显示每个标记轨迹只有一个工具提示“
实现所需行为的解决方法
因此,一种解决方法是通过 ID 而不是物种来colour
为每个逻辑观察提供自己的踪迹。为了维护物种的视觉着色,我们需要将物种调色板 (n=3) 映射到应用于不同 ID (n=9) 的调色板。结果显示在这个答案的顶部,代码如下:
# map species colours to IDs
species_pal <- scales::hue_pal()(length(unique(df$Species)))
ID_pal <- species_pal[as.numeric(unique(df[c("Species", "ID")])$Species)]
# generate the plot
library(ggplot2)
library(plotly)
( ggplot(df, aes(
x = variable,
y = value,
colour = as.factor(ID), # now colouring by observation ID
group = ID
)) +
geom_point(aes(text = ID)) +
geom_line() +
scale_colour_manual(values = ID_pal) + # species colours mapped to IDs
theme(legend.position = "none") # suppress legend :(
) |> ggplotly(tooltip = "text")
模式下可见。 (在引发问题的用例中,即多元数据集的 EDA,分组变量始终基于统计聚类,因此图例无论如何都不会提供任何额外的语义信息。有趣的信息是每个观察的身份和属性,包含在工具提示中。)