ggsave with non-ASCII plotmath labels using cairo - r

I have a non-ASCII axis label with a plotmath expression. When I try to save as png using cairo, I get an error:
library(ggplot2)
ggsave("test.png",
qplot(mtcars$hp, mtcars$cyl) +
ylab(expression(`cÜl`~italic(r)(italic(M)))) +
xlab(expression(hp~italic(hp))),
device = grDevices::png,
type = "cairo")
The error message is:
Metric information not available for this family/device
On the other hand, using the "windows" device works (except for a warning):
ggsave("test.png",
qplot(mtcars$hp, mtcars$cyl) +
ylab(expression(`cÜl`~italic(r)(italic(M)))) +
xlab(expression(hp~italic(hp))),
device = grDevices::png,
type = "windows")
The warning (in German) is:
In dev(filename = filename, width = dim[1], height = dim[2], ...) :
'width=7, height=7' sind unwahrscheinliche Pixelzahlen
Finally, non-ASCII axis labels are not a problem per se, if the label is not a plotmath expression:
ggsave("test.png",
qplot(mtcars$hp, mtcars$cyl) +
ylab("cÜl") +
xlab(expression(hp~italic(hp))),
device = grDevices::png,
type = "cairo")
The last command raises no error.
However, I would prefer to use cairo, since it draws nicer pictures sometimes. Any ideas?

This worked on a Windows machine with R 4.0.2 (and also on linux):
library(ggplot2)
library(ggtext)
ggsave("test.png", width = 6, height = 6,
qplot(mtcars$hp, mtcars$cyl) +
labs(x = "hp *hp*",
y = "c\u00DCl *r*(*M*)") +
theme(
axis.title.x = element_markdown(),
axis.title.y = element_markdown()
),
type = "cairo-png")
Created on 2020-07-07 by the reprex package (v0.3.0)

This works for me (though I am not on windows); try leaving out the device parameter:
library(ggplot2)
ggsave("test.png",
qplot(mtcars$hp, mtcars$cyl) +
ylab(expression(`cÜl`~italic(r)(italic(M)))) +
xlab(expression(hp~italic(hp))),
type = "cairo-png")
#> Saving 7 x 5 in image
Created on 2020-07-05 by the reprex package (v0.3.0)

Related

Unicode Ø symbol with superscript in ggplot

I would like to put the following text behind the ggplot chart
And I thought it should be very easy to achieve. Unfortunately, all my attempts ended in a complete failure.
I have already read over a dozen posts on this forum that dealt with this topic. I have already made several dozen attempts and still do not manage to get the effect I expect.
By the way, I noticed a rather strange treatment of unicode symbols. Please compare the title and subtitle from the chart below.
library(tidyverse)
ggplot()+
labs(
title = expression("\u00AE \u00A9, \u00A2, \u00BC, \u00BD, \u00BE, \u00A5, \u00D8, \u00F8"),
subtitle = "\u00AE \u00A9, \u00A2, \u00BC, \u00BD, \u00BE, \u00A5, \u00D8, \u00F8"
)+
annotate(geom="text", label="\u00D828.15^{+0.15}", x=0, y=0.08,parse = TRUE, size=5)+
annotate(geom="text", label="\u00D8", x=0, y=0, size=5)+
annotate(geom="text", label="28.15^{+0.15}", x=0.03, y=0.001,parse = TRUE, size=5)+
xlim(c(-0.1, 0.1))+
ylim(c(-0.02, 0.1))+
theme_void()
Why do some unicode symbols lose some of their graphics when placed inside an expression function or when I use the parse option? This happens with the symbols ¢, ¥, ¼, ½, ¾, Ø. In my case, I particularly care about the symbol Ø. I finally got the effect on the track chart (annotation at the bottom of the chart) was created from the tedious setting of two annotations next to each other. However, it completely falls apart as soon as I change the size of the chart.
Does anyone know how this can be solved?
Thank you very much for your quick reply. Unfortunately, it still doesn't work for me! :-(
library(latex2exp)
library(ggplot2)
label <- TeX("$Ø28.15^{+0.15}$")
qplot(1, "A") +
annotate(geom = "text", label = label, x = 1, y = 1.1, size = 10) +
xlab(label)
You can use LaTeX syntax within a math ($) environment to auto-generate the plotmath expression:
library(latex2exp)
library(ggplot2)
label <- TeX("$Ø28.15^{+0.15}$")
label
#> expression(`$Ø28.15^{+0.15}$` = paste("", "Ø28", ".", "15",
#> phantom()^{
#> paste("+0", ".", "15")
#> }, ""))
qplot(1, "A") +
annotate(geom = "text", label = label, x = 1, y = 1.1, size = 10) +
xlab(label)
#> Warning in is.na(x): is.na() applied to non-(list or vector) of type
#> 'expression'
Created on 2021-10-18 by the reprex package (v2.0.1)
I know how to modify this solution above, maybe not so cute, but works everywhere
library(ggplot2)
label <- "\u00D828.15\U207A\u2070\U00B7\U00B9\u2075"
qplot(1, "A") +
annotate(geom = "text", label = label, x = 1, y = 1.1, size = 10) +
xlab(label)

Saving ggplot with expression and unicode in axis title with cairo

I'd like to save the following plot:
library(ggplot2)
myplot <- ggplot(iris) +
geom_point(aes(x = Sepal.Width, y = Sepal.Length)) +
ylab(expression(~delta^13*C~"[\211]"))
ggsave(myplot,
filename = "myplot.png",
type = "cairo")
But I get the following error:
Error in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
Metric information not available for this family/device
The problem must be the combination of expression and unicode, as those two work:
myplot <- ggplot(iris) +
geom_point(aes(x = Sepal.Width, y = Sepal.Length)) +
ylab("[\211]")
myplot <- ggplot(iris) +
geom_point(aes(x = Sepal.Width, y = Sepal.Length)) +
ylab(expression(~delta^13*C))
How can I solve this problem?
Edit: I'd like to print the "per mille"-symbol. Apparently its unicode is U2030 and I had mistakenly assumed that "\211" would be a unicode, but must be something else.
Edit 2: In the meantime, I found this question with a similar problem. There, a suggestion is to save the plot with encoding = "MacRoman", which unfortuantely does not work for me:
Error in png_dev(..., res = dpi, units = "in") :
unused argument (encoding = "MacRoman")
Edit 3:
> capabilities()["cairo"]
cairo
TRUE
> sessionInfo()
R version 4.0.1 (2020-06-06)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1
Matrix products: default
locale:
[1] LC_COLLATE=German_Germany.1252 LC_CTYPE=German_Germany.1252 LC_MONETARY=German_Germany.1252 LC_NUMERIC=C
[5] LC_TIME=German_Germany.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] patchwork_1.1.1 ggplot2_3.3.5 dplyr_1.0.7
Which unicode symbol are you trying to actually use. I guess it is only your syntax for specifying the unicode symbol that is wrong.
Try this code:
myplot <- ggplot(iris) +
geom_point(aes(x = Sepal.Width, y = Sepal.Length)) +
ylab(expression(~delta^13*C~"\U0211"))
ggsave(myplot,
filename = "myplot.png",
type = "cairo")
This works perfectly for me.
Gives a plot that looks like this:
You use "\U0211". So "\U for specifying you want unicode and then the code.
Look here for the unicode symbols:
https://en.wikipedia.org/wiki/List_of_Unicode_characters
It's the first column you have to input to get the right symbol.
So e.g. for U+020F you write "\U020F"
Update
Here an example with the new information about your unicode symbol
myplot <- ggplot(iris) +
geom_point(aes(x = Sepal.Width, y = Sepal.Length)) +
ylab(expression(~delta^13*C~"\U2030"))
ggsave(myplot,
filename = "myplot.png",
type = "cairo")
Gives me this plot:
Would you mind trying the exact code above? Also try to run without saving - since the saving of the plot actually shouldn't be the issue.
So also try to just run
library("ggplot2")
ggplot(iris) +
geom_point(aes(x = Sepal.Width, y = Sepal.Length)) +
ylab(expression(~delta^13*C~"\U2030"))
There, take a look if the y-axis label is displayed correctly.
If it still does not work:
It might also be, that the font you are using does not contain the unicode char you are trying to use.
Then add the following to your plot code:
ggplot(iris) +
geom_point(aes(x = Sepal.Width, y = Sepal.Length)) +
ylab(expression(~delta^13*C~"\U2030")) +
theme(text=element_text(family="Arial Unicode MS"))
The "Arial Unicode MS" can actually be any font that is available and includes the unicode char in the form that you want it.
Maybe these hints already solve the problem - if not just write another comment, maybe you additionally need some further steps.
Further steps:
Since it still did not work and you mention it seems to be specific to saving with type = cairo try the following:
First provide some more info and check for cairo with this command:
capabilities()["cairo"]
Result should be true.
Then post us some information about your system
sessionInfo()
As these font and plotting things are often dependent on your OS.
Then we make 100% sure, that we have the fonts/unicode symbols available:
library(ggplot2)
install.packages("extrafont")
library("extrafont")
font_import()
loadfonts()
fonts()
The call to fonts() should now gibe output, which fonts are available.
Maybe you can post these infos additionally, that we can give you further steps.
Afterwards you can try again, using extrafonts() alone sometimes already solves the problem:
library("ggplot2")
library("extrafont")
font_import()
loadfonts()
myplot <- ggplot(iris) +
geom_point(aes(x = Sepal.Width, y = Sepal.Length)) +
ylab(expression(~delta^13*C~"\U2030")) +
theme(text=element_text(family="Arial Unicode MS"))
ggsave(myplot,
filename = "myplot.png",
type = "cairo")
As I said capabilities()["cairo"] must have returned true and family="Arial Unicode MS" must be some font that fonts() returned
Also worth trying a different grDevice after getting extrafont ready
library("extrafont")
font_import()
loadfonts()
myplot <- ggplot(iris) +
geom_point(aes(x = Sepal.Width, y = Sepal.Length)) +
ylab(expression(~delta^13*C~"\U2030")) +
theme(text=element_text(family="Arial Unicode MS"))
ggsave(myplot,
filename = "myplot.png",
type = "cairo-png")
There are also more you can try ... here is a very interesting article about saving graphics on different OS. Interestingly depending on your OS and graphic device exported figures look slightly different.
Just read in your comment you want to use Cairo to increase the quality. Try if it works with ragg instead of Cairo - the quality might be even better.
ragg provides a set of high quality and high performance raster
devices, capable of producing png, tiff, or ppm files, or a matrix of
raw color values directly within R.
ragg is part of our broader effort to improve graphics performance and
quality in R at all levels of the stack
library(ragg)
myplot <- ggplot(iris) +
geom_point(aes(x = Sepal.Width, y = Sepal.Length)) +
ylab(expression(~delta^13*C~"\U2030")) +
theme(text=element_text(family="Arial Unicode MS"))
ggsave(
filename = "myplot3.png",
myplot,
device = ragg::agg_png(
width = 3000,
height = 3000,
units = "px",
res = 500)
)
Since you still had now some issues with expression, you can also combine this also with ggtext. Then there is no need for expression.
myplot <- ggplot(iris) +
geom_point(aes(x = Sepal.Width, y = Sepal.Length)) +
ylab("\U03B4<sup>13</sup>C\U2030") +
theme(
axis.title.y = element_markdown(size = 11, lineheight = 1.2)
)
ggsave(
filename = "myplot4.png",
myplot,
device = ragg::agg_png(
width = 3000,
height = 3000,
units = "px",
res = 500)
)
Using the package ggtext basically enables you to do all kind of things with your axis title (bold, multiple colors, different sizes, ... all in one label). See also ggtext manual.
Certain unicodes only work with certain fonts. Here is a list of fonts that work with unicode u2030.
The package emojifont makes it easier to use certain unicodes, by rendering the font/family you need to make it possible to save your file. That way you skip having to find the correct font and installing it in your OS.
library(ggplot2)
install.packages('emojifont')
library(emojifont)
myplot <- ggplot(iris) +
geom_point(aes(x = Sepal.Width, y = Sepal.Length)) +
ylab(expression(~delta^13*C~"[\u2030]"))
myplot
ggsave(my_plot,
filename = "myplot.png",
type = "cairo")
It also works with \u211.

Finding ggsave and save_plot do not seem to work with the ggdraw+draw_grob from the cowplot package?

I cannot seem to save a plot when using ggdraw() + draw_grob(). Saving just 'plot1' alone works fine but once I start using ggdraw it no longer works with either ggsave() or save_plot(), it produces an error noting an invalid canvas value. Example below:
library(ggplot2)
#> Warning: replacing previous import 'vctrs::data_frame' by 'tibble::data_frame'
#> when loading 'dplyr'
library(cowplot)
library(grid)
plot1 <- ggplot(mpg, aes(x = hwy, y = cty)) +
geom_point()
line <- linesGrob(x = unit(c(0,1), "npc"), y = unit(c(0,1), "npc"))
plot_full <- ggdraw(plot1) +
draw_grob(line)
ggsave("plotfull.png", plot_full)
#> Saving 7 x 5 in image
#> Error in grDevices::png(..., res = dpi, units = "in"): invalid value of 'canvas'
save_plot("plotfull.png", plot_full)
#> Error in grDevices::png(..., res = dpi, units = "in"): invalid value of 'canvas'
Created on 2020-09-14 by the reprex package (v0.3.0)

RMarkdown won't knit ggplot2 plot after changing font

The plot below was generated in R (without any issue), using this code:
library(tidyverse)
library(extrafont)
loadfonts()
x <- rexp(100)
data.frame(info = x) %>%
ggplot() +
geom_histogram(aes(x = info), col = "red", fill = "red", alpha = 0.5) +
theme_minimal() +
theme(text = element_text(family="LM Roman 10"))
As you can see, the font of the plot is set to "LM Roman 10", which I was able to do thanks to this post and it works perfectly within R.
However when I try to place the image in a LaTeX document using RMarkdown, I get this error:
Quitting from lines 10-22 (min_example.Rmd)
Error in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
invalid font type
Calls: <Anonymous> ... drawDetails -> drawDetails.text -> grid.Call.graphics
Además: There were 50 or more warnings (use warnings() to see the first 50)
Ejecución interrumpida
Here is the code for min_example.Rmd
---
title: "Untitled"
author: "Javier Rojas"
date: "2/9/2020"
output: pdf_document
---
```{r, echo=FALSE}
library(tidyverse)
library(extrafont)
loadfonts()
x <- rexp(100)
data.frame(info = x) %>%
ggplot() +
geom_histogram(aes(x = info), col = "red", fill = "red", alpha = 0.5) +
theme_minimal() +
theme(text = element_text(family="LM Roman 10"))
```
I am using a Mac computer running macOS High Sierra and R 3.6.1
Usually quite easy to solve. The problem should be, that the font is not installed in your computer.
You have to download the .otf file for the font e.g. (https://fonts2u.com/lmroman10-regular.font) and install it on your Operating System.
If you don't know how to do this, just google it (e.g. "install extra font Windows"), there are plenty of tutorials on it online.
-edit-
I was a little to quick - didn't realize the problem just comes from running it in rmarkdown. Try the following:
```{r, fig.showtext=TRUE, echo=FALSE}
library("tidyverse")
library("showtext")
x <- rexp(100)
font_add("LM Roman 10", regular = "lmroman10-regular.otf")
data.frame(info = x) %>%
ggplot() +
geom_histogram(aes(x = info), col = "red", fill = "red", alpha = 0.5) +
theme_minimal() +
theme(text = element_text(family="LM Roman 10"))
```
It's important that you add fig.showtext=TRUE, library("showtext") and font_add("LM Roman 10", regular = "lmroman10-regular.otf").
I just placed the .otf in my project folder - but I think you can also give it another path.
There exists a current new approach using showtext and showtextdb packages.
On Windows, install manually Latin Modern Roman font (.tff version) following these steps easy instructions https://tex.stackexchange.com/questions/55787/latin-modern-roman-for-ttf. After the installation, you can locate all your fonts in "C:/Windows/Fonts/" just in case.
Once it's already installed, try the following R code to see and example:
install.packages("showtext")
install.packages("showtextdb")
library(showtext)
library(showtextdb)
#set the name and file path
font_add(family = "lmroman10", regular = "C:/Windows/Fonts/lmroman10-regular-webfont.ttf")
showtext_auto()
library(ggplot2)
p = ggplot(NULL, aes(x = 1, y = 1)) + ylim(0.8, 1.2) +
theme(axis.title = element_blank(), axis.ticks = element_blank(),
axis.text = element_blank()) +
annotate("text", 1, 1.1, family = "lmroman10", size = 15,
label = "Text using new font")

ggplot2 doesn't show Chinese character properly in rstudio-server in docker

I try to use ggplot2 to plot a chart with the Chinese title but shows Unicode in a square.
I've tried some following command
quartz(family='STKaiti')
par(family='STKaiti')
plot(1, xlab = "你好", family = "Heiti SC Light")
and use "extrafont" font to load my ubuntu fonts into R
The characters plot shows are still Unicode in a square. I want to show the Chinese word properly.
Still, I have no idea how to call this kind of words. "Unicode in a square" is the best I can describe.
Try the showtext package, which was designed for this.
Sample code:
library(ggplot2)
library(showtext)
showtext_auto()
p = ggplot(NULL, aes(x = 1, y = 1)) + ylim(0.8, 1.2) +
annotate("text", 1, 1, size = 15, label = "你好,世界") +
xlab("坐标轴") +
theme_bw(base_family = "wqy-microhei", base_size = 24)
quartz()
print(p)

Resources