ggplot2绘图左中部添加标题副标题及相关问题咨询
Bob Ross画作主题TidyTuesday挑战迟交作品
我完成了10幅Bob Ross画作的可视化,代码如下:
library(tidyverse) library(showtext) library(showtextdb) library(ggthemes) library(ggtext) library(magick) library(ggimage) library(cropcircles) library(cowplot) library(patchwork) font_add_google("Lora", bold.wt = 700, family = "plottitle") font_add_google("Roboto Slab", family = "title") font_add_google("Ubuntu", family = "caption") font_add('fa-reg', 'fonts/Font Awesome 6 Free-Regular-400.otf') font_add('fa-brands', 'fonts/Font Awesome 6 Brands-Regular-400.otf') font_add('fa-solid', 'fonts/Font Awesome 6 Free-Solid-900.otf') showtext_auto() bob_ross <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2023/2023-02-21/bob_ross.csv') bob_ross_top <- bob_ross %>% mutate(col_num_n = str_count(colors, ",") + 1) %>% arrange(desc(col_num_n)) %>% slice(1:10) %>% mutate(image = map(img_src, image_read), img_circle = circle_crop(img_src, border_size = 12, border_colour = "white"), painting_title = gsub(" ", "<br>", painting_title), painting_title = case_when(painting_title == "Lake<br>in<br>the<br>Valley" ~ "Lake<br>in the<br>Valley", painting_title == "Waterfall<br>in<br>the<br>Woods" ~ "Waterfall<br>in the<br>Woods", .default = as.character(painting_title))) plot <- ggplot() + geom_image(data = bob_ross_top, aes(x = 1, y = 1, image = img_circle), size = 0.8) + scale_x_discrete(expand = c(0, 0)) + scale_y_continuous(expand = c(0, 0)) + labs(caption = "") + theme_void() + facet_wrap(~painting_title, ncol = 4, strip.position = "right") + theme(# axis.text = element_blank(), panel.grid.major.x = element_blank(), panel.grid.major.y = element_blank(), strip.background = element_blank(), strip.text.y.right = element_markdown(hjust = 0, angle = 0, size = 60, family = "title", face = "bold", lineheight = 0.1), panel.spacing.y = unit(1, "cm"), panel.spacing.x = unit(0.5, "cm"), plot.background = element_rect(fill = "cornsilk", color = "cornsilk"), panel.background = element_rect(fill = "cornsilk", color = "cornsilk"), plot.caption = element_markdown(linewidth = 0.02, hjust = 0.5, size = 45, family = "caption")) title_plot <- ggplot() + geom_text(aes(x = 2, y = 25, label = "Bob Ross\nPainting"), size = 60, family = "plottitle", fontface = "bold", color = "black", lineheight = 0.1) + geom_text(aes(x = 0, y = 20, label = "This plot demonstrates\n10 most colorful\npaintings in Bob\nRoss's show."), size = 30, family = "title", color = "black", lineheight = 0.1) + scale_y_continuous(expand = c(0, 12)) + scale_x_continuous(expand = c(0, 12)) + theme_void() + theme(plot.background = element_rect(fill = "cornsilk", color = "cornsilk"), panel.background = element_rect(fill = "cornsilk", color = "cornsilk"), panel.grid.major.x = element_blank(), panel.grid.major.y = element_blank(), # axis.text = element_blank(), axis.ticks = element_blank()) final_plot <- title_plot + plot + plot_layout(widths = c(1, 5)) + theme(plot.background = element_rect(fill = "cornsilk", color = "cornsilk"), panel.background = element_rect(fill = "cornsilk", color = "cornsilk")) ggsave("~/plot.png", dpi = 720, height = 6, width = 12)
生成的可视化效果如图所示:
遇到的技术问题
- 无需新建绘图,能否将标题和副标题放置在绘图左中部,且支持自定义坐标(如标题设为
c(0,0.7)、副标题设为c(0,0.3))? - 若无法实现上述操作,如何让标题居中、副标题左中部对齐(当前在
title_plot中设置不同hjust会导致位置错乱)? - 为何已多次将
panel.background和plot.background设为cornsilk,绘图仍存在白色边框?
问题解答
问题1:自定义坐标放置标题和副标题
可以直接在主绘图plot中使用annotate()函数添加标题和副标题,无需单独创建title_plot。配合coord_cartesian(clip = "off")允许绘图区域外的元素显示,用相对坐标精准控制位置:
plot <- ggplot() + geom_image(data = bob_ross_top, aes(x = 1, y = 1, image = img_circle), size = 0.8) + scale_x_discrete(expand = c(0, 0)) + scale_y_continuous(expand = c(0, 0)) + labs(caption = "") + # 自定义坐标添加标题和副标题 annotate("text", x = -0.5, y = 0.7, label = "Bob Ross\nPainting", size = 60, family = "plottitle", fontface = "bold", color = "black", lineheight = 0.1, hjust = 0) + annotate("text", x = -0.5, y = 0.3, label = "This plot demonstrates\n10 most colorful\npaintings in Bob\nRoss's show.", size = 30, family = "title", color = "black", lineheight = 0.1, hjust = 0) + coord_cartesian(xlim = c(1, 1), ylim = c(1, 1), clip = "off") + theme_void() + facet_wrap(~painting_title, ncol = 4, strip.position = "right") + theme( panel.grid.major.x = element_blank(), panel.grid.major.y = element_blank(), strip.background = element_blank(), strip.text.y.right = element_markdown(hjust = 0, angle = 0, size = 60, family = "title", face = "bold", lineheight = 0.1), panel.spacing.y = unit(1, "cm"), panel.spacing.x = unit(0.5, "cm"), plot.background = element_rect(fill = "cornsilk", color = "cornsilk"), panel.background = element_rect(fill = "cornsilk", color = "cornsilk"), plot.caption = element_markdown(linewidth = 0.02, hjust = 0.5, size = 45, family = "caption"), plot.margin = margin(left = 8, unit = "cm") # 左侧预留标题空间 )
调整x和y的数值即可自定义标题位置,无需额外拼接绘图。
问题2:标题居中、副标题左中部对齐
如果保留title_plot的方式,需固定坐标范围,确保hjust的参考系一致:
title_plot <- ggplot() + geom_text(aes(x = 1, y = 25, label = "Bob Ross\nPainting"), size = 60, family = "plottitle", fontface = "bold", color = "black", lineheight = 0.1, hjust = 0.5) + geom_text(aes(x = 0, y = 20, label = "This plot demonstrates\n10 most colorful\npaintings in Bob\nRoss's show."), size = 30, family = "title", color = "black", lineheight = 0.1, hjust = 0) + scale_y_continuous(limits = c(0, 30), expand = c(0,0)) + scale_x_continuous(limits = c(-0.5, 2.5), expand = c(0,0)) + theme_void() + theme(plot.background = element_rect(fill = "cornsilk", color = "cornsilk"))
通过scale_x_continuous固定x轴范围,避免hjust设置导致位置错乱。
问题3:白色边框问题
白色边框并非来自panel.background或plot.background,而是ggsave()默认输出的画布背景为白色。只需在ggsave()中添加bg = "cornsilk"参数即可解决:
ggsave("~/plot.png", dpi = 720, height = 6, width = 12, bg = "cornsilk")
该参数直接控制输出图片的背景色,消除白色边框。
内容的提问来源于stack exchange,提问作者mzkrc
相关产品推荐
相关产品推荐

