Particularly aimed at plots where log scale is used (which seems to cause problems with the current javascript solution), I found another solution without using javascript
. It works based on making a list of tickvalues and one of text labels at the whole exponent numbers and leaving the rest empty, and then inserting the two into the plot through the layout
arguments for tickvals
and ticktext
arguments
depending on whether it is a regular scatter
or scatter3d
the layout code changes a bit, but the principle is the same.
In scatter3d
the axes are set within the scene = list()
argument. in scatter
it is done directly in layout()
. camera
, autosize
etc are arguments used to make the plots nice and square, and for 3D at the right zoom level, and of a fixed size.
The answer is based on another SO post found: 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))))
})
}
)
for a 2D solution:
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))
})
}
)
mtcars$disp <- format(mtcars$disp, scientific=T)
? – Opahlayout
orlabel
of the plot. – Shreddingggplot2
andggplotly
. – Jeannettejeannie