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

如何解决R Markdown文档中图表编号重复为Figure 1的问题

图表编号重复问题的解决方案

问题根源

你遇到的所有图表都显示为「Figure 1」,核心原因是混合使用了R代码块生成图和LaTeX原生figure环境,两者的编号计数器不互通:

  • R代码块生成的图由knitr自动管理编号,但你手动在fig.cap里加\label会干扰自动编号逻辑;
  • 直接用LaTeX的figure环境时,它使用的是LaTeX原生计数器,和knitr维护的计数器完全独立,导致编号重复。

修复方案

方案1:统一用knitr管理所有图表(推荐)

把TikZ代码也放到R代码块中,让knitr统一处理编号、标题和交叉引用,彻底避免计数器冲突。

修改后的完整代码:

---
title: "demo" 
author: 
output: 
  pdf_document:
    number_sections: true
keep_tex: yes
fontsize: 12pt
linestretch: 1.2
subparagraph: true
geometry: margin=1in
header-includes:
- \usepackage{amsmath}
- \usepackage{amsthm}
- \usepackage{bbm}
- \numberwithin{equation}{section}
- \usepackage{makecell}
- \usepackage{indentfirst}
- \usepackage{geometry}
- \usepackage{graphicx}
- \usepackage{tikz}
- \usepackage{cleveref}  # 直接加载,不要用AtEndPreamble包裹
---

```{r fig.align="center", fig.cap="Trends", label="figure4", warning=FALSE, echo=FALSE, message=FALSE}
library(ggplot2)
    
options(scipen=999)  # 关闭科学计数法
theme_set(theme_bw())
data("midwest", package = "ggplot2")
gg <- ggplot(midwest, aes(x=area, y=poptotal)) + 
  geom_point(aes(col=state, size=popdensity)) + 
  geom_smooth(method="loess", se=F) + 
  xlim(c(0, 0.1)) + 
  ylim(c(0, 500000)) + 
  labs(subtitle="Area Vs Population", 
       y="Population", 
       x="Area", 
       title="Scatterplot", 
       caption = "Source: midwest")

print(gg)  # ggplot推荐用print输出,替代plot
library(datasets)
data("AirPassengers")
passengers <- AirPassengers
plot(passengers)
knitr::asis_output('
\\tikzset{every picture/.style={line width=0.75pt}}        
\\begin{tikzpicture}[x=0.75pt,y=0.75pt,yscale=-1,xscale=1]
\\draw  [fill={rgb, 255:red, 0; green, 0; blue, 0 }  ,fill opacity=0.32 ] (66.5,28.97) -- (248.5,28.97) -- (248.5,137) -- (66.5,137) -- cycle ;
\\draw  [fill={rgb, 255:red, 0; green, 0; blue, 0 }  ,fill opacity=0.25 ] (62.5,265.61) -- (250.25,265.61) -- (250.25,356.79) -- (62.5,356.79) -- cycle ; 
\\end{tikzpicture}
')
knitr::asis_output('
\\tikzset{every picture/.style={line width=0.75pt}} 
\\begin{tikzpicture}[x=0.75pt,y=0.75pt,yscale=-1,xscale=1]
\\draw  [fill={rgb, 255:red, 0; green, 0; blue, 0 }  ,fill opacity=0.32 ] (66.5,28.97) -- (248.5,28.97) -- (248.5,137) -- (66.5,137) -- cycle ;
\\draw  [fill={rgb, 255:red, 0; green, 0; blue, 0 }  ,fill opacity=0.25 ] (62.5,265.61) -- (250.25,265.61) -- (250.25,356.79) -- (62.5,356.79) -- cycle ;
\\end{tikzpicture}
')

查看 \cref{fig:figure1}, \cref{fig:figure2}, \cref{fig:figure3} 和 \cref{fig:figure4}.

#### 关键修改说明:
- 移除`fig.cap`里手动添加的`\label`,改用R代码块的`label`参数指定标签,knitr会自动生成正确的编号和交叉引用标记;
- 用`knitr::asis_output()`把TikZ代码嵌入R代码块,让knitr统一处理图表环境;
- 把`cleveref`从`\AtEndPreamble`中移出,直接加载,避免和knitr的自动编号逻辑冲突;
- ggplot图改用`print(gg)`输出,确保符合ggplot的输出规范。

---

### 方案2:同步LaTeX与knitr的计数器
如果坚持使用LaTeX原生`figure`环境,可通过修改LaTeX计数器实现编号统一:

在YAML的`header-includes`中添加以下代码,让LaTeX的`figure`计数器复用knitr的`plot`计数器:
```latex
- \makeatletter
- \let\c@figure\c@plot
- \makeatother

同时修改所有R代码块的fig.cap,删除手动添加的\label,改用label参数指定标签(同方案1的R代码块写法)。


验证效果

编译后所有图表会按出现顺序依次编号为Figure 1到Figure 4,交叉引用也能正确指向对应图表。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 08:15:09