knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.path = "README-" )
ggbash provides a simpler ggplot2 syntax.
It features partial match, error messages, and builtin commands such as copy
or png
.
The goal of ggbash is to make ggplot2 more comfortable to write for every user, from beginners to professionals.
library(ggplot2)
ggbash(gg(iris) + point(Sepal.W, Sepal.L, col=Spec, sz=5) + theme(legend.txt(sz=20, face="bold")) | echo)
ggplot(iris)+geom_point(aes(Sepal.Width,Sepal.Length,colour=Species),size=5)+theme(legend.text=element_text(size=20,face="bold")) # gg iris + point Sepal.W Sepal.L col=Spec siz=Petal.W + theme text: size=20 face="bold"
# The output of the above ggbash 'echo' command ggplot(iris) + geom_point(aes(Sepal.Width, Sepal.Length, colour = Species), size = 5) + theme(legend.text = element_text(size = 20, face = "bold"))
ggbash also provides a bash-like REPL environment (ggbash environment, or ggbash session).
```{bash, eval=FALSE} library(ggbash) ggbash() # start a ggbash session
One advantage of ggbash session is that parentheses and commas become optional. ```{bash, eval=FALSE} gg iris + point Sepal.W Sepal.L col=Spec size=7 + theme lgnd.txt size=20 face="bold" | echo
If you prefer an extremely short code,
g iris + p Sepal.W Sepal.L c=Sp s=7 + theme l.tx s=20 f="bold"
will produce exactly the same plot, at the sacrifice of readability for beginners.
Even if the unique identification of specified elements
(geoms, aesthetics, column names, theme element names, etc.)
is not possible,
ggbash
anyway tries to execute its best guess
instead of bluntly returning an error.
For the above ggbash input gg iris + point Sepal.W Sepal.L c="red" sz=5
,
ggbash performs partial matches six times.
ggplot function
gg
matches ggplot2::ggplot()
.ggplot
or g
.geom names
point
matches geom_point
.geom_point
(i.e. write geom_
prefix explicitly).column names
Sepal.W
matches iris$Sepal.Width
.
Sepal.L
matches iris$Sepal.Length
.
aesthetics names
c
matches colour
, which is the aesthetic of geom_point
.sz
matches size
among size
, shape
, and stroke
by fuzzy match.Any of the following commands return exactly the same plot.
ggplot(iris)+geom_point(aes(x=Sepal.Width,y=Sepal.Length),colour="red",size=5) # 78 characters ggplot iris +geom_point x=Sepal.Width y=Sepal.Length colour="red" size=5 ggplot iris + point Sepal.Width Sepal.Length colour="red" size=5 gg iris + point Sepal.W Sepal.L col ="red" siz =5 gg iris + p Sepal.W Sepal.L c ="red" sz =5 g iris + p Sepal.W Sepal.L c ="red" s =5 # 38 characters
Users can select one of the styles which fits them best.
ggbash(gg(diamonds, x=caret, y=price) + point + smooth) # typo COMPILE ERROR: No such column names The column name "caret" does not exist. maybe: carat, clarity The built ggplot2 object is : ggplot(diamonds, aes( <<INVALID_TOKEN_HERE>> ) + geom_point() + geom_smooth()
ggbash has a compiler (ggbash compiler) which converts given ggbash "source code" into an "executable" ggplot2 object. During the compiling process, ggbash can detect various human errors such as element misspecifications (column names, aes names, theme element names, ...). Beginners can learn why their codes don't work from the generated diagnostics.
ggbash(gg(diamonds, x=carat, y=price) + point + smooth) # without typo
ggplot(mtcars) + geom_point(aes(x=mpg, y=wt)) + geom_smooth(aes(x=mpg, y=wt), method='loess')
echo
Print the built ggplot2 object as a string. Useful for learning ggplot2 original grammar iteratively.
```{bash, eval=FALSE} gg iris + point Sepal.W Sepal.L size=7 + theme lgnd.txt face="bold" | echo
```r # The output of ggbash 'echo' command ggplot(iris) + geom_point(aes(Sepal.Width, Sepal.Length), size = 7) + theme(legend.text = element_text(face = "bold"))
copy
ggbash(gg(iris) + p(Sepal.W, Sepal.L, col=Sp, siz=4) | copy) copied to clipboard: ggplot(iris) + geom_point(aes(x=Sepal.Length, y=Sepal.Width, colour=Species, size=Petal.Width))
png
and pdf
ggbash(gg(iris) + p(Sepal.W, Sepal.L, col=Sp) | png(my_image)) saved in: 'currentDir/my_image/iris-150/x-Sepal.Width_y-Sepal.Length-colour-Species.960x960.png'
If you would like to get a scatterplot matrix,
for( i in 1:ncol(iris) ) for ( j in min(i+1, ncol(iris)):ncol(iris) ) ggbash(paste("gg iris + point ", colnames(iris)[i], colnames(iris)[j], " | png my_image"))
png
and pdf
arguments are order-agnostic: Any of the following notations
generates the same png file "my_image/iris-150/point-my-plot.1960x1480.png"
.
```{bash, eval=FALSE} gg mtcars | p mpg cyl | png "my-plot" 19601480 my_image gg mtcars | p mpg cyl | png "my-plot" my_image 19601480 gg mtcars | p mpg cyl | png my_image 19601480 "my-plot" gg mtcars | p mpg cyl | png my_image "my-plot" 19601480 gg mtcars | p mpg cyl | png 19601480 "my-plot" my_image gg mtcars | p mpg cyl | png 19601480 my_image "my-plot"
ggbash(gg(mtcars) + p(mpg,cyl) | png(1960*1480, my_image, "my_plot"))
`png` and `pdf` commands interpret a single- or double-quoted token as file name (`"my-plot"` in the following example), a token with `*` infix as plot size, and otherwise directory name. ##### Guessing Inches or Pixels <!-- 1 inch == 2.54 cm --> <!-- While the `pdf` function in R only recognizes width and height as inches, --> The `pdf` command in ggbash recognizes both inches and pixels. **If the given `width` or `height` in `(width)x(height)` is less than 50** (the same limit of `ggplot2::ggsave`) **, the numbers are interpreted as inches (1 inch = 2.54 cm).** ```{bash, eval=FALSE} # pdf of 15 inch width (=~ 40 cm) and 9 inch height (=~ 23 cm) gg iris + p Sepal.W Sepal.L | pdf 16*9 # pdf of 1440 pixel (=~ 50 cm) width and height gg iris + p Sepal.W Sepal.L | pdf 1440*1440 # the png command in ggbash also recognises inches and pixels gg iris + p Sepal.W Sepal.L | png 16*9
Note: the default dpi (dots per inch) in ggbash is
72 (R's default) and cannot be changed.
If you would like to change the dpi,
you could consider ggplot2::ggsave(..., dpi=...)
.
With iris
dataset which has 150 rows,
the plot of gg iris + p Sepal.W Sepal.L | png
is saved
in iris-150/point_x-Sepal.Width_y-Sepal.Length.960x960.png
.
If you happen to have another iris
dataset
which has a different number of rows (say 33),
the same command result is saved in iris-33/
directory.
# install.packages("devtools") devtools::install_github("caprice-j/ggbash")
If you get no appender.console()
error,
you might need install.packages('rly')
.
packageVersion('rly')
should be at least 1.4.2.
This package is still in its infancy, and might contain several installation bugs.
Currently, I am in my school semester and suspending ggbash development. Please wait till May 2017 :)
The goal of ggbash is to make ggplot2 more comfortable to write. It can be categorized into two subgoals:
Better EDA experience. Provide blazingly fast way to do exploratory data anslysis.
less typing by Partial Match.
casually save plots with Pipe Operators and Auto-generated Filenames.
Intuitive finalization (to be implemented). Make it more intuitive to finalize your plots.
adjust colours or lineweights
rotate axis labels
decide tick label intervals and limits
ggbash
follows original ggplot2 syntax
as much as possible for reducing learning costs of current ggplot2 users.
Learning ggplot2 might be the best way to understand ggbash syntax. The document and book of ggplot2 would be helpful.
The vignette of ggbash is still in a draft.
As far as I know, there are no previous attempts to implement a higher-level language that transcompiles to ggplot2. Reports of similar attempts are welcomed.
ggbash
draws inspiration from some other higher level programming
languages including Bash, CoffeeScript, Ruby, and Lisp.
Fixit is inspired by Fix-It Hints in clang C++ compiler.
ggbash has some weird specification due to parsing rule constraints:
ggbash is first released on December 29, 2016.
DONE:
TODO:
png "my-%aes%-%facet%"
)HOW:
prompt()
does not have built-in completions)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.