1

I have a data frame with five columns and five rows. the data frame looks like this:

df <- data.frame(
  day=c("m","t","w","t","f"),
  V1=c(5,10,20,15,20),
  V2=c(0.1,0.2,0.6,0.5,0.8),
  V3=c(120,100,110,120,100),
  V4=c(1,10,6,8,8)
)

I want to do some plots so I used the ggplot and in particular the geom_bar:

ggplot(df, aes(x = day, y = V1, group = 1)) + ylim(0,20)+ geom_bar(stat = "identity")
ggplot(df, aes(x = day, y = V2, group = 1)) + ylim(0,1)+ geom_bar(stat = "identity")
ggplot(df, aes(x = day, y = V3, group = 1)) + ylim(50,200)+ geom_bar(stat = "identity")
ggplot(df, aes(x = day, y = V4, group = 1)) + ylim(0,15)+ geom_bar(stat = "identity")

My question is, How can I do a grouped ggplot with geom_bar with multiple y axis? I want at the x axis the day and for each day I want to plot four bins V1,V2,V3,V4 but with different range and color. Is that possible?

EDIT

I want the y axis to look like this:

multiple axis

ekad
  • 14,436
  • 26
  • 44
  • 46
g.f.l
  • 39
  • 8
  • 1
    Take a look at the `ggplot2` documentation example How to prepare data for plotting: http://stackoverflow.com/documentation/r/1334/ggplot2#t=201607261933589547859. – Alex Jul 26 '16 at 19:34
  • `ggplot2` does not support multiple y-axis as you wanr it. If you want something like that it will be very complicated (http://stackoverflow.com/questions/3099219/plot-with-2-y-axes-one-y-axis-on-the-left-and-another-y-axis-on-the-right). – Alex Jul 26 '16 at 20:01
  • Read the last answer to the question I linked above. This answer is from the writer of the ggplot2 package. – Alex Jul 26 '16 at 20:04
  • Thank you @Alex for the link. You are probably right, it is not possible to do this with ggplot2. Thank you. – g.f.l Jul 26 '16 at 20:07

3 Answers3

1

First I reshaped as described in the documentation in the link below the question. In general ggplot does not support multiple y-axis. I think it is a philosophical thing. But maybe faceting will work for you.

df <- read.table(text =  "day V1 V2 V3 V4 
                          m   5  0.1 120 1
                          t   10 0.2 100 10
                          w   2  0.6 110 6
                          t   15 0.5 120 8
                          f   20 0.8 100 8", header = TRUE)

library(reshape2)
df <- melt(df, id.vars = 'day')

ggplot(df, aes(x = variable, y = value, fill = variable)) + geom_bar(stat = "identity") + facet_grid(.~day)

enter image description here

Alex
  • 4,925
  • 2
  • 32
  • 48
1
require(reshape)
data.m <- melt(df, id.vars='day')
ggplot(data.m, aes(day, value)) +   
  geom_bar(aes(fill = variable), position = "dodge", stat="identity") +
  facet_grid(variable ~ .)

enter image description here

You can also change the y-axis limits if you like (here's an example).

Alternately you may have meant grouped like this:

require(reshape)
data.m <- melt(df, id.vars='day')
ggplot(data.m, aes(day, value)) +   
  geom_bar(aes(fill = variable), position = "dodge", stat="identity")

enter image description here

For the latter examples if you want 2 Y axes then you just create the plot twice (once with a left y axis and once with a right y axis) then use this function:

double_axis_graph <- function(graf1,graf2){
  graf1 <- graf1
  graf2 <- graf2
  gtable1 <- ggplot_gtable(ggplot_build(graf1))
  gtable2 <- ggplot_gtable(ggplot_build(graf2))
  par <- c(subset(gtable1[['layout']], name=='panel', select=t:r))
  graf <- gtable_add_grob(gtable1, gtable2[['grobs']][[which(gtable2[['layout']][['name']]=='panel')]],

                          par['t'],par['l'],par['b'],par['r'])
  ia <- which(gtable2[['layout']][['name']]=='axis-l')
  ga <- gtable2[['grobs']][[ia]]
  ax <- ga[['children']][[2]]
  ax[['widths']] <- rev(ax[['widths']])
  ax[['grobs']] <- rev(ax[['grobs']])
  ax[['grobs']][[1]][['x']] <- ax[['grobs']][[1]][['x']] - unit(1,'npc') + unit(0.15,'cm')
  graf <- gtable_add_cols(graf, gtable2[['widths']][gtable2[['layout']][ia, ][['l']]], length(graf[['widths']])-1)
  graf <- gtable_add_grob(graf, ax, par['t'], length(graf[['widths']])-1, par['b'])

  return(graf)
}

I believe there's also a package or convenience function that does the same thing.

Community
  • 1
  • 1
Hack-R
  • 22,422
  • 14
  • 75
  • 131
1

If I understand correctly you want to include facets in your plot. You have to use reshape2 to get the data in the right format. Here's an example with your data:

df <- data.frame(
  day=c("m","t","w","t","f"),
  V1=c(5,10,20,15,20),
  V2=c(0.1,0.2,0.6,0.5,0.8),
  V3=c(120,100,110,120,100),
  V4=c(1,10,6,8,8)
)

library(reshape2)

df <- melt(df, "day")

Then plot with and include facet_grid argument:

ggplot(df, aes(x=day, y=value)) + geom_bar(stat="identity", aes(fill=variable)) + 
  facet_grid(variable ~ .)

enter image description here

Warner
  • 1,353
  • 9
  • 23