将动态垂直线轨迹添加到绘图动画水平条形图
Add dynamic vertical line trace to plotly animated horizontal bar plot
我有一个使用 plotly 包的水平动画条形图。我想添加一条垂直线来显示条形值的中值,我希望它随条形图的框架一起改变值。
简化示例:
data <- data_frame(Year=c(1995, 1995, 1995, 1996, 1996, 1996, 1997, 1997, 1997, 1998, 1998, 1998),
Highest_Degree=c("Associate's", "Bachelor's", "PhD",
"Associate's", "Bachelor's", "PhD",
"Associate's", "Bachelor's", "PhD",
"Associate's", "Bachelor's", "PhD"),
Salary=c(35200, 45270, 79670,
41950, 56330, 99410,
42780, 55930, 100000,
42860, 56080, 100000)
)
#plot
plot_ly(data, x=~Salary, y=~Highest_Degree, frame=~Year, type = 'bar') %>%
layout(yaxis=list(title=" "), xaxis=list(title="Median Salary (USD)"),
title=list(text=paste("Median Salary by Education Level 1995-1998")))
##to get medians list
medians <- data %>%
select(c(Year, Salary)) %>%
group_by(Year) %>%
summarise(Median=median(Salary))
图像示例,除了它需要随着动画的其余部分而改变:
更新:我将整体中位数添加到我的原始数据框中,并添加了一条带有轨迹的水平线(下图),但该线并未跨越绘图的整个高度。当 y 轴不是数字时,有没有办法在布局中使用 'shapes' 来做到这一点,以便它跨越整个图?
从构建 plotly
绘图并手动修改框架的布局开始可能是最简单的方法。之后,我使用矢量化来更改帧,所以我想确保中位数按年份排序。对于如此小的数据集,可能没有必要通过代码来执行此操作,但我认为这只是您正在使用的内容的一个小快照。
# build to see frames
p2 <- plotly_build(p1)
# modify frames
# first, make sure the data is in order by year (order by frame)
medians <- arrange(medians, Year)
lapply(1:nrow(medians), # for each frame
function(i){
vline = list(
type = "line",
y0 = 0,
y1 = 1,
yref = "paper",
x0 = unlist(medians[i, ]$Median), # median for that frame
x1 = unlist(medians[i, ]$Median),
line = list(color = "black", dash = "dot") # you can mod here!
)
p2$x$frames[[i]]$layout <<- list(shapes = list(vline)) # change plot
})
之后,你可以调用p2
来绘制它。
我有一个使用 plotly 包的水平动画条形图。我想添加一条垂直线来显示条形值的中值,我希望它随条形图的框架一起改变值。
简化示例:
data <- data_frame(Year=c(1995, 1995, 1995, 1996, 1996, 1996, 1997, 1997, 1997, 1998, 1998, 1998),
Highest_Degree=c("Associate's", "Bachelor's", "PhD",
"Associate's", "Bachelor's", "PhD",
"Associate's", "Bachelor's", "PhD",
"Associate's", "Bachelor's", "PhD"),
Salary=c(35200, 45270, 79670,
41950, 56330, 99410,
42780, 55930, 100000,
42860, 56080, 100000)
)
#plot
plot_ly(data, x=~Salary, y=~Highest_Degree, frame=~Year, type = 'bar') %>%
layout(yaxis=list(title=" "), xaxis=list(title="Median Salary (USD)"),
title=list(text=paste("Median Salary by Education Level 1995-1998")))
##to get medians list
medians <- data %>%
select(c(Year, Salary)) %>%
group_by(Year) %>%
summarise(Median=median(Salary))
图像示例,除了它需要随着动画的其余部分而改变:
更新:我将整体中位数添加到我的原始数据框中,并添加了一条带有轨迹的水平线(下图),但该线并未跨越绘图的整个高度。当 y 轴不是数字时,有没有办法在布局中使用 'shapes' 来做到这一点,以便它跨越整个图?
从构建 plotly
绘图并手动修改框架的布局开始可能是最简单的方法。之后,我使用矢量化来更改帧,所以我想确保中位数按年份排序。对于如此小的数据集,可能没有必要通过代码来执行此操作,但我认为这只是您正在使用的内容的一个小快照。
# build to see frames
p2 <- plotly_build(p1)
# modify frames
# first, make sure the data is in order by year (order by frame)
medians <- arrange(medians, Year)
lapply(1:nrow(medians), # for each frame
function(i){
vline = list(
type = "line",
y0 = 0,
y1 = 1,
yref = "paper",
x0 = unlist(medians[i, ]$Median), # median for that frame
x1 = unlist(medians[i, ]$Median),
line = list(color = "black", dash = "dot") # you can mod here!
)
p2$x$frames[[i]]$layout <<- list(shapes = list(vline)) # change plot
})
之后,你可以调用p2
来绘制它。