R plotly:使用 scaleanchor 和 constraintoward 在绘制的数据和标题之间留下白色 space

R plotly: using scaleanchor and constraintoward leaves white space between plotted data and title

我使用以下代码创建了一种交互式日历热图。它很长,但应该可以重现。

library(plotly)
library(data.table)
library(tidyr)
library(htmlwidgets)
library(widgetframe)

df <- data.frame(dom = sequence(31,1,1),
             Januar= sample(50:500, 31),
             Februar = sample(50:500, 31),
             März =sample(50:500, 31),
             April = sample(50:500, 31),
             Mai = sample(50:500, 31))

df <- as.data.table(df)
df<- melt(df, id.vars= "dom",variable.name="month",value.name="value", na.rm=T)
df<- as.data.frame(df)
df <- df %>% mutate(month= factor(month,levels=as.character(c("Januar","Februar","März","April","Mai")),labels=c("Jan","Feb","Mär","Apr","Mai"),ordered=TRUE))
df$dommapped <- ordered(df$dom, levels = 31:1)
df <- df%>% mutate(group=ceiling(value/(max(value)/5)))
df$group_1<- ifelse(df$group==1,df$group,NA)
df$group_2<- ifelse(df$group==2,df$group,NA)
df$group_3<- ifelse(df$group==3,df$group,NA)
df$group_4<- ifelse(df$group==4,df$group,NA)
df$group_5<- ifelse(df$group==5,df$group,NA)

colorScale1 <- data.frame(z=c(0,1),col=c("#FFE27a","#FFE27a"))
colorScale1$col <- as.character(colorScale1$col)
colorScale2 <- data.frame(z=c(0,1),col=c("#FFCD0e","#FFCD0e"))
colorScale2$col <- as.character(colorScale2$col)
colorScale3 <- data.frame(z=c(0,1),col=c("#A1C863","#A1C863"))
colorScale3$col <- as.character(colorScale3$col)
colorScale4 <- data.frame(z=c(0,1),col=c("#76B82b","#76B82b"))
colorScale4$col <- as.character(colorScale4$col)
colorScale5 <- data.frame(z=c(0,1),col=c("#4A731c","#4A731c"))
colorScale5$col <- as.character(colorScale5$col)

f1=list(family = "Arial, sans-serif",
      size = 12,
      color = "#000000")       
f2 <- list(family = "Arial, sans-serif",
      size = 14,
      color = "#000000")

plot<-df%>%
  plot_ly(.,y = ~month, x = ~dommapped, z=~group_1, text=~value,name="group1", type="heatmap", xgap=2, ygap=2,hovertemplate=" <extra>%{y}. %{x}: Ø %{text} cases</extra>",
          hoverongaps=FALSE,colorscale=colorScale1,showlegend=TRUE, showscale=FALSE) %>%
  add_trace(.,y = ~month, x = ~dommapped, z=~group_2, text=~value,name="group2", type="heatmap", xgap=2, ygap=2,hovertemplate=" <extra>%{y}. %{x}: Ø %{text} cases</extra>",
            hoverongaps=FALSE,colorscale=colorScale2,showlegend=TRUE, showscale=FALSE) %>%
  add_trace(.,y = ~month, x = ~dommapped, z=~group_3, text=~value,name="group3", type="heatmap", xgap=2, ygap=2,hovertemplate=" <extra>%{y}. %{x}: Ø %{text} cases</extra>",
            hoverongaps=FALSE,colorscale=colorScale3,showlegend=TRUE, showscale=FALSE) %>%
  add_trace(.,y = ~month, x = ~dommapped, z=~group_4, text=~value,name="group4",type="heatmap", xgap=2, ygap=2,hovertemplate=" <extra>%{y}. %{x}: Ø %{text} cases</extra>",
            hoverongaps=FALSE,colorscale=colorScale4,showlegend=TRUE, showscale=FALSE) %>%
  add_trace(.,y = ~month, x = ~dommapped, z=~group_5, text=~value,name="group5", type="heatmap", xgap=2, ygap=2,hovertemplate=" <extra>%{y}. %{x}: Ø %{text} cases</extra>",
            hoverongaps=FALSE,colorscale=colorScale5,showlegend=TRUE, showscale=FALSE)
plot<-plot %>%
  layout(title =list(text= "Very long title about content of graph",
                     xref = "paper",
                     x = 0,
                     font = f2),
         hoverlabel=list(bgcolor="#ffffff",
                         bordercolor ="#ffffff",
                         font=f2),
         showlegend = TRUE,
         separators = ', ',
         plot_bgcolor='#ffffff',
         legend=list(itemclick="toggleothers",
                     orientation="h",
                     title=list(font=f1,
                                text="title"),
                     yanchor="top",
                     y=-0.25),
         modebar = list(color = "#a3a3a3",
                        activecolor = "#000000"),
         xaxis = list(title = "Day of month",
                      zeroline = FALSE, 
                      gridcolor = 'ffff',
                      autorange = "reversed",
                      constraintoward="left"), 
         yaxis = list(title="month",zeroline = FALSE,gridcolor = 'ffff',autorange = "reversed",
                      scaleanchor="x", constraintoward = "bottom"))

    plot<- plot %>% config(modeBarButtonsToRemove = list('autoScale2d'))
    plot<- plot %>% config(locale='de')
    plot<- plot %>% config(toImageButtonOptions = list(format = "png",filename = "",width = 760,height = 600))
    plot<- plot %>% onRender("function(el, x) {Plotly.d3.select('.cursor-crosshair').style('cursor', 'default')}")
    plot$sizingPolicy$browser$padding <- 0 
    htmlwidgets::saveWidget(title = "plot", frameableWidget(plot), "directory/plot_1.html")

scaleanchorconstraintoward 命令有助于获得我需要的设计。否则盒子不会是方形的。 但它导致 - 取决于浏览器 window 大小 - 很大 white space between graph and title。 为 yaxis 设置 range 不起作用。 到目前为止,设置 margin 也没有用。

我想我必须找到一个没有 scaleanchorconstraintoward 的解决方案来获得所需的纵横比。所以我尝试使用 aspectratioaspectmode.

来更改 layout
layout(title =list(text= "Very long title about content of graph",
                     xref = "paper",
                     x = 0,
                     font = f2),
         hoverlabel=list(bgcolor="#ffffff",
                         bordercolor ="#ffffff",
                         font=f2),
         showlegend = TRUE,
         separators = ', ',
         plot_bgcolor='#ffffff',
         legend=list(itemclick="toggleothers",
                     orientation="h",
                     title=list(font=f1,
                                text="title"),
                     yanchor="top",
                     y=-0.25),             
         modebar = list(color = "#a3a3a3",
                        activecolor = "#000000"),
         xaxis = list(title = "Day of month",
                      zeroline = FALSE, 
                      gridcolor = 'ffff',
                      autorange = "reversed"), 
         yaxis = list(title="month",zeroline = FALSE,gridcolor = 'ffff',autorange = "reversed"),
         scene=list(aspectmode="manual",
                    aspectratio=list(x=3,
                                     y=1)))

   

但这也没有用。 如果有人对此问题有其他想法或解决方案,我会很高兴。

剧情和标题之间没有刻意的留白space。发生的事情是 plotly 将标题固定在顶部,然后它使用可用的 space 来处理其他所有内容。

如果您在 RStudio 中查看它,只需调整 viewer 窗格即可将其更改为您正在寻找的外观。

查看一个

查看二

此版本使用完全相同的代码,只是查看器窗格大小不同。

(为了让白色space更明显,我加了边框。)

如果您打算保存绘图,请在保存时控制大小。如果您使用的是 R Markdown,请使用 knitr 选项控制大小。

所以你知道:

在你的问题中,你多次使用了colorScale,但是object并不存在。我即兴创作。

你也使用了objectf1f2,但是没有提供这些object,所以我把它们注释掉了。

最后,我在标题上方添加了一个缓冲区,这样它就不会触及查看器窗格的顶部,使用以下代码:

  layout(margin = list(l = 50, r = 50,
                       b = 50, t = 50,
                       pad = 20))

换个角度来看——我更改之前的边距:

  "layout": {
    "margin": {
      "b": 40,
      "l": 60,
      "t": 25,
      "r": 10
    }

如果您想探索这些您从未选择过的设置,请查看 plotly_json(plot)

我找到了解决问题的方法。

通过将 layoutyaxis 的键 constraintoward 更改为 constraintoward = "top" 并添加 constrain="domain" 我得到了我需要的效果。 所以 yaxis-layout 的代码如下所示:

layout(yaxis = list(title="month",
                    zeroline = FALSE,
                    gridcolor = 'ffff',
                    autorange = "reversed",
                    scaleanchor="x",
                    constraintoward = "top",
                    constrain="domain"))