forked from tidyverse/ggplot2
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgeom-bar-.r
149 lines (144 loc) · 6.2 KB
/
geom-bar-.r
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#' Bars, rectangles with bases on x-axis
#'
#' The bar geom is used to produce 1d area plots: bar charts for categorical
#' x, and histograms for continuous y. stat_bin explains the details of
#' these summaries in more detail. In particular, you can use the
#' \code{weight} aesthetic to create weighted histograms and barcharts where
#' the height of the bar no longer represent a count of observations, but a
#' sum over some other variable. See the examples for a practical
#' example.
#'
#' The heights of the bars commonly represent one of two things: either a
#' count of cases in each group, or the values in a column of the data frame.
#' By default, \code{geom_bar} uses \code{stat="bin"}. This makes the height
#' of each bar equal to the number of cases in each group, and it is
#' incompatible with mapping values to the \code{y} aesthetic. If you want
#' the heights of the bars to represent values in the data, use
#' \code{stat="identity"} and map a value to the \code{y} aesthetic.
#'
#' By default, multiple x's occuring in the same place will be stacked a top
#' one another by position_stack. If you want them to be dodged from
#' side-to-side, see \code{\link{position_dodge}}. Finally,
#' \code{\link{position_fill}} shows relative propotions at each x by stacking
#' the bars and then stretching or squashing to the same height.
#'
#' Sometimes, bar charts are used not as a distributional summary, but
#' instead of a dotplot. Generally, it's preferable to use a dotplot (see
#' \code{geom_point}) as it has a better data-ink ratio. However, if you do
#' want to create this type of plot, you can set y to the value you have
#' calculated, and use \code{stat='identity'}
#'
#' A bar chart maps the height of the bar to a variable, and so the base of
#' the bar must always been shown to produce a valid visual comparison.
#' Naomi Robbins has a nice
#' \href{http://www.b-eye-network.com/view/index.php?cid=2468}{article on this topic}.
#' This is the reason it doesn't make sense to use a log-scaled y axis with a bar chart
#'
#' @section Aesthetics:
#' \Sexpr[results=rd,stage=build]{ggplot2:::rd_aesthetics("geom", "bar")}
#'
#' @seealso \code{\link{stat_bin}} for more details of the binning alogirithm,
#' \code{\link{position_dodge}} for creating side-by-side barcharts,
#' \code{\link{position_stack}} for more info on stacking,
#' @export
#' @inheritParams geom_point
#' @examples
#' \donttest{
#' # Generate data
#' c <- ggplot(mtcars, aes(factor(cyl)))
#'
#' # By default, uses stat="bin", which gives the count in each category
#' c + geom_bar()
#' c + geom_bar(width=.5)
#' c + geom_bar() + coord_flip()
#' c + geom_bar(fill="white", colour="darkgreen")
#'
#' # Use qplot
#' qplot(factor(cyl), data=mtcars, geom="bar")
#' qplot(factor(cyl), data=mtcars, geom="bar", fill=factor(cyl))
#'
#' # When the data contains y values in a column, use stat="identity"
#' library(plyr)
#' # Calculate the mean mpg for each level of cyl
#' mm <- ddply(mtcars, "cyl", summarise, mmpg = mean(mpg))
#' ggplot(mm, aes(x = factor(cyl), y = mmpg)) + geom_bar(stat = "identity")
#'
#' # Stacked bar charts
#' qplot(factor(cyl), data=mtcars, geom="bar", fill=factor(vs))
#' qplot(factor(cyl), data=mtcars, geom="bar", fill=factor(gear))
#'
#' # Stacked bar charts are easy in ggplot2, but not effective visually,
#' # particularly when there are many different things being stacked
#' ggplot(diamonds, aes(clarity, fill=cut)) + geom_bar()
#' ggplot(diamonds, aes(color, fill=cut)) + geom_bar() + coord_flip()
#'
#' # Faceting is a good alternative:
#' ggplot(diamonds, aes(clarity)) + geom_bar() +
#' facet_wrap(~ cut)
#' # If the x axis is ordered, using a line instead of bars is another
#' # possibility:
#' ggplot(diamonds, aes(clarity)) +
#' geom_freqpoly(aes(group = cut, colour = cut))
#'
#' # Dodged bar charts
#' ggplot(diamonds, aes(clarity, fill=cut)) + geom_bar(position="dodge")
#' # compare with
#' ggplot(diamonds, aes(cut, fill=cut)) + geom_bar() +
#' facet_grid(. ~ clarity)
#'
#' # But again, probably better to use frequency polygons instead:
#' ggplot(diamonds, aes(clarity, colour=cut)) +
#' geom_freqpoly(aes(group = cut))
#'
#' # Often we don't want the height of the bar to represent the
#' # count of observations, but the sum of some other variable.
#' # For example, the following plot shows the number of diamonds
#' # of each colour
#' qplot(color, data=diamonds, geom="bar")
#' # If, however, we want to see the total number of carats in each colour
#' # we need to weight by the carat variable
#' qplot(color, data=diamonds, geom="bar", weight=carat, ylab="carat")
#'
#' # A bar chart used to display means
#' meanprice <- tapply(diamonds$price, diamonds$cut, mean)
#' cut <- factor(levels(diamonds$cut), levels = levels(diamonds$cut))
#' qplot(cut, meanprice)
#' qplot(cut, meanprice, geom="bar", stat="identity")
#' qplot(cut, meanprice, geom="bar", stat="identity", fill = I("grey50"))
#'
#' # Another stacked bar chart example
#' k <- ggplot(mpg, aes(manufacturer, fill=class))
#' k + geom_bar()
#' # Use scales to change aesthetics defaults
#' k + geom_bar() + scale_fill_brewer()
#' k + geom_bar() + scale_fill_grey()
#'
#' # To change plot order of class varible
#' # use factor() to change order of levels
#' mpg$class <- factor(mpg$class, levels = c("midsize", "minivan",
#' "suv", "compact", "2seater", "subcompact", "pickup"))
#' m <- ggplot(mpg, aes(manufacturer, fill=class))
#' m + geom_bar()
#' }
geom_bar <- function (mapping = NULL, data = NULL, stat = "bin", position = "stack", ...) {
GeomBar$new(mapping = mapping, data = data, stat = stat, position = position, ...)
}
GeomBar <- proto(Geom, {
objname <- "bar"
default_stat <- function(.) StatBin
default_pos <- function(.) PositionStack
default_aes <- function(.) aes(colour=NA, fill="grey20", size=0.5, linetype=1, weight = 1, alpha = NA)
required_aes <- c("x")
reparameterise <- function(., df, params) {
df$width <- df$width %||%
params$width %||% (resolution(df$x, FALSE) * 0.9)
transform(df,
ymin = pmin(y, 0), ymax = pmax(y, 0),
xmin = x - width / 2, xmax = x + width / 2, width = NULL
)
}
draw_groups <- function(., data, scales, coordinates, ...) {
GeomRect$draw_groups(data, scales, coordinates, ...)
}
guide_geom <- function(.) "polygon"
})