如何从论文图表中提取数据重新使用 Stata 或者 R 语言绘图

今天给大家分享一个邪修技能:从论文图表中提取数据重新使用 Stata 或者 R 语言绘图。

经常我们会遇到一个问题,我们想使用参考文献中某个图表的数据,但是作者并不提供数据。这个时候该怎么办呢?

最近为了解决这个问题,我借助豆包编写了一个网页应用:getpicdata,应用的首页是这样的:

其他好用的应用大家也可以先自行探索。

可以使用附件中提供的离线文件访问这个应用。

首次打开加载速度会较慢,耐心等待即可。

该应用不仅可以提取单组 xy 数据,还可以提取多组。

本次课程我们将以两幅图为例演示该应用的使用方法。

单组 xy 图表的提取

对于单组 xy 图表的数据提取,我们以下面这幅图为例:

将该图片上传到我编写的这个应用里面:

第一步要做的事情就是手动在图上选择四个点:xmin,xmax, ymin, ymax, 需要注意,标记点并不需要刻意与点击点重合,只要鼠标点击位置准确即可:

在图上点击之后就会生成标记,标记放置的位置和和鼠标点击点有偏移,这个并不影响;然后就是 ymin 和 xmin 通常是一个位置,拖动标记点让两者重合即可。

然后看页面的左侧,设定四个值:

输入之后点击“确定坐标范围”。

下一步是设定数据组的名字,这个随便写就行,毕竟现在只有一组数据:

点击“添加数据点”。然后在图表上逐个数据点:

再次注意,标记点和鼠标点击点位置是有偏移的,这个并不会有影响,不要拖动让两者一致!

点击“保存当前数据组”就完成这组数据的添加了。

如果手动点击取点的时候有点击错的,也可以在这个表里面删除(保存数据组前,这个表的操作列里面可以点击删除某个点)。

最后就可以点击导出 csv 文件了:

这里我导出的文件名称为 chart_data_2025-09-08.csv。在 Stata 中读取:

cd "~/Desktop/如何从论文图表中提取数据重新使用 Stata 或者 R 语言绘图"
import delimited using "chart_data_2025-09-08.csv", clear
list

*> +-----------------------------+
*> | group x y |
*> |-----------------------------|
*> 1. | group 2005 18.56068 |
*> 2. | group 2006.024 18.26627 |
*> 3. | group 2007.047 18.36441 |
*> 4. | group 2008.038 18.07 |
*> 5. | group 2009.061 18.07 |
*> |-----------------------------|
*> 6. | group 2010.052 17.74289 |
*> 7. | group 2011.042 17.7756 |
*> 8. | group 2012.033 17.97187 |
*> 9. | group 2013.057 17.97187 |
*> 10. | group 2014.047 16.56526 |
*> |-----------------------------|
*> 11. | group 2015.038 15.94374 |
*> 12. | group 2016.061 14.86425 |
*> 13. | group 2017.052 14.56984 |
*> 14. | group 2018.042 14.7334 |
*> 15. | group 2019.066 14.66798 |
*> +-----------------------------+

对这个数据进行简单的处理就可以再重新绘制这幅图了:

replace x = round(x)

tw conn y x, lp(solid) m(o) color(black) msize(small) ///
xla(2005(2)2019) ///
yla(10(2)20) ysc(range(10 20)) ///
xti("图1 我国社会物流总费用占 GDP 比重逐年走势") ///
yti("社会物流总费用占 GDP 比重(%)", bexpand justification(right)) ///
note("注:数据源于历年《中国物流年鉴》。") ///
sch(qlean)

gr export pic11.png, width(4800) replace

是不是几乎一模一样~

使用 R 语言绘制:

# 加载必要的包
library(tidyverse)

# 导入数据
data <- read_csv("chart_data_2025-09-08.csv")

# 数据处理:将 x 变量四舍五入为最接近的整数
data <- data %>%
mutate(x = round(x))

data

# 创建折线图
ggplot(data, aes(x = x, y = y)) +
geom_line(linetype = "solid", color = "black") +
geom_point(shape = 16, size = 2, color = "black") + # m(o) 对应圆点
scale_x_continuous(
breaks = seq(2005, 2019, by = 2), # xla(2005(2)2019)
limits = c(2005, 2019) # 设置 x 轴范围
) +
scale_y_continuous(
breaks = seq(10, 20, by = 2), # yla(10(2)20)
limits = c(10, 20) # ysc(range(10 20))
) +
labs(
x = "图1 我国社会物流总费用占 GDP 比重逐年走势", # xti
y = "社会物流总费用占 GDP 比重(%)", # yti
caption = "注:数据源于历年《中国物流年鉴》。" # note
) +
theme_classic(base_family = cnfont) + # sch(qlean) 的近似主题
theme(
plot.caption = element_text(hjust = 1), # 注释放置在右侧
axis.title.y = element_text(hjust = 1) # y 轴标题右对齐
) -> p1

ggsave("pic11b.png", device = png, width = 8, height = 6)

还可以把数据也标注到图上:

tostring y, gen(label) format(%6.2f) force
replace label = label + "%"
egen pos = fill(12 6 12 6)
tw conn y x, lp(solid) m(o) color(black) msize(small) ///
xla(2005(2)2019) ///
yla(10(2)20) ysc(range(10 20)) ///
mlab(label) mlabvpos(pos) ///
xti("图1 我国社会物流总费用占 GDP 比重逐年走势") ///
yti("社会物流总费用占 GDP 比重(%)", bexpand justification(right)) ///
note("注:数据源于历年《中国物流年鉴》。") ///
sch(qlean)

gr export pic12.png, width(4800) replace

使用 R 语言:

data <- data %>%
mutate(
# 将 y 格式化为保留两位小数的字符串,并添加百分号
label = paste0(format(round(y, 2), nsmall = 2), "%"),
# 创建交替的位置向量 (12 6 12 6...)
pos = rep(c(12, 6), length.out = n())
)

data

ggplot(data, aes(x = x, y = y)) +
geom_line(linetype = "solid", color = "black") +
geom_point(shape = 1, size = 2, color = "black") +
geom_text(
aes(label = label, y = y + ifelse(pos == 12, 0.3, -0.3)), # 根据位置上下调整
size = 3,
color = "black", family = cnfont
) +
scale_x_continuous(
breaks = seq(2005, 2019, by = 2),
limits = c(2005, 2019)
) +
scale_y_continuous(
breaks = seq(10, 20, by = 2),
limits = c(10, 20),
labels = function(x) paste0(x, "%") # 在 y 轴刻度上也添加百分号
) +
labs(
x = "图1 我国社会物流总费用占 GDP 比重逐年走势",
y = "社会物流总费用占 GDP 比重(%)",
caption = "注:数据源于历年《中国物流年鉴》。"
) +
theme_classic(base_family = cnfont) +
theme(
plot.caption = element_text(hjust = 1),
axis.title.y = element_text(hjust = 1)
) -> p2

ggsave("pic12b.png", device = png, width = 8, height = 6)

多组 xy 图表的提取

下面我们再来看下多组 xy 图表数据的提取,这个更为实用,例如下面这个回归系数 + 置信区间的图:

同样的步骤、上传图表、设置四至范围、添加第一组数据:

然后输入第二组数据的名字:ymin,点击取点:

第三组 ymax:

导出数据:chart_data_2025-09-08 (1).csv

然后就可以使用 Stata 绘制这个图表了:

*- 此处代码需下载讲义材料查看~

再使用 R 语言:

# 导入数据
data <- read_csv("chart_data_2025-09-08 (1).csv")
data

# 数据处理
data <- data %>%
mutate(x = round(x)) %>%
group_by(group, x) %>%
mutate(id = row_number()) %>%
ungroup() %>%
pivot_wider(
names_from = group,
values_from = y,
values_fill = NA
) %>%
select(-id) %>%
mutate(
ymax = ifelse(x == -1, beta, ymax),
ymin = ifelse(x == -1, beta, ymin)
)

# 创建图形
# 此处代码需下载讲义材料查看~

关于该应用的更多用法,大家还可以继续深入探索

点击这里跳转到 RStata 短书平台获取附件:如何从论文图表中提取数据重新使用 Stata 或者 R 语言绘图

评论