R语言 如何将一个数据组显示为点,另一个显示为置信椭圆?ggplot和ggsave的问题

yqkkidmi  于 2023-01-10  发布在  其他
关注(0)|答案(1)|浏览(116)

我是R的新手,我试图生成两个变量的散点图,每个变量的值分为4类。
具体而言,我正在努力实现以下目标:
1.将两组显示为数据点,将两组显示为置信椭圆
1.生成并保存具有相同尺寸的散点图,即图框大小和图面积(即x轴长8 cm,y轴长6 cm)。
下面你可以找到一个可复制的版本(你只需要定义png文件的输出),但是它显示了所有数据的数据点和置信椭圆:

library(ggplot2)

out_path = YOUR OUTPUT DIRECTORY

#data frame
gr1 <- (rep(paste('B-12-B-002'), 10))
gr2 <- (rep(paste('B-12-M-03'), 10))
gr3 <-  (rep(paste('b-b-d-3'), 10))
gr4 <-  (rep(paste('h-12-b-01'), 10))

Run_type <- c(gr1,gr2,gr3,gr4)

axial_ratio <- runif(40,0,1) 
Solidity <- runif(40,0,1)
Convexity <- runif(40,0,1)

sel_data_all <- data.frame(Run_type,axial_ratio,Solidity,Convexity)
fill_colors <- c('red','blue','green','orange');

#Plot

one_plot = ggplot(sel_data_all,aes(x = axial_ratio,y = Solidity))+         
  geom_point(aes(x = axial_ratio,y = Solidity, fill = Run_type, shape = Run_type), color = "black", stroke = 1, 
             size = 5, alpha = 0.4)+
  stat_ellipse(data = sel_data_all, aes(x = axial_ratio, y = Solidity, fill = Run_type,colour=Run_type),geom = "polygon",alpha = 0.4,type = "norm",level = 0.6, 
               show.legend = FALSE) +  #, group=Run_type , data = subset(sel_data_all, Run_type %in% leg_keys_man[1:7]),
  scale_shape_manual(values=c(21,21,23,23))+ 
  scale_fill_manual(values = fill_colors)+
  scale_color_manual(values = fill_colors)+
  coord_fixed(ratio = 1)+
  theme(legend.position="top", # write 'none' to hide the legend
        legend.key = element_rect(fill = "white"), # Set background of the points in the legend
        legend.title = element_blank(), # Remove legend title
        
        panel.background=element_rect(fill = "white", colour="black"),
        panel.grid.major=element_line(colour="lightgrey"),
        panel.grid.minor=element_line(colour="lightgrey"),
        axis.title.x = element_text(margin = margin(t = 10), size = 12,face = "bold"), # margin = margin(t = 10) vjust = 0
        axis.title.y = element_text(margin = margin(r = 10), size = 12,face = "bold"), # margin = margin(r = 10) vjust = 2
        axis.text = element_text(color = "black", size = 10), # To hide the text from a specific axis do: axis.text.y = element_blank()
        axis.ticks.length=unit(-0.15, "cm"), # To hide the ticks from a specific axis do: axis.ticks.y = element_blank()
        #plot.margin = margin(t = 0, r = 1, b = 0.5, l = 0.5, unit = "cm"), # define margine of the plot frame t = top, r = right, b = bottom,  l = left
  )
  #expand_limits(x = 0, y = 0)+ #Force the origin of the plot to 0
  #xlim(c(0,1))+
  #ylim(c(0,1)) # or xlim, limit the axis to the values defined

show(one_plot)

# Save plots 
ggsave(
  filename=paste("Axial_ratio","_vs_","Solidity",".png",sep=""),
  plot = one_plot,
  device = "png",
  path = out_path,
  scale = 1,
  width = 8, # Refers to the plot frame, not the area
  height = 6, # Refers to the plot frame, not the area
  units = "cm",
  dpi = 300,
  limitsize = FALSE,
  bg = "white")

不幸的是,经过几天的尝试和阅读R文档和论坛,我无法做到这一点。
对于第一个任务,我尝试通过修改geom_point和stat_ellipse函数来设置数据子集,

geom_point(data = subset(sel_data_all, Run_type %in% c('B-12-B-002','B-12-M-03')),aes(x = axial_ratio,y = Solidity, fill = Run_type, shape = Run_type), color = "black", stroke = 1, 
             size = 5, alpha = 0.4)+ #
  stat_ellipse(data = subset(sel_data_all, Run_type %in% c('b-b-d-3','h-12-b-01')), aes(x = axial_ratio, y = Solidity, fill = Run_type,colour=Run_type),geom = "polygon",alpha = 0.4,type = "norm",level = 0.6, 
               show.legend = FALSE) +  #

但我最终得到了图例的副本(灰色)。
Like this.
对于我的第二个问题,在消息的顶部有脚本的工作版本,
Here is the plot that shows in the "Plots" window in RStudio:
But this is what is saved in the output directory.
关于第二个问题的最后一点说明:这里的脚本实际上是插入到一个for循环中的,这个循环可以生成多个散点图,这些散点图是由两个变量的唯一对组成的,这里提供的数据框只是部分的,以便你更容易地提供帮助。2不幸的是,这是ggsave生成的结果:
axial ratio vs convexity
ves_pct vs axial ratio
有人能帮忙吗?
提前感谢大家!

    • 编辑:**

所以,多亏了Marblo(我非常感谢),我几乎得到了我想要的,但仍然有一些事情我不能弄清楚。
这是代码的最后一个版本,为了更好地符合推理进行了一些修改:

library(tidyverse)

          set.seed(123)
          gr1 <- (rep(paste("B-12-B-002"), 10))
          gr2 <- (rep(paste("B-12-M-03"), 10))
          gr3 <- (rep(paste("b-b-d-3"), 10))
          gr4 <- (rep(paste("h-12-b-01"), 10))

          Sample_ID <- c(gr1, gr2, gr3, gr4)

          axial_ratio <- runif(40, 0, 1)
          Solidity <- runif(40, 0, 1)
          Convexity <- runif(40, 0, 1)

          sel_data_all <- data.frame(Sample_ID, axial_ratio, Solidity, Convexity)
          fill_colors <- c("#5bd9ca",
          "#1e99d6","#1e49d6","#f2581b80","#e8811280","#e3311280","#fc000080")

          sel_data_all <- sel_data_all |> add_column(Run_type = c(
            rep("MAG", 10), rep("PMAG", 10),
            rep("MAG", 10), rep("PMAG", 10)),   .before = "Sample_ID")
          
          one_plot = ggplot( 

          data = sel_data_all |> dplyr::filter(Run_type == "PMAG"),
          aes(x = axial_ratio, y = Solidity)
        ) +
        
        # CONFIDENCE ELLIPSE
        stat_ellipse(
          data = sel_data_all |> dplyr::filter(Run_type == "MAG"),
          aes(x = axial_ratio, y = Solidity,
              fill = Sample_ID),
          geom = "polygon", type = "norm", 
          level = 0.6,
          colour = 'white', # ellipse border
        ) +
        
        # DATA POINTS
        geom_point(aes(colour = Sample_ID, 
                       shape = Sample_ID),
                   stroke = 0.5,
                   size = 3,
        ) +
        
        scale_color_manual(values = fill_colors[1:3]) + # of Data points
        scale_shape_manual(values = c(21, 21, 23, 23,21,23,22)) + # of data points
        scale_fill_manual(values = fill_colors[4:7]) + # of ellipses
        coord_cartesian(xlim=c(0,1))+
        #scale_x_continuous(expand = expansion(mult = c(0.001, 0.05)))+           
        coord_cartesian(ylim=c(0,1))+           
        #scale_y_continuous(expand = expansion(mult = c(0.001, 0.05)))+
        # Theme
        theme(
          legend.position = "top",
          legend.key.size = unit(5, 'mm'), #change legend key size
          # legend.key.height = unit(1, 'cm'), #change legend key height
          # legend.key.width = unit(1, 'cm'), #change legend key width
          legend.text = element_text(size=8),
          legend.key = element_rect(fill = "white", colour = 'white'),
          legend.background = element_rect(fill = "transparent"),
          legend.title = element_blank(),
          panel.background = element_rect(fill = "white", colour = "black"),
          panel.grid.major = element_line(colour = "lightgrey"),
          panel.grid.minor = element_line(colour = "lightgrey"),
          axis.title.x = element_text(vjust = -1, size = 12, face = "bold"),
          axis.title.y = element_text(vjust = 4, size = 12, face = "bold"),
          axis.text = element_text(color = "black", size = 10),
          axis.ticks.length = unit(-0.15, "cm"),
          plot.margin = margin(t = 2,  # Top margin
                               r = 4,  # Right margin
                               b = 4,  # Bottom margin
                               l = 4, # Left margin
                               unit = "mm"),
        )+
        guides(colour = guide_legend(nrow=2, byrow=TRUE)+
        coord_fixed(ratio = 1))
              ggsave(
            filename=paste("snap",".png",sep=""),
            plot = one_plot,
            device = "png",
            path = here::here(),
            width = 8, # Refers to the plot frame, not the area
            height = 8, # Refers to the plot frame, not the area
            units = "cm",
            #dpi = 300,
            #limitsize = FALSE,
            bg = "white")

Here is the saved plot
我需要的是,数据点填充的颜色目前用于其边界,和边界的所有数据点在黑色。
我试着在美学上绕来绕去,但最后却以重复的传说和更多的困惑告终。
再次提前感谢您的帮助。

7d7tgy0s

7d7tgy0s1#

我已经提取了您的数据,并添加了一个名为group的变量,它使ggplot中的过滤更容易。
如果在ggplot(..,aes())中定义了xy,则不必在geom_point中再次定义。在geom_point中,已经为Run_type给予了颜色。应构成图例的变量。因为您在geom_ellipse中使用了DF的不同子集图例将被更新,并再次为变量创建4个图例条目而不是2个。因此,可以跳过color = Run_type
我添加了set.seed(),以确保结果具有可比性,尽管生成了随机数以组成DF

library(tidyverse)

set.seed(123)
gr1 <- (rep(paste("B-12-B-002"), 10))
gr2 <- (rep(paste("B-12-M-03"), 10))
gr3 <- (rep(paste("b-b-d-3"), 10))
gr4 <- (rep(paste("h-12-b-01"), 10))

Run_type <- c(gr1, gr2, gr3, gr4)

axial_ratio <- runif(40, 0, 1)
Solidity <- runif(40, 0, 1)
Convexity <- runif(40, 0, 1)

sel_data_all <- data.frame(Run_type, axial_ratio, Solidity, Convexity)
fill_colors <- c("red", "blue", "green", "orange")

df <- sel_data_all |> mutate(group = c(
  rep("Data", 10), rep("Conf", 10),
  rep("Data", 10), rep("Conf", 10)
))

ggplot(
  data = df |> dplyr::filter(group == "Data"),
  aes(x = axial_ratio, y = Solidity)
) +
  geom_point(aes(color = Run_type, shape = Run_type),
    stroke = 1,
    size = 5, alpha = 0.4
  ) +
  stat_ellipse(
    data = df |> dplyr::filter(group != "Data"),
    aes(
      x = axial_ratio, y = Solidity,
      fill = Run_type
    ),
    geom = "polygon", alpha = 0.4, type = "norm", level = 0.6,
    show.legend = FALSE
  ) +
  scale_shape_manual(values = c(21, 21, 23, 23)) +
  scale_fill_manual(values = fill_colors) +
  scale_color_manual(values = fill_colors) +
  coord_fixed(ratio = 1) +
  theme(
    legend.position = "top",
    legend.key = element_rect(fill = "white"),
    legend.title = element_blank(),
    panel.background = element_rect(fill = "white", colour = "black"),
    panel.grid.major = element_line(colour = "lightgrey"),
    panel.grid.minor = element_line(colour = "lightgrey"),
    axis.title.x = element_text(margin = margin(t = 10), size = 12, face = "bold"),
    axis.title.y = element_text(margin = margin(r = 10), size = 12, face = "bold"),
    axis.text = element_text(color = "black", size = 10),
    axis.ticks.length = unit(-0.15, "cm"),
  )

然后以相等的宽度和高度保存图。

ggsave(
  filename=paste("Axial_ratio","_vs_","Solidity",".png",sep=""),
  plot = last_plot(),
  device = "png",
  path = here::here(),
  width = 8, # Refers to the plot frame, not the area
  height = 8, # Refers to the plot frame, not the area
  units = "cm",
  #dpi = 300,
  #limitsize = FALSE,
  bg = "white")

保存的png如下所示。

新编辑

我的理解现在是,您希望geom_points有两种颜色,stat_ellipse有两种不同的颜色。
所以下面将展示一个新的尝试。如果这是正确的答案,我会删除上面的大部分,使这篇文章更好读。
我认为ggsave问题已经解决。
我已经定义了两种不同的颜色集;一个用于geom_point,另一个用于stat_ellipse。(定义了3种和4种颜色,尽管在scale_color_manualscale_fill_manual中只需要2种颜色。)
对于geom_pointstat_ellipse,使用了不同的DF,调用ggplot时不使用任何dataaes。当调用geom_pointstat_ellipse时,将 * 单独 * 定义这两个函数。
对于stat_ellipse,使用fill;对于geom_point,使用color作为aes
如果不想使用其中一个图例,可以在相应的geom中使用show.legend = F
xlimylim定义轴限制。
guides()theme_bw()确保擦除legend.key的暗背景。
我试着使主题aa更简洁一点。

library(tidyverse)

set.seed(123)
gr1 <- (rep(paste("B-12-B-002"), 10))
gr2 <- (rep(paste("B-12-M-03"), 10))
gr3 <- (rep(paste("b-b-d-3"), 10))
gr4 <- (rep(paste("h-12-b-01"), 10))

Sample_ID <- c(gr1, gr2, gr3, gr4)

axial_ratio <- runif(40, 0, 1)
Solidity <- runif(40, 0, 1)
Convexity <- runif(40, 0, 1)

sel_data_all <- data.frame(Sample_ID, axial_ratio, Solidity, Convexity)
fill_colors_points <- c("#5bd9ca", "#1e99d6", "#1e49d6")
fill_colors_ellipse <- c("#f2581b80", "#e8811280", "#e3311280", "#fc000080")

sel_data_all <- sel_data_all |> mutate(Run_type = c(
  rep("MAG", 10), rep("PMAG", 10),
  rep("MAG", 10), rep("PMAG", 10)
))

ggplot() +
  stat_ellipse(
    data = sel_data_all |> dplyr::filter(Run_type == "MAG"),
    aes(
      x = axial_ratio, y = Solidity,
      fill = Sample_ID
    ),
    geom = "polygon", type = "norm",
    level = 0.6, show.legend = T
  ) +
  geom_point(
    data = sel_data_all |> dplyr::filter(Run_type == "PMAG"),
    aes(
      x = axial_ratio, y = Solidity,
      color = Sample_ID,
      shape = Sample_ID
    ),
    stroke = 0.5, size = 3,
  ) +
  scale_color_manual(values = fill_colors_points[1:2]) + # of Data points
  scale_fill_manual(values = fill_colors_ellipse[1:2]) + # of ellipses
  xlim(0,1) + ylim(0,1) +
  guides(color = guide_legend(override.aes = list(fill = NA))) +
  theme_bw() +
  theme(
    legend.position = "top",
    legend.key.size = unit(5, "mm"), # change legend key size
    legend.text = element_text(size = 8),
    legend.title = element_blank(),
    panel.background = element_rect(fill = "white", colour = "black"),
    panel.grid = element_line(colour = "lightgrey"),
    axis.title.x = element_text(vjust = -1, size = 12, face = "bold"),
    axis.title.y = element_text(vjust = 4, size = 12, face = "bold"),
    axis.text = element_text(color = "black", size = 10),
    axis.ticks.length = unit(-0.15, "cm"),
  ) +
  coord_fixed(ratio = 1)

相关问题