将主刻度标签设置为在R中的绘图中显示为科学符号
我正试图让将主刻度标签设置为在R中的绘图中显示为科学符号,r,plotly,scientific-notation,R,Plotly,Scientific Notation,我正试图让绘声绘色地将值放入科学记数法中,而不管它们的大小,即100应该是刻度中的1E02,但它始终显示低于10.000的数字作为正常注释 设置格式是通过exponentformat=“E””完成的,但它只影响较大的数字 下面是我如何编写它的示例代码: f2 <- list(family = "Old Standard TT, serif", size = 14, color = "black") ax <- list(showticklabels = TRUE, tickfont
绘声绘色地将值放入科学记数法中,而不管它们的大小,即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")
f2%
布局(标题=‘科学中的情节’,yaxis=ay,xaxis=ax,
showlegend=FALSE,hovermode=“y”)
通过将值控制在10k+范围内,可获得所需的输出,但:
mtcars$disp <- mtcars$disp *100
mtcars$disp如果Plotly没有提供所需的功能,我们就用JavaScript自己动手吧
- 让我们使用d3抓取y轴上的所有刻度
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特别针对使用对数刻度的绘图(这似乎会导致当前javascript解决方案出现问题),我找到了另一个不使用javascript
的解决方案。它的工作原理是:在整个指数上列出tickvalue和一个文本标签,其余的为空,然后通过layout
参数tickvals
和ticktext
参数将这两个标签插入到绘图中
根据是常规的散点
还是散点3D
布局代码会有一些变化,但原理是一样的
在scatter3d
中,轴在scene=list()
参数中设置。在scatter
中,轴直接在layout()
中设置;自动调整大小
等参数用于使打印美观、方正,用于右缩放级别的3D,且大小固定
答案基于另一个SO帖子:
库(闪亮)
图书馆(绘本)
shinyApp(
ui=fluidPage(plotlyOutput(“plot”),
服务器=功能(输入、输出){
输出$plot 0])),数字=0)+1#确定所需的最大日志
minlog 0],mtcars[['disp']][mtcars[['disp']]>0],mtcars[['cyl']]][mtcars[['cyl']]>0]),数字=0)-1#确定所需的最小日志
logrange如何mtcars$disp我不认为这会有帮助,它可能应该在绘图的布局或标签中更改。在多面板绘图中,它似乎对我的数据做了非常奇怪的事情。绘图的数据是不同的行,并且当我应用格式方法时,范围参数也会失败thggplot2
和ggplotly
。嘿,max再次感谢您提供了另一个伟大的解决方案。2件事;这可以调整为使指数显示1或2位小数吗?第二件事是:我尝试将此应用于子图结构,在每个子图和整个图上都应用onrender,但在最好的情况下,它只影响第一个面板。我将为此发布一个新问题。这段代码对Plotly的刻度线(显示为10k和20k等)有着迷人的作用。请参见注释其他问题。它可以理解地将它们转换为1.00E1。Max,还有一点,我终于回到这个问题上了。您能演示如何一次性将其应用于x轴和y轴吗?@maximillian,谢谢。我刚刚发现了另一个障碍,当前的答案与plotly的布局(p,yaxis=list(type='log'))相结合,造成了可怕的混乱。我应该为这个特定场景写另一个问题吗?
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);
})
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
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))))
})
}
)
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))
})
}
)