Skip to contents

Produce nice \(a \times 10^k\) expressions to be used instead of the scientific notation "a E<k>".

Usage

<!-- % ../R/prettylab.R -->
pretty10exp(x, drop.1 = FALSE, sub10 = FALSE, digits = 7, digits.fuzz,
            off = pmax(10^-digits, 2^-(l10x*log2(10)+1075)),
            lab.type = c("plotmath","latex"),
            lab.sep = c("cdot", "times"))

Arguments

x

numeric vector (e.g. axis tick locations)

drop.1

logical indicating if \(1 \times\) should be dropped from the resulting expressions.

sub10

logical, "10", "100", an integer number or vector of length two, say \((k_1,k_2)\), indicating if some \(10^j\) expressions for \(j \in J\) should be formatted traditionally, notably e.g., \(10^0 \equiv 1\).
When a number, say \(k\), \(J = \{j; j \le k\}\) are all simplified, when a length–2 vector, \(J = \{j; k_1 \le j \le k_2\}\) are.

Special cases:

sub10 = TRUE:

use \(1\) instead of \(10^0\),

sub10 = "10":

short for c(-1,1), i.e., uses \(0.1\) for 10^{-1}, \(1\) for \(10^0\) and \(10\) for \(10^1\);

sub10 = "100":

short for c(-1,2), i.e., uses \(0.1\), \(1\), \(10\), and \(100\) for 10^{-1},..., 10^2.

sub10 = "1000":

short for c(-2,3), using \(0.01\), \(0.1\), ..., \(1000\) for 10^{-2},..., 10^3.

If it would not break back compatibility, the author would nowadays choose the default as sub10 = "1000".

digits

number of digits for mantissa (\(a\)) construction; the number of significant digits, see signif.

digits.fuzz

the old deprecated name for digits.

off

a numeric offset in eT <- floor(l10x + off) where l10x <- log10(abs(x)) and eT are the exponents \(k\) for label factors \(10^k\). Previously hardcoded to 10^-digits, the new default provides better results for subnormal abs(x) values.

lab.type

a string indicating how the result should look like. By default, (plotmath-compatible) expressions are returned. Alternatively, lab.type = "plotmath" returns LaTeX formatted strings for labels. (The latter is useful, e.g., when using the tikzDevice package to generate LaTeX-processed figures.)

lab.sep

character separator between mantissa and exponent for LaTeX labels; it will be prepended with a backslash, i.e., ‘"cdot"’ will use ‘"\cdot"’

Value

For the default lab.type = "plotmath", an expression of the same length as x, typically with elements of the form a %*% 10 ^ k. Exceptions are 0 which is kept simple, if drop.1 is true and \(a = 1\), 10 ^ k is used, and if sub10 is not false, a %*% 10 ^ 0 as a, and a %*% 10 ^ k as as the corresponding formatted number a * 10^k independently of drop.1.

Otherwise, a character vector of the same length as x. For lab.type = "latex", currently the only alternative to the default, these strings are LaTeX (math mode) compatible strings.

Note

If sub10 is set, it will typically be a small number such as 0, 1, or 2. Setting sub10 = TRUE will be interpreted as sub10 =1 where resulting exponents \(k\) will either be negative or \(k \ge 2\).

Author

Martin Maechler; Ben Bolker contributed lab.type = "latex" and lab.sep.

See also

axTexpr and eaxis() which build on pretty10exp(), notably the eaxis() example plots.

The new toLatex.numeric method which gives very similar results with option scientific = TRUE.
Further, axis, axTicks.

Examples

pretty10exp(-1:3 * 1000)
#> expression(-1 %*% 10^3, 0, 1 %*% 10^3, 2 %*% 10^3, 3 %*% 10^3)
pretty10exp(-1:3 * 1000, drop.1 = TRUE)
#> expression(-10^3, 0, 10^3, 2 %*% 10^3, 3 %*% 10^3)
pretty10exp(c(1,2,5,10,20,50,100,200) * 1e3)
#> expression(1 %*% 10^3, 2 %*% 10^3, 5 %*% 10^3, 1 %*% 10^4, 2 %*% 
#>     10^4, 5 %*% 10^4, 1 %*% 10^5, 2 %*% 10^5)
pretty10exp(c(1,2,5,10,20,50,100,200) * 1e3, drop.1 = TRUE)
#> expression(10^3, 2 %*% 10^3, 5 %*% 10^3, 10^4, 2 %*% 10^4, 5 %*% 
#>     10^4, 10^5, 2 %*% 10^5)

set.seed(17); lx <- rlnorm(10, m=8, s=6)
pretty10exp(lx, digits = 3)
#> expression(6.75 %*% 10^0, 1.85 %*% 10^3, 7.37 %*% 10^2, 2.21 %*% 
#>     10^1, 3.06 %*% 10^5, 1.1 %*% 10^3, 1.02 %*% 10^6, 8.86 %*% 
#>     10^7, 1.38 %*% 10^4, 2.69 %*% 10^4)
pretty10exp(lx, digits = 3, sub10 = 2)
#> expression(6.75, 1.85 %*% 10^3, 737, 22.1, 3.06 %*% 10^5, 1.1 %*% 
#>     10^3, 1.02 %*% 10^6, 8.86 %*% 10^7, 1.38 %*% 10^4, 2.69 %*% 
#>     10^4)

pretty10exp(lx, digits = 3, lab.type="latex")
#>  [1] "$6.75 \\cdot 10^{0}$" "$1.85 \\cdot 10^{3}$" "$7.37 \\cdot 10^{2}$"
#>  [4] "$2.21 \\cdot 10^{1}$" "$3.06 \\cdot 10^{5}$" "$1.1 \\cdot 10^{3}$" 
#>  [7] "$1.02 \\cdot 10^{6}$" "$8.86 \\cdot 10^{7}$" "$1.38 \\cdot 10^{4}$"
#> [10] "$2.69 \\cdot 10^{4}$"
pretty10exp(lx, digits = 3, lab.type="latex", lab.sep="times", sub10=2)
#>  [1] "6.75"                  "$1.85 \\times 10^{3}$" "737"                  
#>  [4] "22.1"                  "$3.06 \\times 10^{5}$" "$1.1 \\times 10^{3}$" 
#>  [7] "$1.02 \\times 10^{6}$" "$8.86 \\times 10^{7}$" "$1.38 \\times 10^{4}$"
#> [10] "$2.69 \\times 10^{4}$"

## use regular formatted numbers from 0.03 to 300 :
pretty10exp(3*10^(-3:4), sub10 = c(-2,2))
#> expression(3 %*% 10^-3, 0.03, 0.3, 3, 30, 300, 3 %*% 10^3, 3 %*% 
#>     10^4)
pretty10exp(3*10^(-3:4), sub10 = c(-2,2), lab.type = "l")
#> [1] "$3 \\cdot 10^{-3}$" "0.03"               "0.3"               
#> [4] "3"                  "30"                 "300"               
#> [7] "$3 \\cdot 10^{3}$"  "$3 \\cdot 10^{4}$" 

ax <- 10^(-6:0) - 2e-16
pretty10exp(ax, drop.1=TRUE) # nice for plotting
#> expression(10^-6, 10^-5, 10^-4, 10^-3, 10^-2, 10^-1, 10^0)
pretty10exp(ax, drop.1=TRUE, sub10=TRUE)
#> expression(10^-6, 10^-5, 10^-4, 10^-3, 10^-2, 10^-1, 1)
pretty10exp(ax, drop.1=TRUE, sub10=c(-2,2))
#> expression(10^-6, 10^-5, 10^-4, 10^-3, 0.01, 0.1, 1)

## in sfsmisc version <= 1.0-16, no 'digits',
## i.e., implicitly had  digits := #{double precision digits} ==
(dig. <- .Machine$double.digits * log10(2)) # 15.95
#> [1] 16
pretty10exp(ax, drop.1=TRUE, digits= dig.)  # ''ugly''
#> expression(9.999999998 %*% 10^-7, 9.9999999998 %*% 10^-6, 9.99999999998 %*% 
#>     10^-5, 9.999999999998 %*% 10^-4, 9.9999999999998 %*% 10^-3, 
#>     9.99999999999998 %*% 10^-2, 1 %*% 10^0)

## Subnormal numbers
x <- sort(c(outer(10^-(323:305), 1:9))); x <- c(x[1]/2, x)
tail(x, 12) # nice
#>  [1] 7e-306 8e-306 9e-306 1e-305 2e-305 3e-305 4e-305 5e-305 6e-305 7e-305
#> [11] 8e-305 9e-305
head(x, 6)  # "ugly" (they are multiple's of 2^-1074):
#> [1] 4.94e-324 9.88e-324 1.98e-323 2.96e-323 3.95e-323 4.94e-323
head(x, 6) / 2^-1074  # nice
#> [1]  1  2  4  6  8 10

head(p0 <- pretty10exp(x, off = 10^-7), 30) # previous behavior {before 'off' existed}
#> expression(Inf %*% 10^-324, Inf %*% 10^-324, 2 %*% 10^-323, 3 %*% 
#>     10^-323, 4 %*% 10^-323, 5 %*% 10^-323, 6 %*% 10^-323, 7 %*% 
#>     10^-323, 8 %*% 10^-323, 9 %*% 10^-323, 10 %*% 10^-323, 2 %*% 
#>     10^-322, 3 %*% 10^-322, 4 %*% 10^-322, 5 %*% 10^-322, 6 %*% 
#>     10^-322, 7 %*% 10^-322, 8 %*% 10^-322, 9 %*% 10^-322, 10.1 %*% 
#>     10^-322, 2 %*% 10^-321, 3 %*% 10^-321, 4 %*% 10^-321, 5 %*% 
#>     10^-321, 6 %*% 10^-321, 7 %*% 10^-321, 8 %*% 10^-321, 9 %*% 
#>     10^-321, 10.0198 %*% 10^-321, 2 %*% 10^-320)
str(head(pTen <- lapply(p0, `[[`, 3L)))
#> List of 6
#>  $ : language 10^-324
#>  $ : language 10^-324
#>  $ : language 10^-323
#>  $ : language 10^-323
#>  $ : language 10^-323
#>  $ : language 10^-323
str(exTen <- sapply(pTen, `[[`, 3L)) # -324 -324 ..
#>  num [1:172] -324 -324 -323 -323 -323 -323 -323 -323 -323 -323 ...
head(f0 <- sapply(p0, `[[`, 2L), 17)
#>  [1] Inf Inf   2   3   4   5   6   7   8   9  10   2   3   4   5   6   7

head(p1 <- pretty10exp(x))# new default
#> expression(0.5 %*% 10^-323, 1 %*% 10^-323, 2 %*% 10^-323, 3 %*% 
#>     10^-323, 4 %*% 10^-323, 5 %*% 10^-323)
str(head(pTen1 <- lapply(p1, `[[`, 3L)))
#> List of 6
#>  $ : language 10^-323
#>  $ : language 10^-323
#>  $ : language 10^-323
#>  $ : language 10^-323
#>  $ : language 10^-323
#>  $ : language 10^-323
str(exTen1 <- sapply(pTen1, `[[`, 3L)) # -324 -324 ..
#>  num [1:172] -323 -323 -323 -323 -323 -323 -323 -323 -323 -323 ...
head(f1 <- sapply(p1, `[[`, 2L), 17)   #
#>  [1] 0.5 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0

head(cbind(x, f0, f1, exTen, exTen1), 80)
#>               x   f0  f1 exTen exTen1
#>  [1,] 4.94e-324  Inf 0.5  -324   -323
#>  [2,] 9.88e-324  Inf 1.0  -324   -323
#>  [3,] 1.98e-323  2.0 2.0  -323   -323
#>  [4,] 2.96e-323  3.0 3.0  -323   -323
#>  [5,] 3.95e-323  4.0 4.0  -323   -323
#>  [6,] 4.94e-323  5.0 5.0  -323   -323
#>  [7,] 5.93e-323  6.0 6.0  -323   -323
#>  [8,] 6.92e-323  7.0 7.0  -323   -323
#>  [9,] 7.91e-323  8.0 8.0  -323   -323
#> [10,] 8.89e-323  9.0 9.0  -323   -323
#> [11,] 9.88e-323 10.0 1.0  -323   -322
#> [12,] 1.98e-322  2.0 2.0  -322   -322
#> [13,] 2.96e-322  3.0 3.0  -322   -322
#> [14,] 3.95e-322  4.0 4.0  -322   -322
#> [15,] 4.94e-322  5.0 5.0  -322   -322
#> [16,] 5.93e-322  6.0 6.0  -322   -322
#> [17,] 6.92e-322  7.0 7.0  -322   -322
#> [18,] 7.91e-322  8.0 8.0  -322   -322
#> [19,] 8.89e-322  9.0 9.0  -322   -322
#> [20,] 9.98e-322 10.1 1.0  -322   -321
#> [21,] 2.00e-321  2.0 2.0  -321   -321
#> [22,] 2.99e-321  3.0 3.0  -321   -321
#> [23,] 3.99e-321  4.0 4.0  -321   -321
#> [24,] 4.99e-321  5.0 5.0  -321   -321
#> [25,] 5.99e-321  6.0 6.0  -321   -321
#> [26,] 6.99e-321  7.0 7.0  -321   -321
#> [27,] 7.98e-321  8.0 8.0  -321   -321
#> [28,] 8.98e-321  9.0 9.0  -321   -321
#> [29,] 1.00e-320 10.0 1.0  -321   -320
#> [30,] 2.00e-320  2.0 2.0  -320   -320
#> [31,] 3.00e-320  3.0 3.0  -320   -320
#> [32,] 4.00e-320  4.0 4.0  -320   -320
#> [33,] 5.00e-320  5.0 5.0  -320   -320
#> [34,] 6.00e-320  6.0 6.0  -320   -320
#> [35,] 7.00e-320  7.0 7.0  -320   -320
#> [36,] 8.00e-320  8.0 8.0  -320   -320
#> [37,] 9.00e-320  9.0 9.0  -320   -320
#> [38,] 1.00e-319 10.0 1.0  -320   -319
#> [39,] 2.00e-319  2.0 2.0  -319   -319
#> [40,] 3.00e-319  3.0 3.0  -319   -319
#> [41,] 4.00e-319  4.0 4.0  -319   -319
#> [42,] 5.00e-319  5.0 5.0  -319   -319
#> [43,] 6.00e-319  6.0 6.0  -319   -319
#> [44,] 7.00e-319  7.0 7.0  -319   -319
#> [45,] 8.00e-319  8.0 8.0  -319   -319
#> [46,] 9.00e-319  9.0 9.0  -319   -319
#> [47,] 1.00e-318 10.0 1.0  -319   -318
#> [48,] 2.00e-318  2.0 2.0  -318   -318
#> [49,] 3.00e-318  3.0 3.0  -318   -318
#> [50,] 4.00e-318  4.0 4.0  -318   -318
#> [51,] 5.00e-318  5.0 5.0  -318   -318
#> [52,] 6.00e-318  6.0 6.0  -318   -318
#> [53,] 7.00e-318  7.0 7.0  -318   -318
#> [54,] 8.00e-318  8.0 8.0  -318   -318
#> [55,] 9.00e-318  9.0 9.0  -318   -318
#> [56,] 1.00e-317  1.0 1.0  -317   -317
#> [57,] 2.00e-317  2.0 2.0  -317   -317
#> [58,] 3.00e-317  3.0 3.0  -317   -317
#> [59,] 4.00e-317  4.0 4.0  -317   -317
#> [60,] 5.00e-317  5.0 5.0  -317   -317
#> [61,] 6.00e-317  6.0 6.0  -317   -317
#> [62,] 7.00e-317  7.0 7.0  -317   -317
#> [63,] 8.00e-317  8.0 8.0  -317   -317
#> [64,] 9.00e-317  9.0 9.0  -317   -317
#> [65,] 1.00e-316  1.0 1.0  -316   -316
#> [66,] 2.00e-316  2.0 2.0  -316   -316
#> [67,] 3.00e-316  3.0 3.0  -316   -316
#> [68,] 4.00e-316  4.0 4.0  -316   -316
#> [69,] 5.00e-316  5.0 5.0  -316   -316
#> [70,] 6.00e-316  6.0 6.0  -316   -316
#> [71,] 7.00e-316  7.0 7.0  -316   -316
#> [72,] 8.00e-316  8.0 8.0  -316   -316
#> [73,] 9.00e-316  9.0 9.0  -316   -316
#> [74,] 1.00e-315  1.0 1.0  -315   -315
#> [75,] 2.00e-315  2.0 2.0  -315   -315
#> [76,] 3.00e-315  3.0 3.0  -315   -315
#> [77,] 4.00e-315  4.0 4.0  -315   -315
#> [78,] 5.00e-315  5.0 5.0  -315   -315
#> [79,] 6.00e-315  6.0 6.0  -315   -315
#> [80,] 7.00e-315  7.0 7.0  -315   -315
(nEQ <- which(sapply(1:length(p0), function(i) p0[[i]] != p1[[i]])))
#> [1]  1  2 11 20 29 38 47
cbind(x, f0, f1, exTen, exTen1)[nEQ,]
#>              x   f0  f1 exTen exTen1
#> [1,] 4.94e-324  Inf 0.5  -324   -323
#> [2,] 9.88e-324  Inf 1.0  -324   -323
#> [3,] 9.88e-323 10.0 1.0  -323   -322
#> [4,] 9.98e-322 10.1 1.0  -322   -321
#> [5,] 1.00e-320 10.0 1.0  -321   -320
#> [6,] 1.00e-319 10.0 1.0  -320   -319
#> [7,] 1.00e-318 10.0 1.0  -319   -318
stopifnot(is.finite(f1), 0.5 <= f1, f1 <= 9)