我试图让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
我们只是做我们自己在JavaScript中,如果Plotly不提供所需的功能。
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
事件时间(el
是htmlwidget
元素)
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
特别针对在使用对数刻度图(这似乎会导致当前的JavaScript解决的问题),我找到了另一种解决方案,而无需使用javascript
。它的工作原理基础上做tickvalues,并在整个指数的数字文本标签的一个列表,并保留其余空,然后插入两成通过layout
论据tickvals
和ticktext
参数的阴谋
这取决于它是否是一个普通的scatter
或scatter3d
布局代码修改了一下,但原理是一样的。
在scatter3d
轴被所述scene = list()
参数内。在scatter
它在layout()
直接完成。 camera
,autosize
等都是用来做情节不错,广场,以及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))
})
}
)