设置主要刻度标签以在R的Plotly图中显示为科学计数法 [英] Set major tick labels to be displayed as scientific notation in a Plotly plot in R
问题描述
我正试图让plotly
将值不管大小如何用科学计数法表示,即100等于1E02,但通常显示的数字低于10.000.
I'm trying to get plotly
to put values in scientific notation regardless of their size, i.e. 100 should be 1E02 in the ticks, but it keeps showing numbers below 10.000 as normal annotation.
设置格式是通过exponentformat = "E"
完成的,但只会影响较大的数字.
Setting the format is done through exponentformat = "E"
"but it only affects larger numbers.
这是我写代码的示例代码:
Here is an example code of how I write it:
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 plus范围内可提供所需的输出,但:
manipulating the values to be in the 10k plus range gives the desired output though:
mtcars$disp <- mtcars$disp *100
推荐答案
如果Plotly没有提供所需的功能,让我们自己使用JavaScript来完成.
Let's just do it ourselves in JavaScript, if Plotly doesn't provide the needed functionality.
-
使用d3抓取y轴上的所有刻度线
let's grab all ticks on the y-axis using d3
ticks = Plotly.d3.selectAll('g.ytick');
原始数据存储在data.x
然后将每个数字的表示形式更改为科学计数法
then change the representation of each one to scientific notation
Plotly.d3
.selectAll('g.ytick')
.each(function(data, i)
{
Plotly.d3.select(this)
.select('text')
.html(formatNumber(data.x, 2));
})
-
最后在图中使用
htmlwidgets
注入所有代码finally inject all the code using
htmlwidgets
in our graphp<-onRender(p,javascript)
p <- onRender(p, javascript)
现在这将是一次唯一的更改,每当用户缩放或修改绘图时,更改都将丢失.为了确保每次将代码包装在函数
fix_ticks()
中并将其添加到Plotly的plotly_afterplot
事件(el
是htmlwidget
元素)now it would be one-time only change, every time a user zooms or modifies the plot the changes would be lost. In order to make sure that changes are applied every time the code is wrapped in a function
fix_ticks()
and added to Plotly'splotly_afterplot
event (el
is thehtmlwidget
element)el.on('plotly_afterplot', fix_ticks);
更新
如果您想更改科学计数法的格式,则可以编写函数,例如
If you want to change the format of the scientific notation, you could write your function, e.g.
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; } }
然后为每个刻度线调用它
and then call it for each tick
ticks.forEach(function(tick) { var num = parseInt(tick[0].innerHTML); tick[0].innerHTML = formatNumber(num, 2); })
注意:这可能在RStudio中不起作用,但在保存输出后在浏览器中正确显示.
Note: this might not work in RStudio but shows up correctly in your browser after saving the output.
完整代码
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
这篇关于设置主要刻度标签以在R的Plotly图中显示为科学计数法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!