Skip to content

Commit e32273a

Browse files
committed
Avoid layering multiple bars when there should be one
1 parent d9ecaf4 commit e32273a

File tree

3 files changed

+230
-3
lines changed

3 files changed

+230
-3
lines changed

R/trace_generation.R

+7-3
Original file line numberDiff line numberDiff line change
@@ -574,11 +574,15 @@ geom2trace <- list(
574574
# Convert days into milliseconds
575575
x <- as.numeric(x) * 24 * 60 * 60 * 1000
576576
}
577-
L <- list(x=x,
578-
y=data$y,
577+
# if there is more than one y-value for a particular combination of
578+
# x, PANEL, and group; then take the _max_ y.
579+
data$x <- x
580+
dat <- plyr::ddply(data, c("x", "PANEL", if("group"%in%names(data))"group"),
581+
plyr::summarise, count = max(y))
582+
L <- list(x=dat$x,
583+
y=dat$count,
579584
type="bar",
580585
name=params$name,
581-
text=data$text,
582586
marker=list(color=toRGB(params$fill)))
583587
if (!is.null(params$colour)) {
584588
L$marker$line <- list(color=toRGB(params$colour))

test-cookbook-bars-and-lines.R

+210
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
df <- data.frame(time = factor(c("Lunch","Dinner"), levels=c("Lunch","Dinner")),
2+
total_bill = c(14.89, 17.23))
3+
# time total_bill
4+
# Lunch 14.89
5+
# Dinner 17.23
6+
7+
# Very basic bar graph
8+
g <- ggplot(data=df, aes(x=time, y=total_bill)) + geom_bar(stat="identity")
9+
save_outputs(g, "bars-and-lines/basic-bar", file_prefix="")
10+
11+
# Map the time of day to different fill colors. These both have the same result.
12+
g <- ggplot(data=df, aes(x=time, y=total_bill, fill=time)) + geom_bar(stat="identity")
13+
save_outputs(g, "bars-and-lines/basic-bar-fill-colors-1", file_prefix="")
14+
g <- ggplot(data=df, aes(x=time, y=total_bill)) + geom_bar(aes(fill=time), stat="identity")
15+
save_outputs(g, "bars-and-lines/basic-bar-fill-colors-2", file_prefix="")
16+
17+
# Add a black outline
18+
g <- ggplot(data=df, aes(x=time, y=total_bill, fill=time)) + geom_bar(colour="black", stat="identity")
19+
save_outputs(g, "bars-and-lines/basic-bar-fill-colors-black-outline", file_prefix="")
20+
21+
# No legend, since the information is redundant
22+
g <- ggplot(data=df, aes(x=time, y=total_bill, fill=time)) +
23+
geom_bar(colour="black", stat="identity") +
24+
guides(fill=FALSE)
25+
save_outputs(g, "bars-and-lines/basic-bar-fill-colors-black-outline-no-legend", file_prefix="")
26+
27+
library(reshape2)
28+
tips
29+
# total_bill tip sex smoker day time size
30+
# 16.99 1.01 Female No Sun Dinner 2
31+
# 10.34 1.66 Male No Sun Dinner 3
32+
# 21.01 3.50 Male No Sun Dinner 3
33+
# ... <244 total rows> ...
34+
# 22.67 2.00 Male Yes Sat Dinner 2
35+
# 17.82 1.75 Male No Sat Dinner 2
36+
# 18.78 3.00 Female No Thur Dinner 2
37+
38+
# Bar graph of counts
39+
g <- ggplot(data=tips, aes(x=day)) + geom_bar(stat="bin")
40+
save_outputs(g, "bars-and-lines/bar-graph-of-counts", file_prefix="")
41+
42+
# Equivalent to this, since stat="bin" is the default:
43+
g <- ggplot(data=tips, aes(x=day)) + geom_bar()
44+
save_outputs(g, "bars-and-lines/bar-graph-of-counts-2", file_prefix="")
45+
46+
# Basic line graph. These both have the same result.
47+
g <- ggplot(data=df, aes(x=time, y=total_bill, group=1)) + geom_line()
48+
save_outputs(g, "bars-and-lines/basic-line", file_prefix="")
49+
g <- ggplot(data=df, aes(x=time, y=total_bill)) + geom_line(aes(group=1))
50+
save_outputs(g, "bars-and-lines/basic-line-2", file_prefix="")
51+
52+
# Add points
53+
g <- ggplot(data=df, aes(x=time, y=total_bill, group=1)) + geom_line() + geom_point()
54+
save_outputs(g, "bars-and-lines/basic-line-with-points", file_prefix="")
55+
56+
57+
58+
59+
60+
61+
62+
63+
64+
65+
66+
67+
68+
69+
70+
# Change color of both line and points
71+
# Change line type and point type, and use thicker line and larger points
72+
# Change points to circles with white fill
73+
g <- ggplot(data=df, aes(x=time, y=total_bill, group=1)) +
74+
geom_line(colour="red", linetype="dotted", size=1.5) +
75+
geom_point(colour="red", size=4, shape=21, fill="white")
76+
save_outputs(g, "bars-and-lines/basic-dashed-line-with-colors", file_prefix="")
77+
78+
79+
80+
81+
82+
83+
84+
85+
# Change the y-range to go from 0 to the maximum value in the total_bill column,
86+
# and change axis labels
87+
g <- ggplot(data=df, aes(x=time, y=total_bill, group=1)) + geom_line() + geom_point() +
88+
ylim(0, max(df$total_bill)) +
89+
xlab("Time of day") + ylab("Total bill") +
90+
ggtitle("Average bill for 2 people")
91+
save_outputs(g, "bars-and-lines/basic-line-fully-styled", file_prefix="")
92+
93+
df1 <- data.frame(sex = factor(c("Female","Female","Male","Male")),
94+
time = factor(c("Lunch","Dinner","Lunch","Dinner"), levels=c("Lunch","Dinner")),
95+
total_bill = c(13.53, 16.81, 16.24, 17.42))
96+
# sex time total_bill
97+
# Female Lunch 13.53
98+
# Female Dinner 16.81
99+
# Male Lunch 16.24
100+
# Male Dinner 17.42
101+
102+
# Stacked bar graph -- this is probably not what you want
103+
g <- ggplot(data=df1, aes(x=time, y=total_bill, fill=sex)) + geom_bar(stat="identity")
104+
save_outputs(g, "bars-and-lines/multi-var-stacked-bar", file_prefix="")
105+
106+
# Bar graph, time on x-axis, color fill grouped by sex -- use position_dodge()
107+
g <- ggplot(data=df1, aes(x=time, y=total_bill, fill=sex)) + geom_bar(stat="identity", position=position_dodge())
108+
save_outputs(g, "bars-and-lines/multi-var-grouped-bar", file_prefix="")
109+
g <- ggplot(data=df1, aes(x=time, y=total_bill, fill=sex)) + geom_bar(stat="identity", position=position_dodge(), colour="black")
110+
save_outputs(g, "bars-and-lines/multi-var-grouped-bar-black-outline", file_prefix="")
111+
112+
# Change colors
113+
g <- ggplot(data=df1, aes(x=time, y=total_bill, fill=sex)) + geom_bar(stat="identity", position=position_dodge(), colour="black") +
114+
scale_fill_manual(values=c("#999999", "#E69F00"))
115+
save_outputs(g, "bars-and-lines/multi-var-grouped-bar-colored", file_prefix="")
116+
117+
# Bar graph, time on x-axis, color fill grouped by sex -- use position_dodge()
118+
g <- ggplot(data=df1, aes(x=sex, y=total_bill, fill=time)) + geom_bar(stat="identity", position=position_dodge(), colour="black")
119+
save_outputs(g, "bars-and-lines/multi-var-grouped-bar-reversed-vars", file_prefix="")
120+
121+
# Basic line graph with points
122+
g <- ggplot(data=df1, aes(x=time, y=total_bill, group=sex)) + geom_line() + geom_point()
123+
save_outputs(g, "bars-and-lines/basic-line-with-points", file_prefix="")
124+
125+
# Map sex to color
126+
g <- ggplot(data=df1, aes(x=time, y=total_bill, group=sex, colour=sex)) + geom_line() + geom_point()
127+
save_outputs(g, "bars-and-lines/basic-line-with-mapped-colors", file_prefix="")
128+
129+
# Map sex to different point shape, and use larger points
130+
g <- ggplot(data=df1, aes(x=time, y=total_bill, group=sex, shape=sex)) + geom_line() + geom_point()
131+
save_outputs(g, "bars-and-lines/basic-line-with-symbols", file_prefix="")
132+
133+
# Use thicker lines and larger points, and hollow white-filled points
134+
g <- ggplot(data=df1, aes(x=time, y=total_bill, group=sex, shape=sex)) +
135+
geom_line(size=1.5) +
136+
geom_point(size=3, fill="white") +
137+
scale_shape_manual(values=c(22,21))
138+
save_outputs(g, "bars-and-lines/basic-line-with-points-fully-styled", file_prefix="")
139+
140+
g <- ggplot(data=df1, aes(x=sex, y=total_bill, group=time, shape=time, color=time)) + geom_line() + geom_point()
141+
save_outputs(g, "bars-and-lines/basic-line-swapped-vars", file_prefix="")
142+
143+
# A bar graph
144+
g <- ggplot(data=df1, aes(x=time, y=total_bill, fill=sex)) +
145+
geom_bar(colour="black", stat="identity",
146+
position=position_dodge(),
147+
size=.3) + # Thinner lines
148+
scale_fill_hue(name="Sex of payer") + # Set legend title
149+
xlab("Time of day") + ylab("Total bill") + # Set axis labels
150+
ggtitle("Average bill for 2 people") + # Set title
151+
theme_bw()
152+
save_outputs(g, "bars-and-lines/finished-bar-bw-theme", file_prefix="")
153+
154+
# A line graph
155+
g <- ggplot(data=df1, aes(x=time, y=total_bill, group=sex, shape=sex, colour=sex)) +
156+
geom_line(aes(linetype=sex), size=1) + # Set linetype by sex
157+
geom_point(size=3, fill="white") + # Use larger points, fill with white
158+
ylim(0, max(df1$total_bill)) + # Set y range
159+
scale_colour_hue(name="Sex of payer", # Set legend title
160+
l=30) + # Use darker colors (lightness=30)
161+
scale_shape_manual(name="Sex of payer",
162+
values=c(22,21)) + # Use points with a fill color
163+
scale_linetype_discrete(name="Sex of payer") +
164+
xlab("Time of day") + ylab("Total bill") + # Set axis labels
165+
ggtitle("Average bill for 2 people") + # Set title
166+
theme_bw() +
167+
theme(legend.position=c(.7, .4)) # Position legend inside
168+
# This must go after theme_bw
169+
save_outputs(g, "bars-and-lines/finished-line", file_prefix="")
170+
171+
dfn <- read.table(header=T, text="
172+
supp dose length
173+
OJ 0.5 13.23
174+
OJ 1.0 22.70
175+
OJ 2.0 26.06
176+
VC 0.5 7.98
177+
VC 1.0 16.77
178+
VC 2.0 26.14
179+
")
180+
181+
g <- ggplot(data=dfn, aes(x=dose, y=length, group=supp, colour=supp)) + geom_line() + geom_point()
182+
save_outputs(g, "bars-and-lines/line-continuous-numerical-x-axis", file_prefix="")
183+
184+
# Copy the data frame and convert dose to a factor
185+
dfn2 <- dfn
186+
dfn2$dose <- factor(dfn2$dose)
187+
g <- ggplot(data=dfn2, aes(x=dose, y=length, group=supp, colour=supp)) + geom_line() + geom_point()
188+
save_outputs(g, "bars-and-lines/line-continuous-categorical-x-axis", file_prefix="")
189+
190+
# Use the original data frame, but put factor() directly in the plot specification
191+
192+
## TODO: Uncomment when Plotly supports this
193+
## g <- ggplot(data=dfn, aes(x=factor(dose), y=length, group=supp, colour=supp)) + geom_line() + geom_point()
194+
## save_outputs(g, "bars-and-lines/line-continuous-categorical-x-axis-with-factor", file_prefix="")
195+
196+
# Use dfn2 from above
197+
g <- ggplot(data=dfn2, aes(x=dose, y=length, fill=supp)) + geom_bar(stat="identity", position=position_dodge())
198+
save_outputs(g, "bars-and-lines/bar-categorical-numerical-labels", file_prefix="")
199+
200+
# Use the original data frame, but put factor() directly in the plot specification
201+
g <- ggplot(data=dfn, aes(x=factor(dose), y=length, fill=supp)) + geom_bar(stat="identity", position=position_dodge())
202+
save_outputs(g, "bars-and-lines/bar-categorical-numerical-labels-with-factor", file_prefix="")
203+
204+
# Add title, narrower bars, gray fill, and change axis labels
205+
g <- ggplot(data=df, aes(x=time, y=total_bill, fill=time)) +
206+
geom_bar(colour="black", fill="#DD8888", width=.7, stat="identity") +
207+
guides(fill=FALSE) +
208+
xlab("Time of day") + ylab("Total bill") +
209+
ggtitle("Average bill for 2 people")
210+
save_outputs(g, "bars-and-lines/basic-bar-fully-styled", file_prefix="")

tests/testthat/test-ggplot-bar.R

+13
Original file line numberDiff line numberDiff line change
@@ -191,3 +191,16 @@ test_that("geom_bar(position = 'fill') stacks proportions", {
191191
expect_identical(prop, 1)
192192
})
193193

194+
d <- head(diamonds, 50)
195+
gbar <- ggplot(d, aes(cut, price)) + geom_bar(stat = "identity")
196+
197+
test_that("For a given x value, if multiple y exist, sum them. ", {
198+
info <- expect_traces(gbar, 1, "category-names")
199+
expect_identical(info$traces[[1]]$type, "bar")
200+
y <- with(d, tapply(price, cut, sum))
201+
# make sure order of counts match
202+
y <- y[info$traces[[1]]$x]
203+
expect_equal(info$traces[[1]]$y, as.numeric(y))
204+
})
205+
206+

0 commit comments

Comments
 (0)