grid的Plotly和ggplot

grid的Plotly和ggplot

本文介绍了R中带有facet_grid的Plotly和ggplot:如何获取y轴标签以使用ticktext值而不是范围值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在 plotly 中使用 ggplot2 构面,但遇到了 y 轴标签显示 y 轴范围值而不是刻度文本的问题.我可以在 plotly 对象中更改什么(使用 plotly_build)以使其正确渲染.我真的很想在 ggplots 上的闪亮应用程序中利用 plotly 的悬停功能.我发现了一些与情节相关的其他问题,但大多数似乎都将用户重定向到使用情节子图而不是 ggplot.在我的情况下,构面数据并没有消失,y轴只是坏了.

参考问题:

plotly 中的相同图已损坏 y 轴标签:

解决方案

这看起来像是从 ggplotPlotly 转换的一些奇怪的工件.无论如何,您需要做的就是将一个空字符串添加到 ticktext 并将 tickvals 扩展 1.

for (i in 2:22) {tick_l <- 长度(p[['x']][['layout']][[paste('yaxis', i, sep='')]][['ticktext']]) + 1p[['x']][['layout']][[paste('yaxis', i, sep='')]][['tickvals']] <- seq(1, tick_l)p[['x']][['layout']][[paste('yaxis', i, sep='')]][['ticktext']][[tick_l]] <- ''}

第一个 yaxis 布局与其他布局相同,但不需要修复,因为它已经正确显示.

修复整个情节需要更多调整.我试图使尽可能通用,但转换可能会破坏每个情节的不同之处.

图书馆(情节)图书馆(ggplot2)库(数据表)库(数据集)#添加假模型以用于构面dt

I would like to use ggplot2 facets with plotly but am running into issues with the y-axis labels showing the yaxis range values instead of the ticktext. Is there something I can alter in the plotly object (using plotly_build) to get it to render correctly. I'd really like to leverage the hover features of plotly in a shiny app on ggplots. I have found a few other questions that are related to facets in plotly but most appear to redirect users to use plotly subplots instead of ggplot. In my case the facet data isn't disappearing, the yaxis is just broken.

Reference Question:Error plotting chart with facet_wrap and scales = "free" in plotly

See example code below with mtcars dataset that shows the issues with facets. If you look at the ggplot object the labels are correct.

If I reduce the number of subplots like reduce the mtcars data set to only a few models the issue appears to be resolved. Why would # of subplots impact the yaxis tick labels? It also looks like the facets/groups that are broken only have 1 item (unless it is the first yaxis), the facets that have more than 1 item (at least in this example) are plotting the yaxis correctly. Is there something I can alter in the plotly object (using plotly_build) to get it to render correctly. I'd really like to leverage the hover features of plotly in a shiny app on ggplots.

library(plotly)
library(ggplot2)
library(data.table)
library(datasets)

#add fake model for use in facet
dt<-data.table(mtcars)
dt[,car.id:=rownames(mtcars)]
dt[,model:=substr(car.id,1,regexpr(" ",car.id)-1)][model=="",model:=car.id]

#Optional toggle: pick a few models and issue seems to go away
#Use data=dt[model %in% c("Mazda","Merc","Toyota","Honda","Hornet")]
ggplot.test<-ggplot(dt,aes(mpg,car.id))+geom_point()+facet_grid(model~.,scales="free_y",space="free",drop=TRUE)

#check ggplot in Plots
ggplot.test

#broken ggplotly object in Viewer
ggplotly(ggplot.test)

ggplot Plot:

Same plot in plotly that has broken yaxis labels:

解决方案

This looks like some weird artifact from the ggplot to Plotly conversion.Anyways, all what you need to do is to add an empty string to ticktext and expand tickvals by 1.

for (i in 2:22) {
  tick_l <- length(p[['x']][['layout']][[paste('yaxis', i, sep='')]][['ticktext']]) + 1
  p[['x']][['layout']][[paste('yaxis', i, sep='')]][['tickvals']] <- seq(1, tick_l)
  p[['x']][['layout']][[paste('yaxis', i, sep='')]][['ticktext']][[tick_l]] <- ''
}

The first yaxis layout is identical to the rest but does not need fixing since it already already correctly shown.



Fixing the whole plot needs some more tweaking. I tried to make as generic as possible but probably the conversion will break something different for each plot.

library(plotly)
library(ggplot2)
library(data.table)
library(datasets)

#add fake model for use in facet
dt<-data.table(mtcars)
dt[,car.id:=rownames(mtcars)]
dt[,model:=substr(car.id,1,regexpr(" ",car.id)-1)][model=="",model:=car.id]

#Optional toggle: pick a few models and issue seems to go away
#Use data=dt[model %in% c("Mazda","Merc","Toyota","Honda","Hornet")]
ggplot.test<-ggplot(dt,aes(mpg,car.id))+geom_point()+facet_grid(model~.,scales="free_y",space="free",drop=TRUE)

p <- ggplotly(ggplot.test)
len <- length(unique(dt$model))

total <- 1
for (i in 2:len) {
  total <- total + length(p[['x']][['layout']][[paste('yaxis', i, sep='')]][['ticktext']])
}

spacer <- 0.01 #space between the horizontal plots
total_length = total + len * spacer
end <- 1
start <- 1

for (i in c('', seq(2, len))) {
  tick_l <- length(p[['x']][['layout']][[paste('yaxis', i, sep='')]][['ticktext']]) + 1

  #fix the y-axis
  p[['x']][['layout']][[paste('yaxis', i, sep='')]][['tickvals']] <- seq(1, tick_l)
  p[['x']][['layout']][[paste('yaxis', i, sep='')]][['ticktext']][[tick_l]] <- ''

  end <- start - spacer
  start <- start - (tick_l - 1) / total_length
  v <- c(start, end)
  #fix the size
  p[['x']][['layout']][[paste('yaxis', i, sep='')]]$domain <- v
}

#fix the first entry which has a different name than the rest
p[['x']][['layout']][['annotations']][[3]][['y']] <- (p[['x']][['layout']][['yaxis']]$domain[2] + p[['x']][['layout']][['yaxis']]$domain[1]) /2
p[['x']][['layout']][['shapes']][[2]][['y0']] <- p[['x']][['layout']][['yaxis']]$domain[1]
p[['x']][['layout']][['shapes']][[2]][['y1']] <- p[['x']][['layout']][['yaxis']]$domain[2]

#fix the annotations
for (i in 3:len + 1) {
  #fix the y position
  p[['x']][['layout']][['annotations']][[i]][['y']] <- (p[['x']][['layout']][[paste('yaxis', i - 2, sep='')]]$domain[1] + p[['x']][['layout']][[paste('yaxis', i - 2, sep='')]]$domain[2]) /2
  #trim the text
  p[['x']][['layout']][['annotations']][[i]][['text']] <- substr(p[['x']][['layout']][['annotations']][[i]][['text']], 1, length(p[['x']][['layout']][[paste('yaxis', i - 2, sep='')]][['ticktext']]) * 3 - 3)
}

#fix the rectangle shapes in the background
for (i in seq(0,(len - 2) * 2, 2)) {
  p[['x']][['layout']][['shapes']][[i+4]][['y0']] <- p[['x']][['layout']][[paste('yaxis', i /2 + 2, sep='')]]$domain[1]
  p[['x']][['layout']][['shapes']][[i+4]][['y1']] <- p[['x']][['layout']][[paste('yaxis', i /2 + 2, sep='')]]$domain[2]
}
p

这篇关于R中带有facet_grid的Plotly和ggplot:如何获取y轴标签以使用ticktext值而不是范围值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-31 02:16