[geom_text()会导致多面符号的更改

问题描述 投票:1回答:1

我正在构建一个多面图,其中每个面板都有3组不同的点,每组都有不同的形状。一切正常,直到我尝试使用geom_text()向每个面板添加一些文本。当我在绘图中包含geom_text()时,我收到一条错误消息,提示“手动比例值不足:需要4个,但只提供3个”。我可以通过添加其他形状和颜色来纠正此问题,但我无法控制在添加geom_text()时发生的形状/颜色因子的重新映射。

这是我正在运行的脚本:

library(ggplot2)
library(RColorBrewer)
library(cowplot)

make_hist_df <- function (vals, breaks, expt, type) {
  hist_d <- hist(vals,breaks=breaks,plot=FALSE)
  hist_d_nz<-hist_d$counts > 0
  n_d_nz<-length(hist_d$counts[hist_d_nz])
  hist_df <- data.frame(expt=character(n_d_nz), counts=numeric(n_d_nz), mids=numeric(n_d_nz),type=character(n_d_nz))
  hist_df$counts <- hist_d$counts[hist_d_nz]
  hist_df$mids <- hist_d$mids[hist_d_nz]
  hist_df$expt = expt
  hist_df$type = type

  return(hist_df)
  }

## get some normal distributions
n1<-rnorm(n=10000, mean=5,sd=1)
n2<-rnorm(n=5000,mean=15,sd=1)
n3<-rnorm(n=2000,mean=25,sd=1)

breaks=seq(0,30,0.5)

tot_hist_df = rbind(
  make_hist_df(n1,breaks,expt='one',type='low'),
  make_hist_df(n2,breaks,expt='one',type='mid'),
  make_hist_df(n3,breaks,expt='one',type='high')
  )

tot_hist_df = rbind(tot_hist_df,
  make_hist_df(n1,breaks,expt='two',type='low'),
  make_hist_df(n2,breaks,expt='two',type='mid'),
  make_hist_df(n3,breaks,expt='two',type='high')
  )

tot_hist_df$expt<-factor(tot_hist_df$expt,levels=c('one','two'), ordered=TRUE)
tot_hist_df$type<-factor(tot_hist_df$type,levels=c('low','mid','high'), ordered=TRUE)

s.open_circ<-1
s.closed_circ<-16
s.triangle <- 2
s.plus<-4
s.dot <- 20
sb.shapes   = c(s.open_circ, s.triangle, s.closed_circ)
sb.shapes_l = c(s.open_circ, s.triangle, s.closed_circ, s.dot)

q_set <- c('N1','N2','N3')
n_q <- length(q_set)

sb.colors <-brewer.pal(max(3,n_q),'Dark2') # 'Dark2', 'Set2', 'Paired'
sb.colors_l <- c(sb.colors,'black')

sb.sizes = rep(1.25,n_q)

## plot out without labels
p1 <- ggplot(data=tot_hist_df,aes(x=mids, y=counts, shape=type, color=type))+geom_point() +
  scale_color_manual(values=sb.colors) +
  scale_shape_manual(values=sb.shapes) +
  facet_wrap(~expt, ncol=2)

## make a label dataframe
hist_label=data.frame(expt=c('one','two'), lab=c('mean 5, 20','mean 5, 20 - dup'),type=c('xlab','xlab'))
hist_label$expt <- factor(hist_label$expt,levels=c('one','two'),ordered=TRUE)
hist_label$type <- factor(hist_label$type,levels=c('low','mid','high','xlab'),ordered=TRUE)

## plot out without labels
p2 <- ggplot(data=tot_hist_df,aes(x=mids, y=counts, shape=type, color=type))+geom_point() +
  geom_text(data=hist_label, aes(x=10,y=1000,label=lab)) +
  scale_color_manual(values=sb.colors_l) +
  scale_shape_manual(values=sb.shapes_l) +
  facet_wrap(~expt, ncol=2)

plot_grid(p1,p2,ncol=1)

这是它产生的输出:bad plot

顶部和底部面板的颜色和形状都不同。

我不明白为什么geom_text()在为绘图数据和标签数据结构明确指定它们之后重新映射由“ type”指定的因子水平。重新映射(看起来像字母)会同时消除颜色和形状。

ggplot2 scale shapes manual geom-text
1个回答
0
投票

感谢您提供可复制的示例。了解现在正在发生的事情要清楚得多。

您描述的重新映射行为是因为在学习离散值(训练比例)时,它不会用从文本数据中学习到的标签来聪明地更新从直方图数据中学习到的标签。要解决此问题,您可以手动设置比例尺的限制。

ggplot(data=tot_hist_df,
       aes(x=mids, y=counts, shape=type, color=type))+
  geom_point() +
  geom_text(data=hist_label, 
            aes(x=10,y=1000,label=lab)) +
  scale_color_manual(values=sb.colors_l, limits = levels(hist_label$type)) +
  scale_shape_manual(values=sb.shapes_l, limits = levels(hist_label$type)) +
  facet_wrap(~expt, ncol=2)

enter image description here

编辑:

或者,您也可以在手动比例尺中设置drop = FALSE

ggplot(data=tot_hist_df,
       aes(x=mids, y=counts, shape=type, color=type))+
  geom_point() +
  geom_text(data=hist_label, 
            aes(x=10,y=1000,label=lab)) +
  scale_color_manual(values=sb.colors_l, drop = FALSE) +
  scale_shape_manual(values=sb.shapes_l, drop = FALSE) +
  facet_wrap(~expt, ncol=2)

END EDIT

下面,请遵循一些可能有用的提示。第一个是您可以在手动离散比例中使用命名矢量,这将保持符号与颜色/形状之间的链接,而不管符号是否在数据中。

当必须绘制多个相似的图并且不知道任何单个图中是否仅存在类别的子集时,这也很有用。

在下面颜色的图中的注意事项已正确匹配数据,并且未使用的not_in_data符号/颜色映射未显示图例项目。

my_colours <- setNames(object = c(brewer.pal(3, 'Dark2'), 'black', 'blue'), 
                       nm = c(levels(hist_label$type), "not_in_data"))
my_shapes <- setNames(object = c(1, 2, 16, NA), 
                      nm = levels(hist_label$type))

ggplot(data=tot_hist_df,
       aes(x=mids, y=counts, shape=type, color=type))+
  geom_point() +
  geom_text(data=hist_label, 
            aes(x=10,y=1000,label=lab)) +
  scale_color_manual(values=my_colours) +
  scale_shape_manual(values=my_shapes) +
  facet_wrap(~expt, ncol=2)

enter image description here

[第二个提示是,您可以避免文本层不继承主图的美感(将形状和颜色分配给文本层,而这可能并不需要),从而不必在图例中包含文本。还要注意,由于不需要为文本的颜色和形状更新比例,因此恢复了直方图中因子水平的正确顺序。

ggplot(data=tot_hist_df,
       aes(x=mids, y=counts, shape=type, color=type)) + 
  geom_point() +
  geom_text(data=hist_label, 
            aes(x=10,y=1000, label=lab),
            inherit.aes = FALSE) +
  scale_color_manual(values=my_colours) +
  scale_shape_manual(values=my_shapes) +
  facet_wrap(~expt, ncol=2)

enter image description here

实现相同目的的另一种方法,它不是在主图调用中定义美感,而是在点层中调用它们(图与上面相同)。>>

ggplot(data=tot_hist_df) + 
  geom_point(aes(x=mids, y=counts, shape=type, color=type)) +
  geom_text(data=hist_label, 
            aes(x=10,y=1000, label = lab)) +
  scale_color_manual(values=sb.colors) +
  scale_shape_manual(values=sb.shapes) +
  facet_wrap(~expt, ncol=2)

希望对您有所帮助!

© www.soinside.com 2019 - 2024. All rights reserved.