mat*_*mat 10 r ggplot2 ggplotly
我正在尝试将geom_tile使用 构建的图转换ggplot为ggplotly. 然而,瓷砖在情节上是扭曲的。同样的问题也发生在geom_raster.
展示:
library(ggplot2)
library(plotly)
set.seed(1)
n <- 10
X <- data.frame(xcoord = sample(1:10, n, replace = TRUE),
                ycoord = sample(1:10, n, replace = TRUE),
                value = runif(n))
gg <- ggplot(X) + geom_tile(aes(x = xcoord, y = ycoord, fill = value))
ggplotly(gg)
Run Code Online (Sandbox Code Playgroud)
    看看这里的绘图代码(下面摘录),似乎栅格仅针对数据集中可用的任何 x 和 y 值定义 - 而两者之间发生的任何事情都取决于绘图代码的其余部分。
geom2trace.GeomTile <- function(data, params, p) {
  x <- sort(unique(data[["x"]]))
  y <- sort(unique(data[["y"]]))
  # make sure we're dealing with a complete grid
  g <- expand.grid(x = x, y = y)
  g$order <- seq_len(nrow(g))
  g <- merge(g, data, by = c("x", "y"), all.x = TRUE)
  g <- g[order(g$order), ]
...
Run Code Online (Sandbox Code Playgroud)
对于示例数据,此代码生成以下数据,其中灰色区域为 NA,空白区域只是未定义。所有的扭曲/拉伸都发生在未定义的区域。
ggplot(g, aes(x = x, y = y, fill = value)) + geom_tile()
Run Code Online (Sandbox Code Playgroud)
这样,一种可能的解决方法(在plotly包之外)是手动确保在整个x/y范围内有(NA)可用数据,因此当绘图转换为plotly时,expand.grid会生成足够密集的网格。
set.seed(1)
X1 <- data.frame(xcoord = c(sample(1:10, n, replace = TRUE), 1:10),
                ycoord = c(sample(1:10, n, replace = TRUE), 1:10),
                value = c(runif(n), rep(NA, 10)))
gg1 <- ggplot(X1) + geom_tile(aes(x = xcoord, y = ycoord, fill = value))
ggplotly(gg1)
Run Code Online (Sandbox Code Playgroud)
虽然上面的示例演示了数据集中的任何 x 和 y 具有单个值就足够了,但我还将按照Waldi在评论中的建议添加一个可以说更干净的解决方案。通过(自动)提前生成完整网格,可以减少对绘图翻译中的怪癖的依赖。对于网格间距不为1的情况,当然需要调整顺序。
# X: original dataframe as defined in the question
X2 <- tidyr::expand_grid(
  xcoord = seq(min(X$xcoord), max(X$xcoord)), 
  ycoord = seq(min(X$ycoord),max(X$ycoord))
  ) %>%    
  dplyr::left_join(X, by=c('xcoord','ycoord'))
gg2 <- ggplot(X2) + geom_tile(aes(x = xcoord, y = ycoord, fill = value))
ggplotly(gg2)
Run Code Online (Sandbox Code Playgroud)
        |   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           574 次  |  
        
|   最近记录:  |