[英]Floating bar chart with trend line on secondary axis
I am just tarting out trying to create visualizations with R/GGPLOT2. 我只是试图用R / GGPLOT2创建可视化。 The chart I am trying to acheive is a floating bar chart(one that has the bar go from one minimum to a maximum).
我试图实现的图表是一个浮动条形图(一个条形图从一个最小值到最大值)。 However, overlayed on top of this I would like a trend line that is on a secondary axis.
但是,重叠在此之上我想要一个在辅助轴上的趋势线。 This has been my attempt so far:
到目前为止,这是我的尝试:
# first, your data
table1 <- read.table(text = 'X A B C D E F G H I J K L
1 "BAR TOP" 31.5 31.8 30.3 28.0 24.9 24.4 21.7 20.9 24.5 25.4 26.0 28.7
2 "TREND VALUE" 1000 1345 1234 1456 1324 1765 1567 1345 1556 1334 1224 1556
3 "BAR BOTTOM" 4.0 5.6 4.1 -1.3 0.0 -3.1 -2.6 -1.4 -0.8 2.0 2.7 4.1', header =T)
library(reshape2)
library(ggplot2)
# reshape to wide format (basically transposing the data.frame)
w <- dcast(melt(table1), variable~X)
p<-ggplot(w, aes(x=variable,ymin = `BAR BOTTOM`,
ymax = `BAR TOP`, lower = `BAR BOTTOM`,
upper = `BAR TOP`, middle = `BAR BOTTOM`)) +
geom_boxplot(stat = 'identity')
p <- p + labs(y = "BAR RANGE",
x = "VARIABLE",
colour = "Parameter")
p <- p + theme(legend.position = c(0.8, 0.9))
p
This is getting my the bars how I want them, however I am having trouble using the value TREND VALUE as a trend line on a secondary axis. 这是我想要它们的条形码,但是我在使用TREND VALUE值作为辅助轴上的趋势线时遇到了麻烦。 Any advice or direction?
有什么建议或指示吗?
I would suggest manually transform TREND VALUE
into desired range and specify sec.axis
with same transformation. 我建议手动将
TREND VALUE
转换为所需范围,并指定具有相同转换的sec.axis
。 I also will use geom_rect()
instead of geom_boxplot()
: 我也将使用
geom_rect()
而不是geom_boxplot()
:
p <- ggplot(w) +
aes(ymin = `BAR BOTTOM`,
ymax = `BAR TOP`,
xmin = as.numeric(variable) - .3,
xmax = as.numeric(variable) + .3,
x = as.numeric(variable),
# Here we (roughly) transform `TREND VALUE` into range of BAR values
y = `TREND VALUE`/100
) +
geom_rect(fill = 'white', col = 'black')+
geom_line() +
scale_x_continuous(labels = levels(w$variable),
breaks = 1:nlevels(w$variable))+
# Specification for secondary axis - inverse transform of `TREND VALUE`
scale_y_continuous(sec.axis = ~.*100)
Resulting plot: 结果情节:
p
Answering comment: we can specify almost any transformation: 回答评论:我们几乎可以指定任何转换:
Transform x
values into range, mn
- new minimum value, mx
- new maximum: 将
x
值转换为范围, mn
- 新的最小值, mx
- 新的最大值:
trans_foo <- function(x, mn, mx) {
(mx - mn)*((x - min(x))/(max(x) - min(x))) + mn
}
Back transformation: 回归:
itrans_foo <- function(y, min_x, max_x, mn, mx) {
min_x + ((y - mn)*(max_x - min_x))/(mx - mn)
}
Now using this functions with mx = 0
and mn = 30
(minimum and maximum of the reversed BAR axis) & scale_y_reverse()
, we will get the reversed primary axis and the normal secondary axis: 现在使用
mx = 0
和mn = 30
(反转BAR轴的最小值和最大值)和scale_y_reverse()
,我们将得到反转的主轴和正常的副轴:
p <- ggplot(w) +
aes(
ymin = `BAR BOTTOM`,
ymax = `BAR TOP`,
xmin = as.numeric(variable) - .3,
xmax = as.numeric(variable) + .3,
x = as.numeric(variable),
y = trans_foo(
`TREND VALUE`,
30, 0)
) +
geom_rect(fill = "white", col = "black") +
geom_line() +
scale_x_continuous(
labels = levels(w$variable),
breaks = 1:nlevels(w$variable)) +
labs(
y = "BAR RANGE",
x = "VARIABLE",
colour = "Parameter") +
# Using scale_y_reverse will reverse the primary axis and
# reverse the reversed secondary axis making it normal
scale_y_reverse(sec.axis = sec_axis(
trans = ~itrans_foo(
.,
min(w$`TREND VALUE`),
max(w$`TREND VALUE`),
30, 0
),
name = "TREND"))
p
You can try to add a loess smoothed line with geom_smooth. 您可以尝试使用geom_smooth添加黄土平滑线。 In order to get it on the same axis, just rescale it.
为了使它在同一轴上,只需重新调整它。
p<-ggplot(w, aes(x=variable,ymin = `BAR BOTTOM`,
ymax = `BAR TOP`, lower = `BAR BOTTOM`,
upper = `BAR TOP`, middle = `BAR BOTTOM`)) +
geom_boxplot(stat = 'identity')
+ geom_smooth(aes(x = as.numeric(w$variable), y = w$`TREND VALUE`/100))
This will not result in a different axis, but dividing by 100 makes it easy to interpret still. 这不会产生不同的轴,但除以100使其易于解释。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.