Lines overlaid on ggplot2 bar plot when saved with ggsave() - r

When I view this bar plot in R Studio, it appears as I intended (this is from a screenshot):
However, when I use the ggsave("filename.png") function, it appears with light-colored lines overlaid (may have to look closely to see):
I'm using R version 3.2.3, ggplot2 version 2.00, and R Studio version 0.99.486, on OS X 10.11.3.
Why might this be happening?

You should check out the Cairo library. I use it for crisp graphics in presentations and reports.
Cairo initializes a new graphics device that uses the cairo graphics
library for rendering. The current implementation produces
high-quality PNG, JPEG, TIFF bitmap files, high resolution PDF files
with embedded fonts, SVG graphics and PostScript files. It also
provides X11 and Windows interactive graphics devices. Unlike other
devices it supports all graphics features including alpha blending,
anti-aliasing etc.
I can't reproduce your example, but here's a similar one.
library("ggplot2")
pl <- ggplot(aggregate(mpg ~ cyl, mtcars, FUN=mean),
aes(x = cyl, y = mpg)) +
geom_bar(stat="identity", fill="red3") +
theme_bw()
library("Cairo")
CairoPNG("CairoCarPlot.png")
pl
dev.off()
Uploading the PNG, it looks like:

Throwing this out there in case it helps anyone else. I had this same issue when the stacked bar chart was made up of multiple values, I fixed it by grouping and then summarizing. I think for your data it would be:
df <- dataframe %>% group_by(Weekday) %>% summarize(percent=sum(percentage of tweets))

Related

Saving filled contour plots to PDF in R gives pixelated results

Saving the output of one of R's built-in examples for the filled.contour function to PDF:
pdf('test.pdf')
require("grDevices")
filled.contour(volcano, asp = 1)
dev.off()
produces a discretised result (see below). Is there any way to fix this? System info:
> sessionInfo()
R version 3.6.3 (2020-02-29)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 20.04.1 LTS
Edit after the accepted answer:
The problem is actually reported in the documentation of the pdf function:
If you see problems with PDF output, do remember that the
problem is much more likely to be in your viewer than in R ...
Symptoms for which the viewer has been at fault are apparent
grids on image plots ...
Unfortunately the default viewers on most Linux and macOS
systems have these problems, and no obvious way to turn off
graphics anti-aliasing.
It's an odd place to document the problem because the subdivision into rectangular segments is clearly caused by filled.contour and not by pdf. Otherwise ggplot2's output would also suffer from the same issue.
That is likely a result of antialiasing: when you display the image, it draws squares one at a time. As they are being drawn, the edge is a mix of the square colours and the white background, so it is drawn lighter.
Unfortunately, this isn't something that's really under your control. It's the PDF previewer that is introducing the artifacts. See this page https://codedocean.wordpress.com/2014/02/03/anti-aliasing-and-image-plots/ for a discussion.
The recommendation there worked for me: use the png() device with type = "cairo". This gives bitmapped output rather than the vector output of a pdf().
png('test.png',type="cairo")
filled.contour(volcano, asp = 1)
dev.off()
Edited to add:
I don't think you can do better with filled.contour, but if you are willing to switch to ggplot2 graphics you can. When it draws filled contours it appears to do it using polygons, not the image style plot that filled.contour uses. This still shows the same antialiasing bugs in the previewer, but now the lines appear along the borders between colours, which is much less irritating. For example:
df <- data.frame(x = as.numeric(row(volcano)-1)/(nrow(volcano)-1),
y = as.numeric(col(volcano)-1)/(ncol(volcano)-1),
z = as.numeric(volcano))
pdf('test.pdf')
library(ggplot2)
ggplot(df, aes(x=x, y=y, z=z)) +
geom_contour_filled()
dev.off()
I don't know how to get the same palette as filled.contour uses, i.e. function(n) hcl.colors(n, "YlOrRd", rev = TRUE). Maybe someone else can show us in a comment.

R - ggplot2 poor quality of charts generated on Windows

Why lines in a chart generated from ggplot2 on Mac looks so smooth and round, but on Windows they look so sharp and edgy. Is there any option to fix that on Windows instead of going to the Apple Store?
For example, chart generated on Mac:
and a chart generated on Windows:
Edit:
Due to #thestatnoob answer, this is a plot generated from iris dataset on R 3.0.2, RStudio 0.99.486, chart resolution: 640x480.
data(iris)
library(ggplot2)
ggplot(data = iris) +
geom_density(aes(x = Sepal.Length, y = ..scaled.., fill = Species), alpha = 0.5)
Anti-aliasing options from the Cairo package in R solved the issue
This might be due to a rendering error rather than anything else. R graphics do look more low res and "edgy". Try plotting the exact same dataset in both OS's with the same settings, e.g. PNG/PS/PDF with identical resolution. If it turns out that the Windows plot doesn't look great, an alternative solution would be to:
Use RStudio, which is a GUI for R and produces "smooth" graphics, even on Windows
Use R in a MS PowerShell/command prompt

Oddly shaped markers in ggplot2

I recently installed ggplot2 and tried a qplot. The plot comes out like this,
If you notice you can see that the markers seem to look deformed rather than circles. Is there a way to correct this?
Here is my code:
require(ggplot2)
set.seed(1410)
qplot(carat, price, data = diamonds)
EDIT: The plot looks fine when exported to a pdf.
I am using R3.0.2 ggplot2_0.9.3.1 on elementary OS.Thanks.
I usually don't worry about the look of the picture in the "window view" / "r view" -- it is just a graphical view of what the picture will look given the current setting for the resolution.
If possible, I save a picture as an eps or pdf file. They are vector based picture and scale well regardless of size.
If I don't use an eps or pdf file, I use png files to save my pictures:
g1 <- ggplot(data, aes(x=X1, y=Y1)+
geom_point(x)
png("high_res_png.png", width = 10000, height = 7000, res = 1300)
print(g1)
dev.off()
Using a lot of pixels on a png will prevent the "saved" picture from looking "fuzzy" or "oddly" shaped (the size of it will be large, but the png looks good even when you zoom in). Hope that helps.
The goofy looking circles is an artifact of your window system; on my Mac OS X (Quartz) setup, default qplot gives great-looking circles. However, I recall that the points do look a little like yours on my Linux box at home...
Shape is customizable, though. The following gives squares rotated 45 degrees, for instance:
qplot(carat, price, data = diamonds) + scale_shape_identity() + geom_point(shape = 23)

Why does this R ggplot2 code bring up a blank display device?

While SO is not usually used for help with bugs, this one shows particularly simple and particularly annoying behavior. If you are a ggplot2 user, you can reproduce it in 10 seconds or less.
As this GitHub issue: ggplot_gtable creates blank display says, the following code
library(ggplot2)
stat = qplot(Sepal.Length, Petal.Length, data = iris, color = Species)
ggplot_gtable(ggplot_build(stat))
will produce a blank device. Note that since ggplot2 is a graphics library, some commands can bring up a graphics device to show the relevant plot. Specifically, just running ggplot_build(stat) will bring up a plot. But that doesn't explain this behaviour.
I'm not sure how to debug this (print statements don't really seem appropriate or useful), and the ggplot2 development community seems to be on vacation or something, so if any experienced R user can offer suggestions on how to debug this effectively, I would appreciate it. This is a trivial but incredibly annoying bug. Every time I run code which looks like the snippet, it brings up a blank device which the display switches focus to, and so I have to click it away before I can continue.
It is possible that I'm doing something horribly wrong and am the only person who can reproduce this bug. It is also possible, for some reason I can't imagine, that this is normal behavior. If you think either of these things are true, please let me know.
I'm using ggplot2 0.9.3.1 (latest release) on Debian squeeze.
Some grid grobs have units that can only be resolved at drawing time, that is to say once a device window is open. This is the case of text grobs, for instance, as their size can depend (in the most general case) of the cex and fontsize arguments of the parent(s) viewports (which can be nested, etc.)
library(grid)
widthDetails(textGrob("hi"))
The current version of ggplot2 appears to use widthDetails in the code to build the legend grobs (guides_build function). It is conceivable that this could be replaced by grobWidth, unless the grob size is too convoluted.
I wonder if it is related to this thread from 3 years ago on R-Help with this workaround from #G.Grothendieck (copied material follows)
https://stat.ethz.ch/pipermail/r-help/2010-December/263754.html
library(lattice)
library(zoo)
df <- data.frame(y = matrix(rnorm(24), nrow = 6), x = 1:6)
xyplot(zoo(df[1:4], df$x), type = "p")
plot.object <- xyplot(zoo(df[1:4], df$x), type = "p")
# problem: a Quartz device is opened (on Mac OS X 10.6)
Grothendieck wrote in response:
This also opens up a window on Windows. It occurs within lattice
when lattice issues a trellis.par.get . A workaround would be to open
a device directed to null. On Windows this would work. I assume if
you use "/dev/null" it would work on your machine.
png("NUL")
plot.object <- ...
dev.off()
I am still having this issue with R 3.6.1 in 2019.
My lack of reputation doesn't allow me to comment. So I am writing yet another answer:
Things become a bit tricky if your plot uses non-standard fonts, say
library (ggplot2)
stat = qplot(Sepal.Length, Petal.Length, data = iris, color = Species) +
theme(text = element_text (family="DejaVu Sans"))
As was explained in the answer by baptiste, the output device is needed in order to determine some text dimensions. With the non-standard font, however, you need the appropriate output device. If you just use a pdf(file=NULL) as baptiste said, you get the dimensions wrong (and a warning that 'DejaVu Sans' was substituted by another font which is responsible for the false dimensions). In order to resolve this, I had to open an output device that is able to render the non-standard font (with a temporary file, say):
cairo_pdf (tempfile (fileext=".pdf"))
grob = ggplot_gtable (ggplot_build (stat))
dummy = dev.off ()
Hope this information is useful.
Problem seems to be caused by "color = Species".
If replaced by "group = Species", then no more blank display device.

Producing a vector graphics image (i.e. metafile) in R suitable for printing in Word 2007

First a caveat: I posted this question here on SuperUser, but it is clearly the wrong place to ask R questions. I recognize that it is not directly a programming question, but I believe it can be solved by changing how plots are produced (i.e. by coding appropriately). So I hope readers find this appropriate for the forum.
R plots usually consist entirely of vector graphics elements (i.e. points, lines, polygons, text). R permits you to save your figure (or copy-paste) in various formats including various raster formats, as a PDF, or as a Windows meta-file.
I usually save my images as PDFs and print them. This renders the images exactly as I intended them on paper, in the highest quality. I avoid raster formats (e.g. JPG, TIFF) for printing as inevitably the quality is poorer and publishers prefer vector formats.
However, I need to make a large multi-page desktop published document using Microsoft Word 2007, and therefore using PDFs is not an option. When I import my figures from meta-files, or copy and paste directly from R into Word both the screen and print rendering of the image changes slightly (e.g. polygons and their fills become slightly misaligned).
Given that I want to retain high vector quality (and not use raster formats), what can I do to make R vector graphics work with Word? (Of course Sweave and LaTeX would be nice, but again, not a realistic option).
Consider this example:
plot(c(1:100), c(1:100), pch=20)
## Copy and paste to Word 2007 as Windows metafile
## Print
## Quality is poorer (e.g. dot fills misaligned with borders)
pdf("printsPerfectly.pdf")
plot(c(1:100), c(1:100), pch=20)
dev.off()
## Now print PDF
## Quality is as expected
EDIT: Further to suggestions by #John I produced it as an EPS postscript file (see below), inserted it as a picture into Word. Because ultimately it will be printed from a PDF created from Word, I converted it to a PDF using default Word 2007 settings, printed it on my HP Laserjet P1606dn laser printer, and then took aphotograph to illustrate the issue of polygons borders and fills misaligning (image on left, below). I also produced it directly as PDF from R using pdf() and printed the PDF and took a photograph (image on right, below).
It may seem like small potatoes! But when you have gone to a lot of trouble to achieve high quality, it is disappointing to be thwarted at the end. In addition, it is not really obvious here, but the numerals are not as high-quality (left) as in the PDF (right), disregarding differences in focus on the photograph.
The accepted answer to me is not acceptable, since if one goes to the trouble of making a nice vector based figure, the last thing one would like to do is just rasterize it to a bitmap... Unless it's an increadibly complex graph that takes ages to render in vector format, or something like that, but for most graphs that's not the case.
The best solution is to export to Word directly in native Office vector format. I just made a new package, export, that allows one to do exactly that an allows export of either graphs or statistical tables to Word and Powerpoint, see
https://cran.r-project.org/web/packages/export/index.html and for demo see
https://github.com/tomwenseleers/export
For example:
library(devtools)
devtools::install_github("tomwenseleers/export")
library(export)
?graph2ppt
?graph2doc
?table2ppt
?table2doc
## export of ggplot2 plot
library(ggplot2)
qplot(Sepal.Length, Petal.Length, data = iris, color = Species,
size = Petal.Width, alpha = I(0.7))
# export to Word
graph2doc(file="ggplot2_plot.docx", width=7, height=5)
# export to Powerpoint
graph2ppt(file="ggplot2_plot.pptx", width=7, height=5)
You can also export to enhanced metafile using the function
graph2emf(file="ggplot2_plot.emf", width=7, height=5)
but the quality of the native Office format is better.
For final production you can also readily print it to PDF from Powerpoint if need be, and it will stay nicely in vector format then.
Your only option is to use high resolution raster graphics. Once you're over 300 dpi it will be completely indistinguishable from vector printed; it will just make larger files.. Your copy and paste method is coming in at 72 dpi and will look terrible. If you import from a file you can get the resolution in the file and things will be much better. Fortunately Office 2007 is supposed to handle png images, which have the best compression for typical graphs. Let's say you wanted the image 4" wide and 6" high...
png('printsGreat.png', width = 4, height = 6, units = 'in', res = 300)
plot(c(1:100), c(1:100), pch=20)
dev.off()
Also, Office 2007 is supposed to be able to handle EPS files and R postscript files are by default EPS compatible when you print one page.
postscript("printsPerfectly.eps", width = 4, height = 6, horizontal = FALSE, onefile = FALSE)
plot(c(1:100), c(1:100), pch=20)
dev.off()
But if you don't have luck with them go back to the high resolution image.
My preferred solution is to use the windows metafile device for plotting, e.g.:
win.metafile("mygraph.wmf")
print(gg1)
dev.off()
This produces a *.wmf file that can be copy-pasted into the word file.
The devEMF package seems to produce graphics that look nicer than the default wmf when pasted into PowerPoint.
Since I tried to produce png at high res in R and it didn't seem to work on my PC (if I set the resolution higher than, say, 300 dpi, R would produce an error like "cannot start png device"), the way I found was to save the figure using postscript() and then use GSView to convert the ps file into png with 600 dpi resolution. MS Word consumes the png's happily and the quality of print seems to be perfect.
What #Tom Wenseleers said:
The current best answer above to me is not acceptable, since if one
goes to the trouble of making a nice vector based figure, the last
thing one would like to do is just rasterize it to a bitmap... Unless
it's an increadibly complex graph that takes ages to render in vector
format, or something like that, but for most graphs that's not the
case.
For me, there is a new best answer to this question, since graph2ppt and graph2doc tend to move axis labels around (which apparently cannot be fixed; see here: https://github.com/davidgohel/rvg/blob/master/R/body_add_vg.R and here: export::graph2office moves axis labels around).
I think that .svg is the most appropriate vector format for usage with publication graphics. The only drawback is that older versions of e.g. MS Word cannot handle it. IN R, you could use the native graphics::svg - device. However, I'd recommend to use CairoSVG from the Cairo - Package, especially when you are working with non-native fonts (e.g. via the extrafont - package), because in contrast to graphics::svg, Cairo::CairoSVG embeds fonts quite nicely (without relying on GhostScript, if I am right).
If you are working with an older version of MS Word, you could use incscape (a free vector graphic editor) and convert your graph to .wmf, for example (which might be better than printing to .wmf directly, because R rasterizes points when exporting .wmf files).
An example:
## create plot
library (ggplot2)
library (extrafont)
# note: if you want to use other fonts than the standard ones - in this example "ChantillyLH" -
# you must register your fonts via
# font_import () ##run only once (type "y" in the console)
# and
# loadfonts (device = "win") ##run only once.
# Otherwise, the extrafont - package is not needed.
beautiful_plot <-
ggplot (data = iris, mapping = aes (x = Sepal.Length, y = Petal.Length)) +
geom_point () +
theme (text = element_text (size = 18,
family = "ChantillyLH")
)
# export SVG
library (Cairo)
CairoSVG ("My_Path/My_Plot.svg", width = 6, height = 6)
print (beautiful_plot)
dev.off ()
# the resulting SVG-file is in the the "My_Path" - Folder.
In Incscape, it looks like this:
Newer versions of Word can import raster graphics from SVG files. R 3.6.2 has built-in support for creating SVG files with the svg function - no extra packages needed.
Your example then becomes
svg("printsPerfectly.svg", width=4, height=4)
plot(c(1:100), c(1:100), pch=20)
dev.off()
Note that there is a known issue when you try to create PDF files from Word documents with embedded SVG files with thin lines. If you are using thin lines, e.g. with lwd=0.7 somewhere, you need to apply this workaround.

Resources