Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ggplot2 graph quality in shiny on shinyapps.io

Problem Summary: ggplot2 graphs seem to be of poor quality in shiny, when hosted on shinyapps.io. Graph elements contain visible defects, e.g. dots of geom_point() are not round, some seem like triangles, other like rectangles etc. Legend looks as if it has been blown up from a low-res jpg. My example is here.

Question: are there any options to control graph quality, such as dpi?

Detailed description: Developing a simple Shiny application, I have noticed that ggplot graphs are a bit rough around the edges, and was unable to improve the situation. The example app demonstrates this well enough, notice how the dots seem to be of irregular shape. Their shape improves, approximating circularity, when I increase zoom (in Chrome) to 200% or more. On 100% zoom the whole graph looks weird and not smooth. As if when an image resolution is decreased by the factor of 0.77 or something like that, you get minor distortion artefacts; the similar effect is here. The easiest way to see it, is to download the image at 100% zoom (right click, save as), and then increase zoom on the local copy. You will see how dots are far from being round. The code for server.R and ui.R is very simple:

# ui.R

shinyUI(fluidPage(
    titlePanel("My Shiny App"),
    sidebarLayout(
        sidebarPanel(
            h4("The graph looks rough")),
        mainPanel(
            plotOutput("myplot",width=800,height=600)
        )
    )
))

and

# server.R

library(ggplot2)
data(mtcars)

shinyServer(
    function(input, output) {
        output$myplot <- renderPlot({
            p <- ggplot(data=mtcars,aes(x=mpg,y=disp,color=factor(cyl)))
            p <- p + geom_point()
            print(p)
        })
    }
)

I am curious whether this can be improved. Shiny is a powerful tool to communicate scientific results, yet the wow-effect is somehow undermined by these visual artefacts. Thanks!

EDIT: probably a more correct way to express the issue is to say that there is no antialiasing in the default PNG image.

EDIT 2: for this question to be of more value to other SO users, here are the screenshots of the graph before and after using the Cairo device (use zoom in your browser to get a better look at the difference):

Without Cairo graphWith Cairo graph

like image 413
Maxim.K Avatar asked Oct 09 '14 18:10

Maxim.K


1 Answers

Since you're probably on a Linux-based server, you will likely need to use the Cairo graphical library.

Cairo is a 2D graphics library with support for multiple output devices. Currently supported output targets include the X Window System (via both Xlib and XCB), Quartz, Win32, image buffers, PostScript, PDF, and SVG file output. Experimental backends include OpenGL, BeOS, OS/2, and DirectFB. Cairo is designed to produce consistent output on all output media while taking advantage of display hardware acceleration when available (eg. through the X Render Extension). Personally, I use it for the alpha channel (transparency options).

Conveniently, there is an R implementation that creates a cairo graphics device in the "Cairo" package. In effect, you have to add the following chunk to 'server.R':

#install.packages("Cairo")
library(Cairo)
options(shiny.usecairo=T)

That should do it.

PS: I see @MathewPlourde already answered this question in the comments.

like image 164
Serban Tanasa Avatar answered Nov 04 '22 12:11

Serban Tanasa