【问题标题】:how to set two x axis and two y axis using ggplot2如何使用ggplot2设置两个x轴和两个y轴
【发布时间】:2025-11-06 03:35:02
【问题描述】:

我的数据如下所示:

d <- data.frame(X=c('x1','x2','x3','x1','x2','x3','x1','x2','x3'),
                Y=c('y1','y1','y1','y2','y2','y2','y3','y3','y3'),
                Value=c(1,2,1,3,1,4,3,5,2))

我使用以下代码生成热图:

ggplot(d,aes(x=X,y=Y,fill=Value)) +
  geom_tile() +
  scale_fill_gradient2(low='green',mid='white',high='red',midpoint=3) +
  theme(axis.text.x = element_text(angle = 90),
        axis.text = element_text(size = 10),
        panel.background = element_blank()) +
  labs(x='',y='')

图表是:

但是,我的整个数据大约是 500*500,所以 x 轴和 y 轴上的刻度太多,以至于标签无法清晰识别。但我必须保留所有的价值观。

所以我想使用双 x 轴和双 y 轴。例如,底部的 x 轴只保留标签 x1、x3、x5...,而顶部的 x 轴只保留标签 x2、x4、x6...。然后我对 y 轴做同样的事情。然后,图表如下所示:

我知道 scale_x_continuous 和 sec.axis 可能会这样做。但我的 x 和 y 是离散的。

谁能帮我让图表看起来像第二个?

【问题讨论】:

    标签: r ggplot2 double axis heatmap


    【解决方案1】:

    您是对的,您只能使用带有连续数据的辅助轴。一种解决方案是将 x 和 y 值转换为连续值以进行绘图(只需使用整数序列),但将离散 x 和 y 值保存为向量以用于标记轴。

    在这里,我以一种可以扩展到更大的实际数据集的方式分配连续值。我已经为 x 和 y 制作了关键数据帧,以将每个唯一的离散值与一个整数匹配,然后将这些关键数据帧与您的原始数据帧合并,以便为每个离散 x 和 y 值分配一个可用于绘图的数值。

    #create key dataframes to assign an integer to each x and y value
    key.df.x <- data.frame(X = unique(d$X), x.num = (1:length(unique(d$X))))
    key.df.y <- data.frame(Y = unique(d$Y), y.num = (1:length(unique(d$Y))))
    
    #merge key dataframes with original data
    d <- merge(d, key.df.x, by = "X", all.x = TRUE)
    d <- merge(d, key.df.y, by = "Y", all.x = TRUE)
    
    #make label vectors from original variable names
    xlabels = unique(d$X)
    ylabels = unique(d$Y)
    
    #select odd numbered elements for primary labels, even for secondary labels
    xlabels.primary <- xlabels[seq(1, length(xlabels), by = 2)]
    xlabels.secondary <- xlabels[seq(2, length(xlabels), by = 2)]
    ylabels.primary <- ylabels[seq(1, length(ylabels), by = 2)]
    ylabels.secondary <- ylabels[seq(2, length(ylabels), by = 2)]
    
    ggplot(d,aes(x = x.num, y = y.num,fill=Value)) + #plot using continuous data
      geom_tile() +
      scale_fill_gradient2(low='green',mid='white',high='red',midpoint=3) +
      theme(axis.text.x = element_text(angle = 90),
            axis.text = element_text(size = 10),
            panel.background = element_blank()) +
      # set primary axis breaks to odd numbers, label with ylabels.primary
      scale_y_continuous(breaks = seq(1, max(d$y.num), by = 2), labels = ylabels.primary,
      # set secondary axis breaks to even numbers, label with ylabels.secondary                    
                          sec.axis = dup_axis(breaks = seq(2, max(d$y.num), by = 2),
                                             labels = ylabels.secondary)) +
      scale_x_continuous(breaks = seq(1, max(d$x.num), by = 2), , labels = xlabels.primary,
                         sec.axis = dup_axis(breaks = seq(2, max(d$x.num), by = 2),
                                             labels = xlabels.secondary)) +
      labs(x='',y='')
    

    【讨论】:

    • 这太棒了!非常感谢。
    最近更新 更多