r - gganimate 如何订购有序条形时间序列?
问题描述
我有一个时间序列的数据,其中我在 y 轴上绘制疾病的诊断率,在 x 轴上绘制DIAG_RATE_65_PLUS
地理组以NAME
作为简单的条形图进行比较。我的时间变量是ACH_DATEyearmon
,动画正在循环播放,如标题所示。
df %>% ggplot(aes(reorder(NAME, DIAG_RATE_65_PLUS), DIAG_RATE_65_PLUS)) +
geom_bar(stat = "identity", alpha = 0.66) +
labs(title='{closest_state}') +
theme(plot.title = element_text(hjust = 1, size = 22),
axis.text.x=element_blank()) +
transition_states(ACH_DATEyearmon, transition_length = 1, state_length = 1) +
ease_aes('linear')
我已经重新排序NAME
,所以它的排名是DIAG_RATE_65_PLUS
.
gganimate 产生什么:
我现在有两个问题:
1) gganimate 究竟如何重新排序数据?有一些总体上的重新排序,但每个月都没有按照DIAG_RATE_65_PLUS
从小到大对组进行完美排序的框架。理想情况下,我希望完美订购最后一个月的“2018 年 8 月”。前几个月的所有 x 轴都可以基于“2018 年NAME
8 月”的订单。
2) gganimate 中是否有一个选项,其中组在条形图中每个月“转移”到正确的排名?
我的评论查询的情节:
https://i.stack.imgur.com/s2UPw.gif https://i.stack.imgur.com/Z1wfd.gif
@JonSpring
df %>%
ggplot(aes(ordering, group = NAME)) +
geom_tile(aes(y = DIAG_RATE_65_PLUS/2,
height = DIAG_RATE_65_PLUS,
width = 0.9), alpha = 0.9, fill = "gray60") +
geom_hline(yintercept = (2/3)*25, linetype="dotdash") +
# text in x-axis (requires clip = "off" in coord_cartesian)
geom_text(aes(y = 0, label = NAME), hjust = 2) + ## trying different hjust values
theme(plot.title = element_text(hjust = 1, size = 22),
axis.ticks.y = element_blank(), ## axis.ticks.y shows the ticks on the flipped x-axis (the now metric), and hides the ticks from the geog layer
axis.text.y = element_blank()) + ## axis.text.y shows the scale on the flipped x-axis (the now metric), and hides the placeholder "ordered" numbers from the geog layer
coord_cartesian(clip = "off", expand = FALSE) +
coord_flip() +
labs(title='{closest_state}', x = "") +
transition_states(ACH_DATEyearmon,
transition_length = 2, state_length = 1) +
ease_aes('cubic-in-out')
使用hjust=2
,标签不对齐并四处移动。
更改上面的代码hjust=1
@eipi10
df %>%
ggplot(aes(y=NAME, x=DIAG_RATE_65_PLUS)) +
geom_barh(stat = "identity", alpha = 0.66) +
geom_hline(yintercept=(2/3)*25, linetype = "dotdash") + #geom_vline(xintercept=(2/3)*25) is incompatible, but geom_hline works, but it's not useful for the plot
labs(title='{closest_state}') +
theme(plot.title = element_text(hjust = 1, size = 22)) +
transition_states(ACH_DATEyearmon, transition_length = 1, state_length = 50) +
view_follow(fixed_x=TRUE) +
ease_aes('linear')
解决方案
为了补充@eipi10 的出色答案,我认为这是一个值得更换geom_bar
以获得更大灵活性的案例。geom_bar
通常对于离散类别来说是相当方便的,但它并没有让我们充分利用gganimate
'ssilly-smooth 动画的荣耀。
例如,使用geom_tile
,我们可以重新创建与 geom_bar 相同的外观,但在 x 轴上具有流体运动。这有助于保持对每个条的视觉跟踪,并查看哪些条的顺序变化最多。我认为这很好地解决了您问题的第二部分。
为了完成这项工作,我们可以在数据中添加一个新列,显示每个月应该使用的顺序。我们将此订单保存为双精度数,而不是整数(使用* 1.0
)。这将允许gganimate
在位置 1 和位置 2 之间设置动画时在位置 1.25 放置一个条形图。
df2 <- df %>%
group_by(ACH_DATEyearmon) %>%
mutate(ordering = min_rank(DIAG_RATE_65_PLUS) * 1.0) %>%
ungroup()
现在我们可以以类似的方式绘图,但使用geom_tile
代替geom_bar
. 我想NAME
在顶部和轴上都显示,所以我使用了两个geom_text
具有不同 y 值的调用,一个在零处,一个在条形的高度。vjust
让我们使用文本行单位垂直对齐每个。
这里的另一个技巧是关闭剪辑coord_cartesian
,这让底部文本位于绘图区域下方,进入 x 轴文本通常所在的位置。
p <- df2 %>%
ggplot(aes(ordering, group = NAME)) +
geom_tile(aes(y = DIAG_RATE_65_PLUS/2,
height = DIAG_RATE_65_PLUS,
width = 0.9), alpha = 0.9, fill = "gray60") +
# text on top of bars
geom_text(aes(y = DIAG_RATE_65_PLUS, label = NAME), vjust = -0.5) +
# text in x-axis (requires clip = "off" in coord_cartesian)
geom_text(aes(y = 0, label = NAME), vjust = 2) +
coord_cartesian(clip = "off", expand = FALSE) +
labs(title='{closest_state}', x = "") +
theme(plot.title = element_text(hjust = 1, size = 22),
axis.ticks.x = element_blank(),
axis.text.x = element_blank()) +
transition_states(ACH_DATEyearmon,
transition_length = 2, state_length = 1) +
ease_aes('cubic-in-out')
animate(p, nframes = 300, fps = 20, width = 400, height = 300)
回到您的第一个问题,这是我fill = "gray60"
从geom_tile
通话中删除后制作的彩色版本。我按照NAME
2017 年 8 月的顺序对类别进行了排序,因此它们看起来像您所描述的那样是按顺序排列的。
可能有更好的方法来进行排序,但我通过加入df2
一个只有 2017 年 8 月排序的表来做到这一点。
Aug_order <- df %>%
filter(ACH_DATEyearmon == "Aug 2017") %>%
mutate(Aug_order = min_rank(DIAG_RATE_65_PLUS) * 1.0) %>%
select(NAME, Aug_order)
df2 <- df %>%
group_by(ACH_DATEyearmon) %>%
mutate(ordering = min_rank(DIAG_RATE_65_PLUS) * 1.0) %>%
ungroup() %>%
left_join(Aug_order) %>%
mutate(NAME = fct_reorder(NAME, -Aug_order))
推荐阅读
- java - Minecraft 插件帮助(Spigot)
- r - 根据 R 中的行值更改字符列的内容
- python-3.x - 使用 Python 3 运行 Apache Beam v 2.2.5 时,我应该使用哪个版本的 dill?
- azure - 如何从 Microsoft Synapse 数据库更新 Azure 地图中的弹出窗口
- sql - 从查询创建 SQL 表
- r - 在没有标签的情况下向 ggplot 添加小中断
- c# - 您可以在 app.config 中拆分连接字符串吗?
- django - Django Rest Framework JSON API - 更新 M2M 关系不持久
- postgresql - 有没有办法在 Postgres 中执行有条件地触发或不触发先前设置的触发功能的命令?
- c# - 表达式树在手动输入时有效,但不是来自另一个类