ggplot2 在 geom_raster 中结合了连续变量和离散变量
ggplot2 combine continous variable and discrete variable in geom_raster
我有一个包含两种元素的 100 x 100 矩阵。第一种是 0 到 100 之间的连续变量(在程序中实际上是离散的,但它们表示连续的东西,因此应该有一个连续缩放的图例),另一种是具有三个可能值(-1、-2、 -3). I used this matrix in this question.
目标是制作连续变量的热图,同时区分具有离散负值的区域。目前,我正在使用 ggplot 和 geom_raster(请参阅此问题底部的代码片段)来绘制以下热图。
但是,顶部和右侧的均匀灰色区域由负离散值组成,应该与图表的其他部分具有不同的 color/pattern。例如,这些区域应该是白色的,并带有指示值的标签(见第二张图片)。有没有办法用ggplot做到这一点?在理想情况下,该图应该有连续范围的图例和三个离散值的指南。
奖励问题:是否可以在边界处画一条线,即,如果矩阵中的下一个元素具有不同的值,则画一条线。现在我通过绘制许多段来手动执行此操作(参见第二个代码片段),但这不是可行的方法(而且我没有成功地将其与 ggplot 热图结合起来)。
第一个代码片段(制作热图)
minRate = 0;
maxRate = 100;
colnames(df) = NULL
df = melt(df)
colnames(df) = c("col", "row", "value")
# geom_raster takes the center as input argument
df[,"col"] = df[,"col"] - 0.5
df[,"row"] = df[,"row"] - 0.5
# Without labels
ggplot(df, aes(x = col, y = row, fill = value)) +
geom_raster() +
theme_bw() +
labs(fill="Rate (%)") +
theme(plot.margin=unit(c(3,3,3,2),"mm"), legend.position = "right") +
scale_fill_gradient(low="black", high="white", limits=c(minRate, maxRate)) +
scale_x_continuous("state 1", expand = c(0,0), limits=c(0,100)) +
scale_y_continuous("state 2", expand = c(0,0), limits=c(0,100))
第二个代码片段(仅绘制边框):
printPolicy <- function(df, title)
{
n = nrow(df)
plot(NA, xlim=c(0, n), ylim=c(0, n),
xlab="Machine 0", ylab="Machine 1", main=title,
las=1, yaxs='i', xaxs='i')
for (x0 in 1:(n-1))
{
for (x1 in 1:(n-1))
{
# Horizontal lines
if (df[x0, x1] != df[x0+1, x1])
segments(x1-1, x0, x1, x0)
# Vertical lines
if (df[x0, x1] != df[x0, x1+1])
segments(x1, x0-1, x1, x0)
}
}
}
使用 ggnewscale
包相对容易做到这一点,请参见下面的示例。假设 dat
是 read.csv(the_data_you_posted)
.
的输出
library(ggplot2)
library(ggnewscale)
dat <- as.matrix(dat)
dimnames(dat) <- NULL
mdat <- reshape2::melt(dat)
conti <- mdat[mdat$value >= 0,]
discr <- mdat[mdat$value < 0,]
ggplot(mapping = aes(Var1, Var2)) +
geom_raster(data = conti, aes(fill = value),
hjust = 0, vjust = 0) +
scale_fill_continuous() + # scale for continuous values need to be
# defined before call to new_scale_fill()
new_scale_fill() +
geom_raster(data = discr, aes(fill = as.factor(value)),
hjust = 0, vjust = 0)
按照您认为合适的方式装饰地块。
很遗憾,我不知道您的附加问题的答案,但我很想知道是否有人有针对该问题的自动解决方案。
我有一个包含两种元素的 100 x 100 矩阵。第一种是 0 到 100 之间的连续变量(在程序中实际上是离散的,但它们表示连续的东西,因此应该有一个连续缩放的图例),另一种是具有三个可能值(-1、-2、 -3). I used this matrix in this question.
目标是制作连续变量的热图,同时区分具有离散负值的区域。目前,我正在使用 ggplot 和 geom_raster(请参阅此问题底部的代码片段)来绘制以下热图。
但是,顶部和右侧的均匀灰色区域由负离散值组成,应该与图表的其他部分具有不同的 color/pattern。例如,这些区域应该是白色的,并带有指示值的标签(见第二张图片)。有没有办法用ggplot做到这一点?在理想情况下,该图应该有连续范围的图例和三个离散值的指南。
奖励问题:是否可以在边界处画一条线,即,如果矩阵中的下一个元素具有不同的值,则画一条线。现在我通过绘制许多段来手动执行此操作(参见第二个代码片段),但这不是可行的方法(而且我没有成功地将其与 ggplot 热图结合起来)。
第一个代码片段(制作热图)
minRate = 0;
maxRate = 100;
colnames(df) = NULL
df = melt(df)
colnames(df) = c("col", "row", "value")
# geom_raster takes the center as input argument
df[,"col"] = df[,"col"] - 0.5
df[,"row"] = df[,"row"] - 0.5
# Without labels
ggplot(df, aes(x = col, y = row, fill = value)) +
geom_raster() +
theme_bw() +
labs(fill="Rate (%)") +
theme(plot.margin=unit(c(3,3,3,2),"mm"), legend.position = "right") +
scale_fill_gradient(low="black", high="white", limits=c(minRate, maxRate)) +
scale_x_continuous("state 1", expand = c(0,0), limits=c(0,100)) +
scale_y_continuous("state 2", expand = c(0,0), limits=c(0,100))
第二个代码片段(仅绘制边框):
printPolicy <- function(df, title)
{
n = nrow(df)
plot(NA, xlim=c(0, n), ylim=c(0, n),
xlab="Machine 0", ylab="Machine 1", main=title,
las=1, yaxs='i', xaxs='i')
for (x0 in 1:(n-1))
{
for (x1 in 1:(n-1))
{
# Horizontal lines
if (df[x0, x1] != df[x0+1, x1])
segments(x1-1, x0, x1, x0)
# Vertical lines
if (df[x0, x1] != df[x0, x1+1])
segments(x1, x0-1, x1, x0)
}
}
}
使用 ggnewscale
包相对容易做到这一点,请参见下面的示例。假设 dat
是 read.csv(the_data_you_posted)
.
library(ggplot2)
library(ggnewscale)
dat <- as.matrix(dat)
dimnames(dat) <- NULL
mdat <- reshape2::melt(dat)
conti <- mdat[mdat$value >= 0,]
discr <- mdat[mdat$value < 0,]
ggplot(mapping = aes(Var1, Var2)) +
geom_raster(data = conti, aes(fill = value),
hjust = 0, vjust = 0) +
scale_fill_continuous() + # scale for continuous values need to be
# defined before call to new_scale_fill()
new_scale_fill() +
geom_raster(data = discr, aes(fill = as.factor(value)),
hjust = 0, vjust = 0)
按照您认为合适的方式装饰地块。
很遗憾,我不知道您的附加问题的答案,但我很想知道是否有人有针对该问题的自动解决方案。