本周,Kaggle Hidden Gems大赛与奇妙的TidyTuesday项目进行了一次特别的交叉活动,以进一步加强R和Kaggle社区之间的联系。TidyTuesday的参赛者被邀请在Kaggle平台上将他们精心制作的数据可视化扩展为叙述性笔记本,并获得反馈和奖品。这篇文章将简要介绍我的目标和这次合作的动机,然后展示我自己的一个视觉作品的代码,在那里我学会了如何在ggplot2柱状图中包含图片。
@R4DS社区欢迎你参加第17周的#TidyTuesday!我们正在探索由@heads0rtai1s提供的Kaggle隐藏宝石!!
📂t.co/sElb4fcv3u
🗞t.co/OVy4t58mvO#…](twitter.com/hashtag/r4d…) #Tidyverse #rstats #dataviz pic.twitter.com/MP85A6im6h- 汤姆-莫克(@thomas_mock)2022年4月25日
一个TidyTuesday的交叉情节
TidyTuesday系列是由Tom Mock和R4DS在线学习社区组织的一个长期项目,主要在Twitter上运行。每周都有一个新的数据集,处于不同的整洁状态,而挑战是如何处理、探索和可视化这些数据。每周参与者都会以其创造性的解决方案让人感到高兴和惊讶。
TidyTuesday的目标与我在Kaggle Hidden Gems比赛中的目标有很大的重叠,我在上周的文章中写到了这一点。对我来说,可视化是有效的数据科学交流的核心。现在,Hidden Gems挑战赛的笔记本格式提供了一个机会,可以将这些视觉效果嵌入到一个引人入胜、易于理解的故事中。
我已经通过Twitter上的#TidyTuesday 和#Rstats 标签看到了许多优秀的视觉效果,我计划在未来的文章中收集其中的大部分或全部内容。
练习新的想法。柱状图中的图像
像TidyTuesday这样的活动或这个跨界项目的一个主要动机是让参与者有机会练习他们的数据和数据分析技能,并学习和展示新的工具和想法。当我为Hidden Gems数据写入门笔记本时,我做了类似的事情,决定挑战自己,学习如何在图中包含(png)图片。
在这里,我将对其中的一个图进行分解,它使用自成一体的kaggle_hidden_gems.csv 数据集来研究Hidden Gems作者资料中的社交媒体链接的频率。
首先,我们得到我们所需的库。
libs <- c('dplyr', 'tibble', # wrangling
'tidyr', 'stringr', # wrangling
'tidytuesdayR', # tidytuesday
'gt', # tables
'grid', 'magick', # images, plots
'ggthemes', 'ggplot2') # plots
invisible(lapply(libs, library, character.only = TRUE))
数据集本身在Kaggle上是公开的,通过TidyTuesday的交叉,现在也可以像这样通过tidytuesdayR包访问。
tuesdata <- tidytuesdayR::tt_load('2022-04-26')
##
## Downloading file 1 of 1: `hidden_gems.csv`
gems <- tuesdata$hidden_gems
对数据集及其特征的详细探索当然是Hidden Gems竞赛和TidyTuesday挑战的目标,所以在这里我只关注这个狭隘的问题:Hidden Gems作者中,在他们的简历中拥有Twitter链接与LinkedIn链接的比例是多少?
在这里,我们对包含社交链接的功能author_twitter 和author_linkedin 。我们将这些列重新格式化一下,并将它们透视为一个长表。这样我们就可以按照社交media 平台进行分组,并提取在其简介中显示这些链接的作者的比例。请注意,这段代码比我最初为入门笔记本写的更优雅。
foo <- gems %>%
distinct(author_twitter, author_linkedin) %>%
pivot_longer(everything(), names_to = "media", values_to = "links") %>%
mutate(media = str_to_title(str_replace(media, "author_", ""))) %>%
group_by(media) %>%
summarise(total = n(),
ct = sum(!is.na(links)),
frac = mean(!is.na(links)))
foo %>%
gt()
| 媒体 | 总数 | ct | frac |
|---|---|---|---|
| 188 | 171 | 0.9095745 | |
| 推特 | 188 | 91 | 0.4840426 |
我们看到,总共有188位不同的作者,91%的人显示了他们的LinkedIn,但只有48%的人显示了他们的Twitter。这是一个明显的差异,它提供了有趣的见解,让我们了解Kaggle的资料在更广泛的社会环境中是如何被使用和感知的。
我们可以把它变成一个简单的柱状图并在此完成,但我们的目标是练习使用图像。我们将使用各自平台的标识,为了方便起见,我已经下载并在Hidden Gems数据集中提供了这些标识。
我们将制作一个包含图片路径的小帮助表。
path_img <- "/pics/"
img_d <- tibble(
media = c("Linkedin", "Twitter"),
img = str_c(path_img, c("linkedIn_logo.png", "twitter_logo_v2.png"))
)
img_d %>%
gt()
| 媒体 | img |
|---|---|
| 链接 | /pics/linkedIn_logo.png |
| 推特 | /pics/twitter_logo_v2.png |
这是在一个单元格中的绘图本身。
p <- foo %>%
ggplot(aes(media, frac)) +
geom_col(fill = "white") +
scale_y_continuous(labels = scales::percent, breaks = seq(0, 1, 0.1)) +
theme_hc() +
theme(legend.position = "none") +
labs(x = "", y = "", title = "Percentage of Authors with Social Media on their Profile")
p_dat <- ggplot_build(p)
p_map <- p_dat$data[[1]] %>%
select(xmin, xmax, ymin, ymax) %>%
bind_cols(foo %>% select(media)) %>%
left_join(img_d, by = "media")
for (i in seq(nrow(p_map))){
p <- p +
annotation_custom(
grid::rasterGrob(image_read(p_map$img[i]),
width = unit(1, "npc"),
height = unit(1, "npc")),
xmin = p_map$xmin[i],
xmax = p_map$xmax[i],
ymin = p_map$ymin[i],
ymax = p_map$ymax[i])
}
p
你可以看到,标志现在就像图中的条形一样,并被缩放为条形的高度。这样的效果很容易让人得意忘形,但我认为只有几张图片和一种简洁的风格,该图仍然保持可读性和信息性。
好了,现在让我们把它分解一下。
我们首先用正常的方法建立条形图,geom_col 。条形图的背景是白色的,但我们也可以把它们变成完全透明的。我们用百分比格式化Y轴,添加一个漂亮的主题和一个标题来设置我们的画布。
p <- foo %>%
ggplot(aes(media, frac)) +
geom_col(fill = "white") +
scale_y_continuous(labels = scales::percent, breaks = seq(0, 1, 0.1)) +
theme_hc() +
theme(legend.position = "none") +
labs(x = "", y = "", title = "Percentage of Authors with Social Media on their Profile")
p
你看,情节风格已经在那里了,我们只需要填入图像。我们首先通过ggplot_build ,将上面的绘图对象解构为一组可用于渲染图形的组件,从而实现这一目标。
p_dat <- ggplot_build(p)
结果是一个有三个条目的列表:data (条形图),layout (绘图设置),以及plot (渲染的结果)。我不打算在这里展示所有的内容,但是你可以很容易地打印和检查它。为了我们的目的,我们将采取data 条目并添加我们的图像链接。
p_map <- p_dat$data[[1]] %>%
select(xmin, xmax, ymin, ymax) %>%
bind_cols(foo %>% select(media)) %>%
left_join(img_d, by = "media")
p_map %>%
gt()
| xmin | xmax | ymin | ymax | 媒体 | 图像 |
|---|---|---|---|---|---|
| 0.55 | 1.45 | 0 | 0.9095745 | 链接 | /pics/linkedIn_logo.png |
| 1.55 | 2.45 | 0 | 0.4840426 | 推特 | /pics/twitter_logo_v2.png |
这就给了我们条形图的尺寸和我们要添加到条形图上的图片。现在剩下的就是循环浏览这个表格并添加图片。
这里,annotation_custom 是一个用于插入图像或装饰的ggplot2 帮助器。图片本身由Magick包的image_read 读取,由grid 包的rasterGrob 渲染。然后我们根据绘图数据设置x和y的尺寸,最后的绘图就准备好了。
for (i in seq(nrow(p_map))){
p <- p +
annotation_custom(
grid::rasterGrob(magick::image_read(p_map$img[i]),
width = unit(1, "npc"),
height = unit(1, "npc")),
xmin = p_map$xmin[i],
xmax = p_map$xmax[i],
ymin = p_map$ymin[i],
ymax = p_map$ymax[i])
}
p
这里有许多可能的变化,包括图像作为背景,图像在顶部的条形图上(我在我的R与Python见解的入门笔记本中正在做),图像角落的标志,以及更多。如果少用的话,这些视觉元素可以丰富你的视觉效果和洞察力展示。
有兴趣玩玩这些图吗?我很乐意看到你的想法!
-
参加Hidden Gems挑战赛,向我们展示你的技能,或者叉开我的启动器笔记本来修补代码并获得灵感。
-
TidyTuesday交叉活动仍在进行,我们非常欢迎你在Twitter上与社区分享你的想法。
祝你玩得开心!