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

如何在ggplot绘图区域的固定位置放置条形图标签

解决方案

要让标签固定在绘图区域的指定位置,核心是将标签与数据的条形位置解绑,使用固定坐标值,同时确保每个动画帧加载对应年份的标签内容。具体实现步骤如下:

1. 提取目标标签的单独数据集

从原始数据中筛选出需要添加标签的Ford数据,整理成仅包含年份和对应数值的精简数据集:

ford_labels <- data_bar %>%
  filter(firm == "ford") %>%
  select(year, value) %>%
  mutate(label = round(value, 2))

2. 修改绘图代码,固定标签位置

在ggplot中,使用geom_text并指定固定的x、y坐标,同时通过inherit.aes = FALSE避免继承主图层的映射关系,确保位置不随条形变化。以下是完整修改后的代码:

library(ggimage)
library(janitor)
library(gganimate)
library(ggplot2)
library(tidyverse)
library(transformr)
library(ggforce)
theme_set(theme_classic())

# 原始数据(保持不变)
data_bar <- structure(list(firm = c("audi", "ford", "mercedes", "toyota", 
"audi", "ford", "mercedes", "toyota", "audi", "ford", "mercedes", 
"toyota", "audi", "ford", "mercedes", "toyota", "audi", "ford", 
"mercedes", "toyota", "audi", "ford", "mercedes", "toyota", "audi", 
"ford", "mercedes", "toyota", "audi", "ford", "mercedes", "toyota", 
"audi", "ford", "mercedes", "toyota", "audi", "ford", "mercedes", 
"toyota", "audi", "ford", "mercedes", "toyota"), year = c(1945, 
1945, 1945, 1945, 1946, 1946, 1946, 1946, 1947, 1947, 1947, 1947, 
1948, 1948, 1948, 1948, 1949, 1949, 1949, 1949, 1950, 1950, 1950, 
1950, 1951, 1951, 1951, 1951, 1952, 1952, 1952, 1952, 1953, 1953, 
1953, 1953, 1954, 1954, 1954, 1954, 1955, 1955, 1955, 1955), 
    value = c(1156L, 2750L, 48436L, NA, 1170L, 3118L, 48653L, 
    NA, 1189L, 3453L, 47990L, NA, 1240L, 4406L, 49284L, NA, 1245L, 
    5249L, 51490L, NA, 1156L, 5907L, 48436L, 2007L, 1170L, 6311L, 
    48653L, 2042L, 1189L, 6323L, 47990L, 2077L, 1240L, 6594L, 
    49284L, 2110L, 1245L, 7261L, 51490L, 2146L, 1246L, 8054L, 
    49632L, 2179L), rank = c(3, 2, 1, 4, 3, 2, 1, 4, 3, 2, 1, 
    4, 3, 2, 1, 4, 3, 2, 1, 4, 4, 2, 1, 3, 4, 2, 1, 3, 4, 2, 
    1, 3, 4, 2, 1, 3, 4, 2, 1, 3, 4, 2, 1, 3), Value_rel = c(0.0238665455446362, 
    0.0567759517714097, 1, NA, 0.0240478490535013, 0.0640864900417241, 
    1, NA, 0.0247759949989581, 0.0719524901021046, 1, NA, 0.0251602954305657, 
    0.0894002110218326, 1, NA, 0.024179452320839, 0.101942124684405, 
    1, NA, 0.0238665455446362, 0.121954744404988, 1, 0.041436121892807, 
    0.0240478490535013, 0.129714508868929, 1, 0.0419706903993587, 
    0.0247759949989581, 0.131756615961659, 1, 0.0432798499687435, 
    0.0251602954305657, 0.133795958120282, 1, 0.0428130833536239, 
    0.024179452320839, 0.141017673334628, 1, 0.0416779957273257, 
    0.0251047711154094, 0.162274339136041, 1, 0.0439031270148291
    ), Value_lbl = c(" 0", " 0", " 0", " NA", " 0", " 0", " 0", 
    " NA", " 0", " 0", " 0", " NA", " 0", " 0", " 0", " NA", 
    " 0", " 0", " 0", " NA", " 0", " 0", " 0", " 0", " 0", " 0", 
    " 0", " 0", " 0", " 0", " 0", " 0", " 0", " 0", " 0", " 0", 
    " 0", " 0", " 0", " 0", " 0", " 0", " 0", " 0")), row.names = c(NA, 
-44L), class = c("tbl_df", "tbl", "data.frame"))

# 提取Ford的标签数据
ford_labels <- data_bar %>%
  filter(firm == "ford") %>%
  select(year, value) %>%
  mutate(label = round(value, 2))

staticplot = ggplot(data_bar, aes(rank, group = firm, 
                                  fill = if_else(firm == "ford", "darkblue", "darkred"), 
                                  color = if_else(firm == "ford", "darkblue", "darkred"))) +
  geom_tile(aes(y = value/2, height = value, width = 0.9), alpha = 0.8, color = NA) +
  # 固定位置的标签:x设为数据最大值的90%(右侧),y设为rank=4(最下方)
  geom_text(data = ford_labels, 
            aes(x = max(data_bar$value, na.rm = TRUE)*0.9, y = 4, label = label),
            size = 20, color = "red", inherit.aes = FALSE) +
  coord_flip(clip = "off", expand = FALSE) +
  scale_y_continuous(labels = scales::comma) +
  scale_x_reverse() +
  # 使用identity比例尺直接映射颜色字符串
  scale_fill_identity() +
  scale_color_identity() +
  guides(color = "none", fill = "none") +
  theme(axis.line=element_blank(),
        axis.text.x=element_text(size = 28),
        axis.text.y=element_blank(),
        axis.ticks=element_blank(),
        axis.title.x=element_blank(),
        axis.title.y=element_blank(),
        legend.position="none",
        panel.background=element_blank(),
        panel.border=element_blank(),
        panel.grid.major=element_blank(),
        panel.grid.minor=element_blank(),
        panel.grid.major.x = element_line( size=.1, color="black" ),
        panel.grid.minor.x = element_line( size=.1, color="black" ),
        plot.title=element_blank(),
        plot.subtitle=element_blank(),
        plot.caption =element_blank(),
        plot.background=element_blank(),
        plot.tag = element_text(size=102, face="italic", color="red"),
        plot.tag.position = c(0.893,0.2),
        plot.margin = margin(2,2, 2, 4, "cm"))

anim = staticplot + transition_states(year, transition_length = 1, state_length = 1, wrap = FALSE)

animate(anim, 200, fps = 10, duration = 30, width = 1600, height = 900,
        renderer = ffmpeg_renderer()) -> for_mp4

anim_save("firm position by year.mp4", animation = for_mp4)

关键说明

  • 固定坐标设置:x = max(data_bar$value, na.rm = TRUE)*0.9确保标签始终在数值轴的右侧(90%最大数值位置),y = 4对应rank的最下方位置(因scale_x_reverse()反转了rank轴,coord_flip后成为y轴的最底部)。
  • inherit.aes = FALSE:避免继承主图层的rank和group映射,确保标签位置不受数据变化影响。
  • 单独标签数据集:保证每个动画帧加载对应年份的Ford数值,实现内容动态更新但位置固定。

内容的提问来源于stack exchange,提问作者Marlom

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 11:36:16