I'd like to use Unicode shapes in ggplot2 geom_point() (specifically, arrows like ↘, Unicode "\u2198", or LaTeX \searrow), as in shape = "\u2198", that are not in the default font. In this unanswered post, #Laserhedvig commented "it seems that the problem lies in the font. Apparently, the base default fonts don't contain support for these specific glyphs. Now, how to change the font for the shape argument of geom_point()?"
This solution for Unicode in axes.text uses theme(axis.text.x = element_text(family = "FreeSerif")), and this solution uses theme(text=element_text(size=16, family="Comic Sans MS")) for all text, but how can I do this for shape?
Is there a general solution to use Unicode for shape? (must I somehow use cairo and/or a font family argument?)
If not, is there some other set of arrow shapes? (My search for arrow shapes and glyphs, including in the scale_shape documentation came up empty.)
In my case, I need a ggplot2 layer showing qualitative predictions for the direction of change at points in time across discrete categories.
An example:
library(dplyr)
library(ggplot2)
d <- tibble(year = c(1, 1, 2, 2),
policy = rep( c('policy 1', 'policy 2'), 2),
prediction = c(NA, 'increase', 'decrease', NA),
predictionUnicode = c(NA, '\u2197', '\u2198', NA))
ggplot(d) +
geom_point(aes(x = year, y = policy, color = prediction), shape = "\u2198")
shape = "\u2198" (i.e. "↘") does not work
Edit: Thanks to djangodude's comment about ggplot's font usage, I found the family argument of geom_text, which allows different fonts. Thus, Unicode "shapes" can be plotted as characters with geom_text. However, the legend for geom_text is fixed to "a". And themes only control non-data display, so the base_family argument will not work for shape.
ggplot(d) +
geom_tile( aes(x = year, y = policy), color = "black", fill = "white") +
# geom_point does not allow new fonts?
geom_point(aes(x = year, y = policy,
color = prediction), shape = "\u2198") +
# geom_text does allow new fonts, but the legend text is fixed to "a"
geom_text(aes(x = year, y= policy,
color = prediction,
label = predictionUnicode),
family = "Calibri") +
scale_x_continuous(breaks = c(1,2)) +
theme_gray(base_family = "Calibri")
geom_text plots unicode, but not in the legend
It seems the shape argument is really the correct way to do this, right?
I tried setting Sys.setenv(LANG = "en_US.UTF-8") and Sys.setenv(LANG = "Unicode") to no effect, but perhaps some global language setting would affect shape?
Thank you so much for any help!
Note: These solutions for Unicode skull and crossbones and half-filled points do not have legends and will not work without the right font:
To get the right font:
Look for an installed font that contains the Unicode character you seek. I found these instructions helpful.
Import installed fonts into R
library(extrafont)
font_import()
fonts()
sessionInfo()
R version 3.5.2 (2018-12-20)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS Mojave 10.14.3
Use shape="\u2198" instead of \u8600. When specifying a character with \u notation, the value needs to be hexadecimal. 8600 is the decimal value for Unicode character LOWER RIGHT ARROW; the hex value is 2198.
Related
I'm performing a plot of a raster in R, and I need all of the text and the number on a graph to have the same font and font size. The font should be Times New Roman (serif family) and its size should be 12. The code I'm using is:
GHI <- rasterFromXYZ(Solar_Potential)
cuts <- c(1300,1325,1350,1375,1400,1425,1450,1475,1500,1525,1550,1575,1600)
pal <- colorRampPalette(c("yellow","red"))
plot(GHI,breaks = cuts,col = pal(13),
xlab = "Longitude",ylab = "Latitude",family = "serif")
title("Global horizontal irradiation",family = "serif")
however, the color bar on the right stays on the default font, and the title is bold and has much larger letters in comparison with the rest of the graph. Could anyone help me with this?
This might be difficult to achieve with the default plot function from raster, which does not appear to allow changes of the font family of the legend.
You could use ggplot2 to achieve that, using something like this (since you do not provide GHI you might have to adjust things):
library(ggplot2)
ggplot() +
geom_tile(data=as.data.frame(rasterToPoints(GHI)), aes(x=x, y=y, fill=layer)) +
scale_fill_gradientn(colours=pal(13), breaks=seq(1300, 1600, length.out=13)) +
theme_classic(base_size=12, base_family="serif") +
theme(panel.border=element_rect(fill=NA, size=1),
plot.title=element_text(hjust=0.5, size=12),
axis.text=element_text(size=12)) +
labs(x="Longitude", y="Latitude", title="Global horizontal irradiation")
Edit:
I was wrong; the font family can be passed globally, but the font size depends on the graphics device, I believe, hence with ggplot2 it might still be easier to get your target font size.
To get the same sizes with plot, you could try:
par(family="serif")
plot(GHI, breaks = cuts, col = pal(13),
xlab = "Longitude", ylab = "Latitude", cex.lab=1)
title("Global horizontal irradiation", font.main = 1, cex.main=1)
I'm trying to make a simple plot in R using ggplot2. The data is stored in a dataframe with its column written in Russian. The problem is that the contents of the label is shifted from the right border of the latter. These extra spaces appeared whether the label names are defined explicitly (the code below) or implicitly from the dataframe column names.
ggplot(mtcars, aes(x = drat, y =mpg, color = cyl))+
geom_point() +
labs(color = "Русское название") +
theme(legend.background = element_rect(color = "black", linetype = "solid", size = 0.7),
legend.justification = c(1, 1),
legend.position = c(1, 1),
legend.title.align = 0)
The plot with the English title is depicted appropriately.
The encoding of the operational system is set as follows:
"LC_COLLATE=Russian_Russia.1251;LC_CTYPE=Russian_Russia.1251;LC_MONETARY=Russian_Russia.1251;LC_NUMERIC=C;LC_TIME=Russian_Russia.1251"
Is there a way to cope this problem?
I have faced the same issue when needed legend with cyrillic symbols. Looks like it is known issue reported in ggplot2 repo because of the default graphic device on Windows. Actually, if you would try to save your ggplot with ggsave, probably you won't get that issue.
I have not tried to save files by myself yet, but I have followed the reported issue and found some workaround specific for R studio here and it has worked for me, maybe it can solve your issue too. Sample code to run before plotting anything is:
trace(grDevices:::png, quote({
if (missing(type) && missing(antialias)) {
type <- "cairo-png"
antialias <- "subpixel"
}
}), print = FALSE)
I'd like to use unicode characters as the shape of plots in ggplot, but for unknown reason they're not rendering. I did find a similar query here, but I can't make the example there work either.
Any clues as to why?
Note that I don't want to use the unicode character as a "palette", I want each item plotted by geom_point() to be the same shape (color will indicate the relevant variable).
Running
Sys.setenv(LANG = "en_US.UTF-8")
and restarting R does not help. Wrapping the unicode in sprintf() also does not help.
This is an example bit of code that illustrates the problem:
library(tidyverse)
library(ggplot2)
library(Unicode)
p1 = ggplot(mtcars, aes(wt, mpg)) +
geom_point(shape="\u25D2", colour="red", size=3) +
geom_point(shape="\u25D3", colour="blue", size=3) +
theme_bw()
plot(p1)
And here's what that renders result.
I use macOS Sierra (10.13.6), R version 3.5.1 & Rstudio 1.0.143.
Grateful for any help! I've been scouting several forums looking for a solution and posted to #Rstats, so far nothing has worked. It may be that the solution is hidden in some thread somewhere, but if so I have failed to detect it and I suspect others have also missed it. So, here I am making my first ever post to stack overflow :)
Might it work to use geom_text instead? It allows control of the font, so you can select one with the glyph you need.
library(tidyverse)
ggplot(mtcars, aes(wt, mpg)) +
geom_text(label = "\u25D2", aes(color = as.character(gear)),
size=10, family = "Arial Unicode MS") +
geom_text(label = "\u25D3", colour="blue",
size=10, family = "Arial Unicode MS") +
scale_color_discrete(name = "gear") +
theme_bw()
It's possible to change the font family using par. The problem is that this will affect base R graphics but not ggplot2 graphics, as they use two different graphics devices (grDevices vs. grid). For instance, we can try to plot your example using base R functions, but at first we see the same issue:
plot(mtcars$wt, mtcars$mpg, pch="\u25D2", col = "red", cex = 2)
points(mtcars$wt, mtcars$mpg, pch="\u25D3", col = "blue", cex = 2)
We can get what we want if we call par first (the font should support the symbols):
par(family = "Arial Unicode MS")
plot(mtcars$wt, mtcars$mpg, pch="\u25D2", col = "red", cex = 2)
points(mtcars$wt, mtcars$mpg, pch="\u25D3", col = "blue", cex = 2)
Changing the font family parameter that specifically affects the points in a ggplot geom_point appears to be a bit more complicated. As far as I can tell, it would involve turning the ggplot object into a grob, editing the parameters, and then drawing it. It probably makes more sense to either use Jon Spring's geom_text solution, or use base R.
I have been using filled symbols in ggplot2 and never had any problems exporting to png. However, when I export to svg, for some shapes (triangles and diamonds) one side of the symbol has no stroke.
This initially occurred when I was plotting some maps, so I have tried to replicate the issue with just simple example plots - it's still happening. I can't fathom what is causing one side of the symbols to disappear like this. Is this something I am failing to specify when exporting as svg? Or is there a bug somewhere? Any help would be much appreciated.
Here's an example:
And the code that created this image:
library(tidyverse)
plot =
data_frame(x = 1:5, y = 1:5, group = c("tri", "sq", "tri", "sq", "dia")) %>%
ggplot(aes(x,y, shape = group)) +
geom_point(fill = "red", colour = "black", size = 4) +
scale_shape_manual(values = c(23,22,24)) +
theme_bw()
plot %>% ggsave("test.svg", ., height = 10, width = 10, units = "cm")
Note: I have tried using svglite() directly to export - same thing happens.
This seems like a bug in svglite:
Missing edges in svg file for some point characters when background color is set
First reported on ggplot2 github:
ggsave missing edges with some shapes in svg format
This is a simple question.
I am trying to write a legend with text in small caps in R.
I can write the plot using tikzDevice and manually change the plot to small-caps in LaTex, but I want to know if it's possible in R itself?
Thanks.
This is the R code I am using so far:
legend("bottomright", inset=.05, c(expression(Delta*ZRT1), expression(Delta*ZRT2)), lty=1:2, pch=1:2)
This is the LaTex expression I am trying to get into the R legend:
\Delta Z\textsc{rt\oldstylenums{1}}
The Unicode standard does define a number of "small capital" characters in the IPA extensions.
E.g., using this Smallcaps Generator: http://fsymbols.com/generators/smallcaps/
plot(1L:10, main="Aʙᴄᴅᴇғɢʜɪᴊᴋʟᴍɴᴏᴘǫʀsᴛᴜᴠᴡxʏᴢ")
legend("bottomright", expression(\Delta Zʀᴛ1")
As of Unicode 5.1, the only characters missing to allow representation of the full Latin alphabet in small capital Unicode characters are small capital versions of Q and X.
See also here: http://en.wikipedia.org/wiki/Small_caps#Unicode
The small caps generated by Smallcaps Generator do not work for all fonts. For example, the Linux Libertine family (Libertine, Biolinum) have their small caps and Old Style numbers in the Unicode Private Use Area (E000-F8FF), as shown here (last page).
The example plots below use axis labels assembled from the small caps generator, plus the small_caps and small_nums string, assembled from the private use area. The first plot uses Times New Roman, which works with the generated small caps but does not have corresponding glyphs in the private use area. The second plot uses Linux Libertine O, which does not have all Unicode characters from the IPA extensions.
library(ggplot2)
x <- 1L:10
y <- 1L:10
df <- data.frame(x,y)
# assemble strings from Libertine's private use area.
small_caps <- "S\UE05D\UE051\UE05C\UE05C C\UE051\UE060\UE063"
small_nums <- "\UE020\UE021\UE022\UE023\UE024\UE025\UE026\UE027\UE028\UE029"
font <- "Times New Roman"
ggplot(df) +
geom_point(aes(x = x, y = y)) +
labs(x = paste("Sᴍᴀʟʟ Cᴀᴘs /", small_caps),
y = paste("Oʟᴅ Sᴛʏʟᴇ", small_nums)) +
theme(text = element_text(family = font)) +
annotate("text", x = 2, y = 9, label = font)
font <- "Linux Libertine O"
ggplot(df) +
geom_point(aes(x = x, y = y)) +
labs(x = paste("Sᴍᴀʟʟ Cᴀᴘs /", small_caps),
y = paste("Oʟᴅ Sᴛʏʟᴇ", small_nums)) +
theme(text = element_text(family = font)) +
annotate("text", x = 2, y = 9, label = font)
Created on 2018-12-08 by the reprex package (v0.2.1)