在R A Plotly阴谋显示设置主刻度标记为科学记数法

问题描述 投票:1回答:2

我试图让plotly把值以科学计数法无论其规模大小,即100应在蜱1E02,但它一直显示为正常注释下面10.000号码。

设置的格式是通过exponentformat = "E"做“,但它不仅影响较大的数字。

下面是我如何写一个示例代码:

f2 <- list(family = "Old Standard TT, serif", size = 14, color = "black")

ax <- list(showticklabels = TRUE, tickfont = f2,  showgrid=F,  zeroline=T,  showline=T,  nticks = 4,  exponentformat = "E")
ay <- list(nticks = 4,  showticklabels = TRUE,  tickfont = f2,  showgrid=F,  zeroline=T,  showline=T,  range =c(0,max(mtcars$disp*1.2)),  exponentformat = "E")

plot_ly(x = mtcars$mpg  , y = mtcars$disp) %>%
  add_trace(type = 'scatter', mode = 'markers', 
            marker = list(color = c('black'))) %>%
  add_lines(hoverinfo='none', line = list(color = 'black')) %>%
  layout(title = 'A plot in science',yaxis = ay, xaxis = ax,
         showlegend = FALSE, hovermode = "y")

操纵值是在10K加范围,得到所需的输出虽然:

 mtcars$disp <- mtcars$disp *100 
r plotly scientific-notation
2个回答
1
投票

我们只是做我们自己在JavaScript中,如果Plotly不提供所需的功能。

  • 让我们抢在y轴使用D3所有蜱 ticks = Plotly.d3.selectAll('g.ytick');
  • 原始数据被存储在data.x
  • 然后改变每一个的至科学记数法表示 Plotly.d3 .selectAll('g.ytick') .each(function(data, i) { Plotly.d3.select(this) .select('text') .html(formatNumber(data.x, 2)); }) 终于在我们的图形使用htmlwidgets注入所有的代码 P < - 的OnRender(P,JavaScript的)
  • 现在这将是一次唯一的变化,每一个用户放大或修改情节的变化将失去的时间。为了确保更改应用于每次代码被包裹在一个函数fix_ticks()并添加到Plotly的plotly_afterplot事件时间(elhtmlwidget元素) el.on('plotly_afterplot', fix_ticks);

更新

如果你想改变科学记数法的格式,你可以写你的函数,例如

function formatNumber(num, desiredLength)
{
  num = num.toExponential().toUpperCase();
  var r = /(\\d*)([E][-+])(\\d*)/;
  var fields = r.exec(num);
  if (fields !== null && fields.length > 3)
  {
    return fields[1] + fields[2] + fields[3].padStart(desiredLength, '0');
  }
  else
  {
    return num;
  }   
}

然后调用它的每个刻度

ticks.forEach(function(tick) 
{
  var num = parseInt(tick[0].innerHTML); 
  tick[0].innerHTML = formatNumber(num, 2);
})

注意:这可能不是在RStudio工作,但保存后的输出正确地显示了在浏览器中。


完整代码

library(plotly)
library(htmlwidgets)

p <- plot_ly(x = mtcars$mpg  , y = mtcars$disp) %>%
  add_lines()

javascript <- "
function(el, x) 
{
  function fixTicks()
  {

    Plotly.d3
          .selectAll('g.ytick')
          .each(function(data, i) 
            {
               Plotly.d3.select(this)
                        .select('text')
                        .html(formatNumber(data.x, 2));
            }) 
  }

  function formatNumber(num, desiredLength)
  {
    num = num.toExponential().toUpperCase();
    var r = /(\\d*)([E][-+])(\\d*)/;
    var fields = r.exec(num);
    if (fields !== null && fields.length > 3)
    {
      return fields[1] + fields[2] + fields[3].padStart(desiredLength, '0');
    }
    else
    {
      return num;
    }
  }

  el.on('plotly_afterplot', fixTicks);
}"

p <- onRender(p, javascript)  
p

1
投票

特别针对在使用对数刻度图(这似乎会导致当前的JavaScript解决的问题),我找到了另一种解决方案,而无需使用javascript。它的工作原理基础上做tickvalues,并在整个指数的数字文本标签的一个列表,并保留其余空,然后插入两成通过layout论据tickvalsticktext参数的阴谋

这取决于它是否是一个普通的scatterscatter3d布局代码修改了一下,但原理是一样的。

scatter3d轴被所述scene = list()参数内。在scatter它在layout()直接完成。 cameraautosize等都是用来做情节不错,广场,以及3D在右变焦水平的参数,并具有固定大小的。

答案是基于另一个SO POST发现:here

    library(shiny)
    library(plotly)

    shinyApp(
      ui = fluidPage( plotlyOutput('plot') ),

      server = function(input, output) {
        output$plot <- renderPlotly ({

          mtcars <- rbind(mtcars, mtcars*1000, mtcars/1000)  #create data with big logarithmic range
          maxlog <- round(log10(max(mtcars[['mpg']][mtcars[['mpg']]>0], mtcars[['disp']][mtcars[['disp']]>0],mtcars[['cyl']][mtcars[['cyl']]>0])), digits = 0) +1 # determine max log needed
          minlog <- round(log10(min(mtcars[['mpg']][mtcars[['mpg']]>0], mtcars[['disp']][mtcars[['disp']]>0],mtcars[['cyl']][mtcars[['cyl']]>0])), digits = 0) -1 # determine min log needed
          logrange <- (maxlog - minlog)*9 +1 # get the distance between smallest and largest log power
          tval <- sort(as.vector(sapply(seq(1,9), function(x) x*10^seq(minlog, maxlog)))) #generates a sequence of numbers in logarithmic divisions
          ttxt <- rep("",length(tval))  # no label at most of the ticks
          ttxt[seq(1,logrange,9)] <- formatC(tval, format = "e", digits = 2)[seq(1,logrange,9)] # every 9th tick is labelled


          p <- plot_ly(source = 'ThresholdScatter')
          p <- add_trace(p, data = mtcars, 
                      x = mtcars[['mpg']], 
                      y = mtcars[['disp']],
                      z = mtcars[['cyl']],
                      type = 'scatter3d', 
                      mode = 'markers',
                      marker = list(size = 2)) 

      p <- layout(p, autosize = F, width = 500, height = 500,
                  scene = list(yaxis = list(type="log",
                                            zeroline=F, showline=T, 
                                            ticks="outside",
                                            tickvals=tval,
                                            ticktext=ttxt),
                               xaxis = list(type="log",
                                            zeroline=F, showline=T, 
                                            ticks="outside",
                                            tickvals=tval,
                                            ticktext=ttxt),
                               zaxis = list(type="log",
                                            zeroline=F, showline=T, 
                                            ticks="outside",
                                            tickvals=tval,
                                            ticktext=ttxt),
                               camera = list(eye = list(x = -1.5, y = 1.5, z = 1.5))))
    })
  }
    )

用于2D溶液:

library(shiny)
library(plotly)

shinyApp(
  ui = fluidPage( plotlyOutput('plot') ),

  server = function(input, output) {
    output$plot <- renderPlotly ({

      mtcars <- rbind(mtcars, mtcars*1000, mtcars/1000)  #create data with big logarithmic range
      maxlog <- round(log10(max(mtcars[['mpg']][mtcars[['mpg']]>0], mtcars[['disp']][mtcars[['disp']]>0])), digits = 0) +1 # determine max log needed
      minlog <- round(log10(min(mtcars[['mpg']][mtcars[['mpg']]>0], mtcars[['disp']][mtcars[['disp']]>0])), digits = 0) -1 # determine min log needed
      logrange <- (maxlog - minlog)*9 +1 # get the distance between smallest and largest log power
      tval <- sort(as.vector(sapply(seq(1,9), function(x) x*10^seq(minlog, maxlog)))) #generates a sequence of numbers in logarithmic divisions
      ttxt <- rep("",length(tval))  # no label at most of the ticks
      ttxt[seq(1,logrange,9)] <- formatC(tval, format = "e", digits = 2)[seq(1,logrange,9)] # every 9th tick is labelled


      p <- plot_ly(source = 'ThresholdScatter')
      p <- add_trace(p, data = mtcars, 
                     x = mtcars[['mpg']], 
                     y = mtcars[['disp']],
                     type = 'scatter', 
                     mode = 'markers',
                     marker = list(size = 2)) 

      p <- layout(p,autosize = F, width = 500, height = 500,
                  yaxis = list(type="log",
                                 zeroline=F, showline=T, 
                                 ticks="outside",
                                 tickvals=tval,
                                 ticktext=ttxt),
                  xaxis = list(type="log",
                               zeroline=F, showline=T, 
                               ticks="outside",
                               tickvals=tval,
                               ticktext=ttxt))
    })
  }
)

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.