ggtext让ggplot2图像也可以使用html、markdown及css语法,丰富了ggplot2文本的表现力。
在主题部分如坐标轴标题、坐标轴标签、图形标题、副标题、脚注等,可以使用html、markdown及css语法的文本,然后在theme函数中使用element_markdown和element_textbox进行渲染即可。
在panel区域,也就是类似于原生的geom_text或者geom_label的图层所作用的区域,可以使用geom_richtext或者geom_textbox来扩展文本标注的表现力。
element_markdown
element_markdown可以渲染html、markdown及css语法,获得高级的文本表现。
下图中可以看到,y轴标签使用了html的标记和css语法,改变文字为倾斜和不同颜色。脚注基本上是markdown语法,加了一个html换行标签。
代码语言:javascript复制data <- tibble(
bactname = c("Staphylococcaceae", "Moraxella", "Streptococcus", "Acinetobacter"),
OTUname = c("OTU 1", "OTU 2", "OTU 3", "OTU 4"),
value = c(-0.5, 0.5, 2, 3)
)
data %>% mutate(
color = c("#009E73", "#D55E00", "#0072B2", "#000000"),
name = glue("<i style='color:{color}'>{bactname}</i> ({OTUname})"),
name = fct_reorder(name, value)
) %>%
ggplot(aes(value, name, fill = color))
geom_col(alpha = 0.5)
scale_fill_identity()
labs(caption = "Example posted on **stackoverflow.com**<br>(using made-up data)")
theme(
axis.text.y = element_markdown(),
plot.caption = element_markdown(lineheight = 1.2)
)
html的img标签其实也是支持的,但是目前貌似出现了bug,无法出图。正常情况下应该如下图所示:
代码语言:javascript复制labels <- c(
setosa = "<img src='https://upload.wikimedia.org/wikipedia/commons/thumb/8/86/Iris_setosa.JPG/180px-Iris_setosa.JPG'
width='100' /><br>*I. setosa*",
virginica = "<img src='https://upload.wikimedia.org/wikipedia/commons/thumb/3/38/Iris_virginica_-_NRCS.jpg/320px-Iris_virginica_-_NRCS.jpg'
width='100' /><br>*I. virginica*",
versicolor = "<img src='https://upload.wikimedia.org/wikipedia/commons/thumb/2/27/20140427Iris_versicolor1.jpg/320px-20140427Iris_versicolor1.jpg'
width='100' /><br>*I. versicolor*"
)
ggplot(iris, aes(Species, Sepal.Width))
geom_boxplot()
scale_x_discrete(
name = NULL,
labels = labels
)
theme(
axis.text.x = element_markdown(color = "black", size = 11)
)
element_textbox
element_textbox可以让长文本自动折叠,但是它在轴标签上无法使用。文本的旋转角度也不能是任意的,只能是0、90、180、270。
一般情况下不使用element_textbox,而是使用element_textbox_simple,它和element_textbox是一样的,只不过更加容易使用,很多默认参数都已经设置好了。
代码语言:javascript复制ggplot(mtcars, aes(disp, mpg))
geom_point()
labs(
title = "<b>Fuel economy vs. engine displacement</b><br>
<span style = 'font-size:10pt'>Lorem ipsum *dolor sit amet,*
consectetur adipiscing elit, **sed do eiusmod tempor incididunt** ut
labore et dolore magna aliqua. <span style = 'color:red;'>Ut enim
ad minim veniam,</span> quis nostrud exercitation ullamco laboris nisi
ut aliquip ex ea commodo consequat.</span>",
x = "displacement (in<sup>3</sup>)",
y = "Miles per gallon (mpg)<br><span style = 'font-size:8pt'>A measure of
the car's fuel efficiency.</span>"
)
theme(
plot.title.position = "plot",
plot.title = element_textbox_simple(
size = 13,
lineheight = 1,
padding = margin(5.5, 5.5, 5.5, 5.5),
margin = margin(0, 0, 5.5, 0),
fill = "cornsilk"
),
axis.title.x = element_textbox_simple(
width = NULL,
padding = margin(4, 4, 4, 4),
margin = margin(4, 0, 0, 0),
linetype = 1,
r = grid::unit(8, "pt"),
fill = "azure1"
),
axis.title.y = element_textbox_simple(
hjust = 0,
orientation = "left-rotated",
minwidth = unit(1, "in"),
maxwidth = unit(2, "in"),
padding = margin(4, 4, 2, 4),
margin = margin(0, 0, 2, 0),
fill = "lightsteelblue1"
)
)
element_box在使用上非常有意思的一个地方是可以修改分面图的strip格式,如下图所示。
代码语言:javascript复制ggplot(mpg, aes(cty, hwy))
geom_point()
facet_wrap(~class)
cowplot::theme_half_open(12)
cowplot::background_grid()
theme(
strip.background = element_blank(),
strip.text = element_textbox(
size = 12,
color = "white", fill = "#5D729D", box.color = "#4A618C",
halign = 0.5, linetype = 1, r = unit(5, "pt"), width = unit(1, "npc"),
padding = margin(2, 0, 1, 0), margin = margin(3, 3, 3, 3)
)
)
上图是固定的格式显示,strip的格式都是一样的,其实也可以更进一步,将strip按照分组显示,从而实现多一个维度的信息展示,比如此图的stipe文本是class信息(因为这里的分面是facet_wrap(~class)控制的),那么可以将原始的数据的class格式化为一个html的标记,下图就是将strip的字体颜色映射为mpg中的cyl变量,当然了由于class中存在多种cyl信息,因此被拆分成了多个子图,这也是正常情况。如果要和以前一样的子图数量,其实可以按照class的水平值,各自组合一个颜色即可。
代码语言:javascript复制mpg %>% mutate(cyl = fct_recode(factor(cyl),
red = "4",
blue = "5",
yellow = "6",
green = "8")) %>%
mutate(class = str_glue("<span style = 'color:{cyl}'>{class}</span>")) %>%
ggplot(aes(cty, hwy))
geom_point()
facet_wrap(~class)
cowplot::theme_half_open(12)
cowplot::background_grid()
theme(
strip.background = element_blank(),
strip.text = element_textbox(
size = 12,
color = "white", fill = "#5D729D", box.color = "#4A618C",
halign = 0.5, linetype = 1, r = unit(5, "pt"), width = unit(1, "npc"),
padding = margin(2, 0, 1, 0), margin = margin(3, 3, 3, 3)
)
)
geom_richtext
geom_richtext和基础图层geom_text或者geom_label类似,但是扩增了很多格式控制。
代码语言:javascript复制df <- tibble(
label = c(
"Some text **in bold.**",
"Linebreaks<br>Linebreaks<br>Linebreaks",
"*x*<sup>2</sup> 5*x* *C*<sub>*i*</sub>",
"Some <span style='color:blue'>blue text **in bold.**</span><br>And *italics text.*<br>
And some <span style='font-size:18pt; color:black'>large</span> text."
),
x = c(.2, .1, .5, .9),
y = c(.8, .4, .1, .5),
hjust = c(0.5, 0, 0, 1),
vjust = c(0.5, 1, 0, 0.5),
angle = c(0, 0, 45, -45),
color = c("black", "blue", "black", "red"),
fill = c("cornsilk", "white", "lightblue1", "white")
)
ggplot(df)
aes(
x, y, label = label, angle = angle, color = color, fill = fill,
hjust = hjust, vjust = vjust
)
geom_richtext()
geom_point(color = "black", size = 2)
scale_color_identity()
scale_fill_identity()
xlim(0, 1) ylim(0, 1)
geom_textbox
不同于geom_richtext,geom_textbox可以自动折叠文本,也就是说不需要手动换行(br标签)。它和element_textbox类似,也无法旋转任意角度。
代码语言:javascript复制df <- tibble(
label = rep("Lorem ipsum dolor **sit amet,** consectetur adipiscing elit,
sed do *eiusmod tempor incididunt* ut labore et dolore magna
aliqua.", 2),
x = c(0, .6),
y = c(1, .6),
hjust = c(0, 0),
vjust = c(1, 0),
orientation = c("upright", "right-rotated"),
color = c("black", "blue"),
fill = c("cornsilk", "white") )
ggplot(df)
aes(
x, y, label = label, color = color, fill = fill,
hjust = hjust, vjust = vjust,
orientation = orientation
)
geom_textbox(width = unit(0.4, "npc"))
geom_point(color = "black", size = 2)
scale_discrete_identity(aesthetics = c("color", "fill", "orientation"))
xlim(0, 1) ylim(0, 1)