library(unigd) temp <- airquality$Temp
The following guide walks through the basic features of unigd
and compares them with the plot rendering methods in base R.
Rendering a plot in base R is done by (1) starting a graphics device, (2) calling some plot functions and subsequently (3) closing the device:
temp <- airquality$Temp # Fetch some data png(file="my_plot1.png", width=600, height=400) # (1) Start the 'png' device hist(temp, col="darkblue") # (2) Plot a histogram dev.off() # (3) Close the device
Note that this has some unfortunate constraints:
png()
, pdf()
, svg()
, ...)file="my_plot1.png"
)width=600, height=400
)dev.off()
must be called every time.unigd
solves these issues by employing a different graphics device architecture.
unigd
Let's see how the same render can be created using unigd
:
library(unigd) temp <- airquality$Temp # Fetch some data ugd() # (1) Start the 'ugd' device hist(temp, col="darkblue") # (2) Plot a histogram ugd_save(file="my_plot1.png", width=600, height=400) # Render 600*400 PNG file dev.off() # (3) Close the device
Notice how rendering is an explicit instruction after plotting when using unigd. This way we can also render the same plot to multiple formats and/or dimensions:
# ... hist(temp, col="darkblue") ugd_save(file="my_plot1.png", width=600, height=400) # Render 600*400 PNG file ugd_save(file="my_plot2.pdf", width=300, height=300) # Render 300*300 PDF file # ...
Starting and closing a device can be cumbersome, especially if the plotting code aborts after an error and leaves the device open.
For this reason unigd
comes with a set of functions called ugd_*_inline
:
library(unigd) temp <- airquality$Temp # Fetch some data ugd_save_inline({ hist(temp, col="darkblue") }, file="my_plot1.png", width=600, height=400)
Plotting this way keeps you from having to create and close a device manually. Depending on your personal preference this may also be considered as more 'readable' code.
You can obtain the full list of included renderers with ugd_renderers()
. (It's growing with every unigd
update!)
The next section will illustrate how to access the render data directly without having to create a file.
For some applications, you might want to access the rendered data directly.
Example use-cases for this might be report generation, web services or interactive applications.
While you can most likely think of workarounds for this issue, this unigd
feature will certainly lower code complexity and increase performance.
Rendering in-memory is done by simply calling ugd_render(...)
instead of ugd_save(...)
:
temp <- airquality$Temp ugd() hist(temp, col="darkblue") my_svg <- ugd_render(as="svg") dev.off() cat(my_svg) # Print the SVG as a string
Of course there is also a inline function for this:
temp <- airquality$Temp my_svg <- ugd_render_inline({ hist(temp, col="darkblue") }, as="svg") cat(my_svg) # Print the SVG as a string
unigd
featuresunigd
offers a number of features which go beyond the base R graphics devices.
All rendering function in unigd
offer a zoom
parameter. This parameter can be
used to increase (or decrease) the size of objects inside a plot (independently
of plot dimensions). For example zoom=2
will increase the size of all objects
to 200%, zoom=0.5
will decrease them to 50%.
my_svg_1_0 <- ugd_render_inline({ hist(temp, col="darkblue", main = "Zoom 1.0") }, as="png-base64", width=300, height=300, zoom=1.0) my_svg_1_5 <- ugd_render_inline({ hist(temp, col="darkblue", main = "Zoom 1.5") }, as="png-base64", width=300, height=300, zoom=1.5) my_svg_0_5 <- ugd_render_inline({ hist(temp, col="darkblue", main = "Zoom 0.5") }, as="png-base64", width=300, height=300, zoom=0.5) # (Output directly in this RMarkdown document) knitr::raw_html(paste0(sprintf("<img src=\"%s\" />", c(my_svg_1_0, my_svg_1_5, my_svg_0_5))))
The page
parameter lets you select which plot should from the history should be rendered.
By default this is set to 0
which will use the last created plot. Set this to any number
≥ 1 to select a plot by it's index (oldest first). Use numbers ≤ 0 to select plots
newest-first:
ugd() for (i in 1:10) { plot(1, main=paste0("Plot #", i)) } ugd_save(file="plot.png", page = 3) # Plot #3 ugd_save(file="plot.png") # Plot #10 ugd_save(file="plot.png", page = -1) # Plot #9 dev.off()
Note that plots can be deleted from the history the same way:
# ... ugd_remove() # Remove last ugd_remove(page = -1) # Remove second-to-last ugd_clear() # Remove all # ...
Instead of keeping track of the plot index, which might change when plots are added and removed, static plot IDs can be obtained.
If you want to render a plot at a later point without having to keep track of its index, you can obtain its ID at any point after it's creation.
The following example extensively demonstrates how this can be used:
ugd() plot(rnorm(50)) # A first_plot_id <- ugd_id() # Get last ID (A at this point) hist(rnorm(50)) # B plot(sin((1:100)/3)) # C other_id <- ugd_id(-1) # Get the second-to-last ID (B at this point) hist(runif(100)) # D ugd_remove(3) # Remove 3rd plot (C) first_again <- ugd_id(1) # Get the first ID (A) ugd_save(file="plot_1.png", page = first_plot_id) ugd_save(file="plot_2.png", page = other_id) ugd_save(file="plot_3.png", page = first_again) dev.off()
Note that a typical use-case would be much simpler, and just be getting
the last ID after each plot by calling ugd_id()
subsequently.
unigd
also ships with a number of 'special' renderers. This guide will
not go into too much detail about this topic but here are some noteworthy mentions:
"strings"
-renderer "meta"
-renderer "json"
-rendererunigd
has about one plotWhile unigd
aims to provide the best performance in any case, there are some
considerations you can make when optimizing graphics rendering.
At this point it should be mentioned that for most user applications readability should be prioritized over performance and, unless graphics rendering is bottlenecking your R script, you can most likely ignore this section in good conscience.
When optimizing rendering code, it is fundamental to understand in what
cases unigd
needs to call into the R graphics engine to let a plot be re-drawn:
Rendering is done after drawing. The last drawn dimensions of a plot are cached. We can derive a few simple rules from this:
This means ordering the rendering calls will result in faster execution:
# SLOWER: ugd_save(file="my_plot1.png", width=600, height=400) ugd_save(file="my_plot2.pdf", width=300, height=300) # re-draw 1 ugd_save(file="my_plot3.pdf", width=600, height=400) # re-draw 2 # FASTER: ugd_save(file="my_plot1.png", width=600, height=400) ugd_save(file="my_plot3.pdf", width=600, height=400) ugd_save(file="my_plot2.pdf", width=300, height=300) # re-draw 1
And, while unigd
gives you the choice of specifying your render dimension
after plotting, you can hint them at device creation time to achieve the
best performance:
# SLOWER: ugd() # default dimensions: 720 * 576 # ... ugd_save(file="my_plot1.png", width=300, height=300) # re-draw # FASTER: ugd(width=300, height=300) # ... ugd_save(file="my_plot1.png", width=300, height=300)
If the dimensions are omitted when calling rendering functions, the last known dimensions will be used and rendering is guaranteed to be fast:
ugd_save(file="my_plot1.png")
Any use of ugd_*_inline
functions is also guaranteed to be fast.
Note that width and height also interact with the zoom
parameter. (i.e.: Cached width = width / zoom).
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.