R ggplot // X轴上的多个分组

时间:2016-08-31 09:48:05

标签: r ggplot2 shiny

我正在尝试将图表1从Excel实现为Shiny。到目前为止,我得到的代码包含结果图2

newa = [{'val': 'men', 'locval': {'China':24},'key3': 'bla'},{'val': 'men', 'locval': {'India':56},'key3': 'cheh'}]

我想像在Excel示例中那样对月份和年份进行分组,所以在传奇和年份的第一行中只有月份计数器(“1”,“2”,...)(“2016” “,”2017“,......)在第二个。月数可能会有所不同。

数据集如下:

ggplot(filteredData(), aes(x=interaction(month, year), y=sum)) 
+ geom_bar(stat="identity")  + facet_grid(. ~ X)  + theme(legend.position="none")

2 个答案:

答案 0 :(得分:2)

我略微更改了数据集,这是我得到的最接近你的规格:

df <- read.table(text = "X    year  month  sum
10   2016  1      450
10   2016  2      670
10   2017  1      200
11   2016  1      460
11   2017  2      500", header = T)

# Notice the variable type for month and year
df$month <- as.factor(df$month)
df$year <- as.factor(df$year)
df$X <- as.factor(df$X)

 ggplot(df, aes(x = month, y = sum)) + geom_bar(stat = "identity") + 
  facet_grid(.~X + year,
             switch = "x", # Moves the labels from the top to the bottom
             labeller = label_both # Adds the labels to the year and X variables
             ) + 
  xlab("") # Removes the month label

结果: enter image description here

或者如果你想删除未使用的级别:

ggplot(df, aes(x = month, y = sum)) + geom_bar(stat = "identity") + 
  facet_grid(.~X + year,
             switch = "x", # Moves the labels from the top to the bottom
             labeller = label_both, # Adds the labels to the year and X variables
             scales = "free_x") + 
  xlab("") # Removes the month legend

enter image description here

答案 1 :(得分:2)

You can get a little more complex and use cowplot to merge the plots together. You could automate this using lapply to loop through your unique values, though that is probably overkill for just two groups.

library(ggplot2)
library(cowplot)
library(dplyr)

# Return to default theme, as cowplot sets its own
theme_set(theme_gray())

# Save y limits to get same scale
myYlims <- c(0, ceiling(max(df$sum)/100)*100)


# Generate each plot
x10 <-
  ggplot(df %>%
           filter(X == 10)
         , aes(x = month, y = sum)) + geom_bar(stat = "identity") + 
  facet_grid(~ year,
             switch = "x") +
  panel_border() +
  coord_cartesian(ylim = myYlims) +
  xlab("X = 10")


x11 <-
  ggplot(df %>%
           filter(X == 11)
         , aes(x = month, y = sum)) + geom_bar(stat = "identity") + 
  facet_grid(~ year,
             switch = "x") +
  panel_border() +
  coord_cartesian(ylim = myYlims) +
  xlab("X = 11")


# Put the plots together
plot_grid(x10
          , x11 +
            theme(axis.title.y = element_blank()
                  , axis.text.y = element_blank()
                  , axis.ticks.y = element_blank())
          , rel_widths = c(1.1,1)
          )

enter image description here

Here is an approach to automate this, including more complex data to justify the automation. Note that you will need to play with the aspect ratio of your output and with the rel_widths option to make it look decent:

df <-
  data.frame(
    X = rep(1:6, each = 9)
    , year = rep(rep(2016:2018, each = 3),3)
    , month = rep(1:3, 6)
    , sum = rnorm(9*6, 700, 100)
  )


# Notice the variable type for month and year
df$month <- as.factor(df$month)
df$year <- as.factor(df$year)
df$X <- as.factor(df$X)


# Save y limits to get same scale
myYlims <- c(0, ceiling(max(df$sum)/100)*100)


# Generate each plot
eachPlot <- lapply(levels(df$X), function(thisX){
  ggplot(df %>%
           filter(X == thisX)
         , aes(x = month, y = sum)) +
    geom_bar(stat = "identity") + 
    facet_grid(~ year,
               switch = "x") +
    panel_border() +
    coord_cartesian(ylim = myYlims) +
    xlab(paste("X =", thisX))
})


# Remove axes from all but the first
eachPlot[-1] <- lapply(eachPlot[-1], function(x){
  x +
    theme(axis.title.y = element_blank()
          , axis.text.y = element_blank()
          , axis.ticks.y = element_blank()
    )
})

# Put the plots together
plot_grid(plotlist = eachPlot
          , rel_widths = c(1.4, rep(1, length(eachPlot)-1))
          , nrow = 1
)

enter image description here