绘图轴为指数格式 [英] Plotly axis as exponential format

查看:120
本文介绍了绘图轴为指数格式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是此问题的后续内容:

This is a follow up on this question: SO Q

上述问题的答案使用JavaScript代码将轴刻度线变成指数.它适用于单个图上的单个轴.

The answer in the above question uses JavaScript code that turns an axis ticks into exponential. It works for a single axis on a single plot.

当在subplot()结构中运行它时,仅当我将其应用于最终图时,它才可在第一个图上使用.

When running it in a subplot() structure, it only works on the first plot when I apply it to the final plot.

我正在寻找的修改是:

1:如何使其在子图上工作.我尝试在每个子图的构建中调用JavaScript,但是所有图出都没有指数级.

1: How to make it work on subplots. I tried calling JavaScript in the build of each subplot, but all plots came out without exponential then.

2:使其在x和y轴上都可以工作(我尝试过,失败了,哭了一点)

2: make it work for both x an y axis (I tried, failed and cried a little)

3:当轴证明不是数字时,不要破坏宇宙(我的应用程序也可以绘制日期列,因此需要检查它是否实际上是数字输入)

3: Make it not destroy the universe when the axis turns out to not be a numerical (My app can plot date columns too, so it needs to check whether it actually is a numerical input)

4:如果可能,打印为1.23E + 1而不是1E + 1

4: If possible print as 1.23E+1 rather than 1E+1

 library(shiny)
library(plotly)
library(htmlwidgets)


ui <- fluidPage(
    mainPanel(
     plotlyOutput('myplotly')
     )
  )

server <- function(input, output, session) {

  javascript <- "
function(el, x) 
{
  function fix_ticks()
  {
    ticks = Plotly.d3.selectAll('g.ytick').selectAll('text');
    ticks.forEach(function(tick) 
    {
      var num = parseInt(tick[0].innerHTML); 
      tick[0].innerHTML = num.toExponential();
    })
  }
  el.on('plotly_afterplot', fix_ticks);
}"


  output$myplotly <- renderPlotly({

    myplots <- lapply(unique(mtcars$cyl), function(v) {

    data <- mtcars[which(mtcars$cyl == v), ] 
      subp <-   plot_ly(data = data,
                x = rownames(data), 
                y = ~mpg,
                type = "bar")
      subp
     })

    p <- subplot(myplots, margin = 0.08)

    p$elementId <- NULL   ## to surpress warning of widgetid
    p <- onRender(p, javascript)

    p <- p %>% layout(margin =list(l = 60, r = 20, b = 160, t = 70) )

    p
  })
 }

shinyApp(ui = ui, server = server)

更新 有了这里给出的答案建议,我现在运行以下代码,检查数字,然后在每个轴上工作.我尚未获得使用负值[0] .innerHTML处理最后一个负值的建议.我最终在第1点的答案下使用了建议,因为我无法在tickt0循环中使用tick [0] .innerHTML方法.但是,针对早期评论的建议可以追溯到tick [0]方法,而我无法获得一种完全可行的方法.

UPDATE with the answer suggestions given here I am now running the following code that checks for numerical and then works for each axis. I haven't been able to get the last suggestion to deal with negative values to work yet, which was using tick[0].innerHTML. I ended up using the suggestion under the answer under point 1, using, as I could not get the tick[0].innerHTML approach to work inside the forEach loop. However, the suggestion in response to earlier comment is going back to the tick[0] approach, and I can't get one approach to work completely.

这是我在遇到负面-> NaN问题之前最终使用的代码

This is the code I ended up using before running into negative -> NaN problems

  javascriptMPP <- "
  function(el, x) 
  {
    function isNumber(n) {
      return (Object.prototype.toString.call(n) === '[object Number]' || Object.prototype.toString.call(n) === '[object String]') &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(/^-/, ''));
    }
    function fixTicks()
    {
      ticks = Plotly.d3.selectAll('g.yaxislayer-above,g.xaxislayer-above').selectAll('text');
      ticks.each(function(d) 
      {
        if(parseInt(d.text) !== 0 )
        {
          var num = parseInt(d.text).toExponential(2);
          Plotly.d3.select(this).text(num);
        }
      })
    }
    el.on('plotly_afterplot', fixTicks);
  }"

推荐答案

1:如何使其在子图上工作.我尝试在构建中调用Java 每个子图,但是所有图都没有指数化.

1: How to make it work on subplots. I tried calling java in the build of each subplot, but all plots came out without exponential then.

第2/3rd/等的滴答声.子图具有类似y2tick/y3tick/etc的类名.我们可以降低d3选择器的特定性,然后使用each更改所有刻度.

The ticks of the 2nd/3rd/etc. subplot have class names like y2tick/y3tick/etc. We could make our d3 selector less specific and then use each to change all ticks.

ticks = Plotly.d3.selectAll('g.yaxislayer-above').selectAll('text');
ticks.each(function(d, i) 
{
  var num = parseInt(d.text).toExponential();
  Plotly.d3.select(this).text(num);
})

2:使其在x和y轴上均有效(我尝试过,失败并哭了 小)

2: make it work for both x an y axis (I tried, failed and cried a little)

只需将selectAll语句更改为Plotly.d3.selectAll('g.xaxislayer-above').selectAll('text')

Just change the selectAll statement to Plotly.d3.selectAll('g.xaxislayer-above').selectAll('text')

3:当轴转为不存在时,使其不破坏宇宙 数字(我的应用程序也可以绘制日期列,因此需要检查 是否实际上是数字输入)

3: Make it not destroy the universe when the axis turns out to not be a numerical (My app can plot date columns too, so it needs to check whether it actually is a numerical input)

您可以更改fixTicks函数以检查输入值是否为数字,例如通过使用typeof或正则表达式.使用1999、2000等值时,可能会比较棘手,您需要手动对其进行处理.

You could change your fixTicks functions to check if the input value is numeric, e.g. by using typeof or a regex. With values like 1999, 2000, etc. it might be tricky and you would need to manually address it.

4:如果可能,打印为1.23E + 1而不是1E + 1

4: If possible print as 1.23E+1 rather than 1E+1

toExponential采用一个参数,即小数点后的符号",即num.toExponential(3)可以解决您的问题.

toExponential takes one parameter which is the "number of digits in the notation after the decimal point", i.e. num.toExponential(3) would do the trick in your case.

根据评论:当价格变动值为负值时,我似乎会得到NaN

From the comment: I seem to get NaN when the values on the ticks are negative values

使用 Unicode减号代替常规破折号.您可以将其替换为以下JavaScript行:

Plotly uses an Unicode minus sign instead of a regular dash. You can replace it with the following JavaScript line:

var num = parseInt(tick[0].innerHTML.replace(/\\u2013|\\u2014|\\u2212/g, '-'));

注意:R中需要双反斜杠\\,纯JavaScript只需一个\.

Note: the double backslash \\ is required in R, pure JavaScript would require only a single \.

这篇关于绘图轴为指数格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆