这是通过操纵频率计数使频率计数变为负数来回答该问题的第二次且希望是完整的尝试am==1
。区别在于第一次尝试 https://stackoverflow.com/a/41794581/3817004就是它geom_col(position = "fill")
被用来代替geom_tile()
用于绘图。
注:我没有编辑过第一个答案 https://stackoverflow.com/a/41794581/3817004因为OP已经对此发表了评论,我最终可能会删除第一个不完整的答案。
准备数据
freq_am <-data.frame(xtabs(~cyl + gear + am, mtcars))
freq_am$Freq_am <- freq_am$Freq * (-1)^as.integer(as.character(freq_am$am))
这会创建一个新列Freq_am
where Freq
计数乘以-1
if am == 1
(手动的)。使用逻辑值求幂是一个需要避免的技巧ifelse
.
Plotting
有两种可能性可以实现所需的热图式外观。
变体1
p <- ggplot(freq_am, (aes(x = cyl, y = Freq, fill = Freq_am))) +
geom_col(position = "fill", width = 1) +
scale_fill_gradient2() +
facet_grid(gear ~ ., as.table = FALSE, switch = "y") +
scale_y_continuous(expand = c(0, 0)) +
scale_x_discrete(expand = c(0, 0))
p
这将创建一个堆积条形图Freq
vs cyl
using geom_col()
其中条形垂直拉伸(position = "fill"
)和水平(width = 1
) 来填充绘图区域。除此之外expand = c(0, 0)
参数到scale
函数告诉ggplot
to not像往常一样展开轴。请注意,x 轴是离散的xtabs()
已经胁迫cyl
因素。
facet_grid()
用于模拟 y 轴grid
按递增顺序排列的值(as.table = FALSE
). switch = "y"
将面板条移至左侧。
scale_fill_gradient2()
默认情况下使用方便的发散配色方案,自动变速箱的汽车数量显示为蓝色,手动变速箱的汽车数量显示为红色。
现在,我们需要删除热图不需要的所有装饰和空间。最后,y轴标签被重命名:
p + theme(panel.grid = element_blank()
, axis.ticks = element_blank()
, axis.text.y = element_blank()
, strip.background = element_blank()
, panel.spacing.y = unit(0, "pt")
) +
ylab("gear")
这种方法的缺点是图块之间缺乏边界。因此,如果相邻的图块具有与例如 6 缸、3 齿轮和 4 齿轮图块相同的颜色,则很难区分计数的份额。
变体2
此变体在图块之间添加了边框。边框的宽度可以灵活调整:
p <- ggplot(freq_am, (aes(x = 1, y = Freq, fill = Freq_am))) +
geom_col(position = "fill") +
scale_fill_gradient2() +
facet_grid(gear ~ cyl, as.table = FALSE, switch = "both") +
scale_y_continuous(expand = c(0, 0)) +
scale_x_continuous(expand = c(0, 0))
p
在这里,我们使用facet_grid()
对于两个方向。对于每个面板,Freq
绘制与虚拟变量的关系图1
using geom_col()
如上。作为虚拟变量1
是数字,我们不需要width
参数为geom_col()
。现在两个轴都是连续的。
同样,我们需要删除一些装饰并重命名 x 轴和 y 轴上的标签:
p + theme(panel.grid = element_blank()
, axis.ticks = element_blank()
, axis.text = element_blank()
, strip.background = element_blank()
# , panel.spacing = unit(0, "pt")
) +
xlab("cyl") + ylab("gear")
现在,我们确实有了一个带有图块之间边框的热图。为了删除边框或调整宽度,您可以使用以下命令取消注释该行panel.spacing
并更改值。