How to Generate Ascii "Graphical Output" from R

How can I generate ascii graphical output from R?

You should look at the fairly recent txtplot package. Currently, it includes scatterplot, line plot, density plot, acf, and bar chart.

From the online help,

> txtplot(cars[,1], cars[,2])
+----+------------+------------+-----------+------------+--+
120 + * +
| |
100 + +
| * * |
80 + * * +
| * * * |
60 + * * +
| * * * * * |
40 + * * * * * +
| * * * * * * * |
20 + * * * * * * * +
| * * * * |
| * * * |
0 +----+------------+------------+-----------+------------+--+
5 10 15 20 25

ASCII Plotting Functions for R

There are a number of things that can do bits of it. There's stem in default R, there's this scatter plot function, but best of all, there's the package txtplot on CRAN which does scatterplots, boxplots, barplots, density traces, acfs and plots curves (like the curve function... kinda).

I only need it once in a while - but if I am trying to convey a rough idea of a graphic in pure text as I sometimes need to, it's a life-saver.

In the past I wrote a short piece of R code that made tally-style ascii graphic in very quick time (like a sideways barchart or a stem-and-leaf plot with the numbers replaced by symbols, which solved a problem I had) - but I didn't keep it since stem mostly covers that territory.

Of course the 'table' facility produces ascii output and can be manipulated to do some interesting/useful semigraphical things.

There's also the package ascii that can be used to render various R objects into ascii form in similar fashion to Sweave - handy for formatting tables and so on. Just formatting a table into ascii is not really what it's for but you might still be able to get some use out of it with a little work and the right output format.

Sample output from txtplot:

scatter plot:

 > with(cars,txtplot(speed,dist))
+----+-----------+------------+-----------+-----------+--+
120 + * +
| |
100 + +
| * * |
80 + * * +
| * * * |
60 + * * +
| * * * * * |
40 + * * * * * +
| * * * * * * * |
20 + * * * * * * * +
| * * * * |
| * * * |
0 +----+-----------+------------+-----------+-----------+--+
5 10 15 20 25

acf plot:

 > txtacf(ldeaths)
+-+--------------+--------------+--------------+--------+
1 + * +
| * |
| * * * * * |
0.5 + * * * * * +
| * * * * * * * * |
| * * * * * * * * |
| * * * * * * * * |
0 + * * * * * * * * * * * * * * * * * * * * * +
| * * * * * * * * * * |
| * * * * * * * * * * |
| * * * * * * * * * |
-0.5 + * * * * * * +
| * * * * |
+-+--------------+--------------+--------------+--------+
0 0.5 1 1.5

density trace:

 > txtdensity(rnorm(100,m=5,s=.1))
+------+----------+----------+----------+----------+-------+
| ***** |
4 + ** *** +
| * *** |
| ** *** |
3 + ** *** +
| *** ** |
| ***** ** |
2 + *** ** +
| *** ** |
| ** ** |
1 + ** *** +
| *** ****** |
| ******** *** |
+------+----------+----------+----------+----------+-------+
4.8 4.9 5 5.1 5.2

box plot:

 > vc <- ToothGrowth[,2]=="VC"
> oj <- ToothGrowth[,2]=="OJ"
> txtboxplot(ToothGrowth[vc,1],ToothGrowth[oj,1])
5 10 15 20 25 30 35
|----+-------+--------+--------+--------+--------+-------+--|
+--------+-----------+
1 -------------| | |------------------
+--------+-----------+
+------------+----+
2 -------------| | |---------
+------------+----+
Legend: 1=ToothGrowth[vc, 1], 2=ToothGrowth[oj, 1]

curve plot:

 > txtcurve(sin(pi*x),from=0,to=2)
+--+-----------+------------+------------+-----------+--+
1 + ********* +
| *** ** |
| ** ** |
0.5 + ** ** +
| ** ** |
| * ** |
0 + * ** * +
| * * |
| ** ** |
-0.5 + *** ** +
| ** ** |
| ** *** |
-1 + ********* +
+--+-----------+------------+------------+-----------+--+
0 0.5 1 1.5 2

bar chart:

 > txtbarchart(as.factor(res),pch="|")
+--+------------+------------+------------+------------+--+
50 + | +
| | |
40 + | +
| | |
30 + | | +
| | | |
| | | |
20 + | | | +
| | | | |
10 + | | | +
| | | | |
0 + | | | +
+--+------------+------------+------------+------------+--+
1 1.5 2 2.5 3
Legend: 1=A, 2=B, 3=C

Add in the stem function from default R graphics:

> stem(log(islands,10))

The decimal point is at the |

1 | 1111112222233444
1 | 5555556666667899999
2 | 3344
2 | 59
3 |
3 | 5678
4 | 012

and you have quite a lot of coverage.

Text Based Graphs in R

You could try the txtplot package, see also: https://stackoverflow.com/a/9151960/567015

How to create ascii-only tables as output in R, similar to MySQL style?

Using your data:

d <- data.frame(id = 1:3, va1 = rep("asdf", 3), var2 = c("g","h","j"),
stringsAsFactors = FALSE)

here is something to get you started, at least and might be sufficient for simple tables.

asciify <- function(df, pad = 1, ...) {
## error checking
stopifnot(is.data.frame(df))
## internal functions
SepLine <- function(n, pad = 1) {
tmp <- lapply(n, function(x, pad) paste(rep("-", x + (2* pad)),
collapse = ""),
pad = pad)
paste0("+", paste(tmp, collapse = "+"), "+")
}
Row <- function(x, n, pad = 1) {
foo <- function(i, x, n) {
fmt <- paste0("%", n[i], "s")
sprintf(fmt, as.character(x[i]))
}
rowc <- sapply(seq_along(x), foo, x = x, n = n)
paste0("|", paste(paste0(rep(" ", pad), rowc, rep(" ", pad)),
collapse = "|"),
"|")
}
## convert everything to characters
df <- as.matrix(df)
## nchar in data
mdf <- apply(df, 2, function(x) max(nchar(x)))
## nchar in names
cnames <- nchar(colnames(df))
## max nchar of name+data per elements
M <- pmax(mdf, cnames)
## write the header
sep <- SepLine(M, pad = pad)
writeLines(sep)
writeLines(Row(colnames(df), M, pad = pad))
writeLines(sep)
## write the rows
for(i in seq_len(nrow(df))) {
## write a row
writeLines(Row(df[i,], M, pad = pad))
## write separator
writeLines(sep)
}
invisible(df)
}

In use we get:

> asciify(d)
+----+------+------+
| id | va1 | var2 |
+----+------+------+
| 1 | asdf | g |
+----+------+------+
| 2 | asdf | h |
+----+------+------+
| 3 | asdf | j |
+----+------+------+

On something a bit more complex we get

> asciify(mtcars)
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| mpg | cyl | disp | hp | drat | wt | qsec | vs | am | gear | carb |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| 21 | 6 | 160 | 110 | 3.9 | 2.62 | 16.46 | 0 | 1 | 4 | 4 |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| 21 | 6 | 160 | 110 | 3.9 | 2.875 | 17.02 | 0 | 1 | 4 | 4 |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| 22.8 | 4 | 108 | 93 | 3.85 | 2.32 | 18.61 | 1 | 1 | 4 | 1 |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| 21.4 | 6 | 258 | 110 | 3.08 | 3.215 | 19.44 | 1 | 0 | 3 | 1 |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| 18.7 | 8 | 360 | 175 | 3.15 | 3.44 | 17.02 | 0 | 0 | 3 | 2 |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| 18.1 | 6 | 225 | 105 | 2.76 | 3.46 | 20.22 | 1 | 0 | 3 | 1 |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| 14.3 | 8 | 360 | 245 | 3.21 | 3.57 | 15.84 | 0 | 0 | 3 | 4 |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| 24.4 | 4 | 146.7 | 62 | 3.69 | 3.19 | 20 | 1 | 0 | 4 | 2 |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| 22.8 | 4 | 140.8 | 95 | 3.92 | 3.15 | 22.9 | 1 | 0 | 4 | 2 |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| 19.2 | 6 | 167.6 | 123 | 3.92 | 3.44 | 18.3 | 1 | 0 | 4 | 4 |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| 17.8 | 6 | 167.6 | 123 | 3.92 | 3.44 | 18.9 | 1 | 0 | 4 | 4 |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| 16.4 | 8 | 275.8 | 180 | 3.07 | 4.07 | 17.4 | 0 | 0 | 3 | 3 |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| 17.3 | 8 | 275.8 | 180 | 3.07 | 3.73 | 17.6 | 0 | 0 | 3 | 3 |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| 15.2 | 8 | 275.8 | 180 | 3.07 | 3.78 | 18 | 0 | 0 | 3 | 3 |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| 10.4 | 8 | 472 | 205 | 2.93 | 5.25 | 17.98 | 0 | 0 | 3 | 4 |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| 10.4 | 8 | 460 | 215 | 3 | 5.424 | 17.82 | 0 | 0 | 3 | 4 |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| 14.7 | 8 | 440 | 230 | 3.23 | 5.345 | 17.42 | 0 | 0 | 3 | 4 |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| 32.4 | 4 | 78.7 | 66 | 4.08 | 2.2 | 19.47 | 1 | 1 | 4 | 1 |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| 30.4 | 4 | 75.7 | 52 | 4.93 | 1.615 | 18.52 | 1 | 1 | 4 | 2 |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| 33.9 | 4 | 71.1 | 65 | 4.22 | 1.835 | 19.9 | 1 | 1 | 4 | 1 |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| 21.5 | 4 | 120.1 | 97 | 3.7 | 2.465 | 20.01 | 1 | 0 | 3 | 1 |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| 15.5 | 8 | 318 | 150 | 2.76 | 3.52 | 16.87 | 0 | 0 | 3 | 2 |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| 15.2 | 8 | 304 | 150 | 3.15 | 3.435 | 17.3 | 0 | 0 | 3 | 2 |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| 13.3 | 8 | 350 | 245 | 3.73 | 3.84 | 15.41 | 0 | 0 | 3 | 4 |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| 19.2 | 8 | 400 | 175 | 3.08 | 3.845 | 17.05 | 0 | 0 | 3 | 2 |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| 27.3 | 4 | 79 | 66 | 4.08 | 1.935 | 18.9 | 1 | 1 | 4 | 1 |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| 26 | 4 | 120.3 | 91 | 4.43 | 2.14 | 16.7 | 0 | 1 | 5 | 2 |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| 30.4 | 4 | 95.1 | 113 | 3.77 | 1.513 | 16.9 | 1 | 1 | 5 | 2 |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| 15.8 | 8 | 351 | 264 | 4.22 | 3.17 | 14.5 | 0 | 1 | 5 | 4 |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| 19.7 | 6 | 145 | 175 | 3.62 | 2.77 | 15.5 | 0 | 1 | 5 | 6 |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| 15 | 8 | 301 | 335 | 3.54 | 3.57 | 14.6 | 0 | 1 | 5 | 8 |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+
| 21.4 | 4 | 121 | 109 | 4.11 | 2.78 | 18.6 | 1 | 1 | 4 | 2 |
+------+-----+-------+-----+------+-------+-------+----+----+------+------+

Note that the code doesn't handle aligning numeric data on their decimal points but the code for the internal Row() function could be modified to suit as all that requires is slightly different sprintf() call. Also, I realise I have right-aligned the strings which is not what you showed in the example table but not a terminal failure!

To get the output in a file, capture the output from asciify() using capture.output():

> capture.output(asciify(d), file = "asciified_d.txt")
> readLines("asciified_d.txt")
[1] "+----+------+------+" "| id | va1 | var2 |" "+----+------+------+"
[4] "| 1 | asdf | g |" "+----+------+------+" "| 2 | asdf | h |"
[7] "+----+------+------+" "| 3 | asdf | j |" "+----+------+------+"

(Note the output shown above is just a vector of character strings, each one a line in the captured file. The file looks like this on disk:

$ cat asciified_d.txt 
+----+------+------+
| id | va1 | var2 |
+----+------+------+
| 1 | asdf | g |
+----+------+------+
| 2 | asdf | h |
+----+------+------+
| 3 | asdf | j |
+----+------+------+

.)

I haven't checked this much and it will more than likely be shown to fail in a number of cases, but it works for basic data frames.

Update asciify() now handles data frames with factors as well as character and numeric data:

> require(ggplot2)
> asciify(head(diamonds))
+-------+-----------+-------+---------+-------+-------+-------+------+------+------+
| carat | cut | color | clarity | depth | table | price | x | y | z |
+-------+-----------+-------+---------+-------+-------+-------+------+------+------+
| 0.23 | Ideal | E | SI2 | 61.5 | 55 | 326 | 3.95 | 3.98 | 2.43 |
+-------+-----------+-------+---------+-------+-------+-------+------+------+------+
| 0.21 | Premium | E | SI1 | 59.8 | 61 | 326 | 3.89 | 3.84 | 2.31 |
+-------+-----------+-------+---------+-------+-------+-------+------+------+------+
| 0.23 | Good | E | VS1 | 56.9 | 65 | 327 | 4.05 | 4.07 | 2.31 |
+-------+-----------+-------+---------+-------+-------+-------+------+------+------+
| 0.29 | Premium | I | VS2 | 62.4 | 58 | 334 | 4.20 | 4.23 | 2.63 |
+-------+-----------+-------+---------+-------+-------+-------+------+------+------+
| 0.31 | Good | J | SI2 | 63.3 | 58 | 335 | 4.34 | 4.35 | 2.75 |
+-------+-----------+-------+---------+-------+-------+-------+------+------+------+
| 0.24 | Very Good | J | VVS2 | 62.8 | 57 | 336 | 3.94 | 3.96 | 2.48 |
+-------+-----------+-------+---------+-------+-------+-------+------+------+------+

Show an ASCII character

You can use backslash to escape otherwise unprintable characters:

print("\245")

displays the Yen character (¥) on my gui. The 245 is in octal format, so the above expression is printing out ASCII (or whatever encoding the GUI is using) character 165.

219 is 333 in octal, but

print("\333")

prints out the Û character on my gui.


A few (but by no means all) unicode characters are also supported on the R gui:

cyrillic_d <- "\u0414"
print(cyrillic_d)

outputs Д.

Convert each integer to a simple ASCII graph

You may use this awk:

awk '{s = sprintf("%*s", $1, ""); gsub(/ /, "*", s); p = sprintf("%*s", 10-$1, ""); gsub(/ /, "-", p); print s p}' file

******----
**--------
***-------
****------
***-------

A more readable version:

awk '{
s = sprintf("%*s", $1, "")
gsub(/ /, "*", s)
p = sprintf("%*s", 10-$1, "")
gsub(/ /, "-", p)
print s p
}' file

Raster to ASCII export in R- ASCII full of NA's

Your raster mostly consists of NAs, as can be illustrated like this (I prefer to use terra the replacement of raster):

library(terra)
x <- rast("ntl.tif")
plot(x, colNA="light blue")

Sample Image

Most of the image is light blue, that is, covered with cells that are NA

You can remove most NAs with trim

y <- trim(x)
plot(y, colNA="light blue")

Sample Image

You are not saying why you are creating an ascii file. I assume that you want to read the values with some other tool that does not know about spatial data file formats. In that case you might consider as.data.frame with na.rm=TRUE instead.

d <- as.data.frame(x, na.rm=TRUE, cells=TRUE)
head(d)
# cell ntl
#44592 44592 3.615484
#44593 44593 6.819953
#45010 45010 2.256919
#45011 45011 3.350195
#45012 45012 9.617457
#45013 45013 8.812189

And then save it to file, for example with

write.csv(d, "test.csv", row.names=FALSE)

R, generate pretty plot by dfSummary

A little update on this:

  • Always use knitr chunk option results='asis', as someone pointed in an earlier comment.
  • It is possible to generate summaries including png graphs using print():

    print(dfSummary(iris), method = "render")

  • Starting with version 0.9.0 (available only on GitHub as of Feb. 2019), markdown summaries will also include png graphs provided you specify the following arguments:

    • plain.ascii = FALSE
    • style = "grid"
    • a physical location for temporary png's (tmp.img.dir)

      dfSummary(iris, plain.ascii = FALSE, style = "grid", tmp.img.dir = "/tmp")

Additionnal tips

  • In both cases, you will (in all likelihood) need to adjust the size of the graphs with dfSummary()'s graph.magnif parameter (try values between .75 and .85).
  • Exclude a column or two to avoid overly wide summaries:

    dfSummary(iris, [...], varnumbers = FALSE, valid.col = FALSE)

Tool to create ASCII graph from a set of vertices and edges?

Yes! Perl has Graph::Easy, as described in this Hacker News comment.

Here's some output from the online demo:

........     +---------+     +-----+
: Bonn : --> | Berlin | ..> | Ulm |
:......: +---------+ +-----+
H
H train
v
+---------+
| Koblenz |
+---------+


Related Topics



Leave a reply



Submit