You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)

生成的可视化效果如图所示:
Bob Ross画作可视化

遇到的技术问题

  • 无需新建绘图,能否将标题和副标题放置在绘图左中部,且支持自定义坐标(如标题设为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 04:37:34