-
Notifications
You must be signed in to change notification settings - Fork 633
geom_smooth() #183
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
geom_smooth() #183
Changes from 9 commits
b0ca230
9b5bbf3
a5da68d
edf669a
30813df
91e6e3d
2378655
7a3430c
4ac88f0
cbe301b
a97ba2b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
Package: plotly | ||
Type: Package | ||
Title: Interactive, publication-quality graphs online. | ||
Version: 0.5.24 | ||
Version: 0.5.25 | ||
Authors@R: c(person("Chris", "Parmer", role = c("aut", "cre"), | ||
email = "[email protected]"), | ||
person("Scott", "Chamberlain", role = "aut", | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -217,8 +217,24 @@ gg2list <- function(p){ | |
} | ||
|
||
# This extracts essential info for this geom/layer. | ||
traces <- layer2traces(L, df, misc) | ||
|
||
if (L$geom$objname == "smooth") { | ||
# smooth is really a line + ribbon geom | ||
# draw ribbon (unless se = FALSE) | ||
misc$smoothRibbon <- TRUE | ||
trace1 <- if (isTRUE(L$stat_params$se == FALSE)) { | ||
NULL | ||
} else { | ||
layer2traces(L, df, misc) | ||
} | ||
misc$smoothRibbon <- FALSE | ||
# always draw the line | ||
misc$smoothLine <- TRUE | ||
trace2 <- layer2traces(L, df, misc) | ||
trace2 <- lapply(trace2, function(x) { x$showlegend <- FALSE; x }) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it is confusing to use lapply with an anonymous function here where you could have used a for loop. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @tdhock What?! I would say that, in R, you want to use *ply functions (in order to avoid for loops) as much as possible!! |
||
traces <- c(trace1, trace2) | ||
} else { | ||
traces <- layer2traces(L, df, misc) | ||
} | ||
possible.legends <- markLegends[[L$geom$objname]] | ||
actual.legends <- possible.legends[possible.legends %in% names(L$mapping)] | ||
layer.legends[[paste(i)]] <- actual.legends | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
set.seed(955) | ||
# Make some noisily increasing data | ||
dat <- data.frame(cond = rep(c("A", "B"), each=10), | ||
xvar = c(1.475957, -3.423712, 1.966129, 5.575364, 2.954719, 2.768286, 3.507499, 6.945000, 12.135050, 10.231673, 13.040393, 12.231689, 13.506993, 13.590874, 15.455178, 28.431185, 17.758937, 24.730797, 22.954238, 21.122766), | ||
yvar = c(-1.315387, 3.323239, 4.452183, 4.597885, 5.697203, 5.991221, 5.764561, 10.163165, 14.805634, 11.447913, 12.163597, 10.930851, 13.491366, 11.800783, 19.246991, 13.870457, 11.031923, 22.700302, 24.877547, 22.520114)) | ||
# cond xvar yvar | ||
# A -4.252354091 3.473157275 | ||
# A 1.702317971 0.005939612 | ||
# ... | ||
# B 17.793359218 19.718587761 | ||
# B 19.319909163 19.647899863 | ||
|
||
g <- ggplot(dat, aes(x=xvar, y=yvar)) + | ||
geom_point(shape=1) # Use hollow circles | ||
save_outputs(g, "scatterplots-hollow") | ||
|
||
g <- ggplot(dat, aes(x=xvar, y=yvar)) + | ||
geom_point(shape=1) + | ||
geom_smooth(method=lm) # Add linear regression line | ||
save_outputs(g, "scatterplots-smooth-lm") | ||
|
||
g <- ggplot(dat, aes(x=xvar, y=yvar)) + | ||
geom_point(shape=1) + | ||
geom_smooth(method=lm, se=FALSE) # Don't add shaded confidence region | ||
save_outputs(g, "scatterplots-smooth-lm-se-false") | ||
|
||
|
||
g <- ggplot(dat, aes(x=xvar, y=yvar)) + | ||
geom_point(shape=1) + # Use hollow circles | ||
geom_smooth() # Add a loess smoothed fit curve with confidence region | ||
save_outputs(g, "scatterplots-loess") | ||
|
||
# Set color by cond | ||
g <- ggplot(dat, aes(x=xvar, y=yvar, color=cond)) + geom_point(shape=1) | ||
save_outputs(g, "scatterplots-color") | ||
|
||
# # Same, but with different colors and add regression lines | ||
g <- ggplot(dat, aes(x=xvar, y=yvar, color=cond)) + geom_point(shape=1) + | ||
scale_colour_hue(l=50) + # Use a slightly darker palette than normal | ||
geom_smooth(method=lm, se=FALSE) | ||
save_outputs(g, "scatterplots-scale-color-hue") | ||
|
||
# Extend the regression lines beyond the domain of the data | ||
g <- ggplot(dat, aes(x=xvar, y=yvar, color=cond)) + geom_point(shape=1) + | ||
scale_colour_hue(l=50) + | ||
geom_smooth(method=lm, se=FALSE, fullrange=T) | ||
save_outputs(g, "scatterplots-full-range") | ||
|
||
# Set shape by cond | ||
g <- ggplot(dat, aes(x=xvar, y=yvar, shape=cond)) + geom_point() | ||
save_outputs(g, "scatterplots-shape") | ||
|
||
# Same, but with different shapes | ||
g <- ggplot(dat, aes(x=xvar, y=yvar, shape=cond)) + geom_point() + | ||
scale_shape_manual(values=c(1,2)) # Use a hollow circle and triangle | ||
save_outputs(g, "scatterplots-shape-manual") | ||
|
||
# Round xvar and yvar to the nearest 5 | ||
dat$xrnd <- round(dat$xvar/5)*5 | ||
dat$yrnd <- round(dat$yvar/5)*5 | ||
|
||
# Make each dot partially transparent, with 1/4 opacity | ||
# For heavy overplotting, try using smaller values | ||
g <- ggplot(dat, aes(x=xrnd, y=yrnd)) + | ||
geom_point(shape=19, # Use solid circles | ||
alpha=1/4) # 1/4 opacity | ||
save_outputs(g, "scatterplots-overlap") | ||
|
||
# Jitter the points | ||
# Jitter range is 1 on the x-axis, .5 on the y-axis | ||
g <- ggplot(dat, aes(x=xrnd, y=yrnd)) + | ||
geom_point(shape=1, # Use hollow circles | ||
position=position_jitter(width=1,height=.5)) | ||
save_outputs(g, "scatterplots-jitter") |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
context("smooth") | ||
|
||
p <- ggplot(mtcars, aes(mpg, wt)) + geom_point() + geom_smooth() | ||
|
||
test_that("geom_point() + geom_smooth() produces 3 traces", { | ||
info <- gg2list(p) | ||
expect_true(sum(names(info) == "") == 3) | ||
save_outputs(p, "smooth") | ||
}) | ||
|
||
p2 <- ggplot(mtcars, aes(mpg, wt)) + geom_point() + geom_smooth(se = FALSE) | ||
|
||
test_that("geom_point() + geom_smooth(se = FALSE) produces 2 traces", { | ||
info2 <- gg2list(p2) | ||
expect_true(sum(names(info2) == "") == 2) | ||
save_outputs(p2, "smooth-se-false") | ||
}) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this geom_smooth-dependent code should be moved inside of trace_generation.R. Is there some reason why you did not put it there with the other geom-specific code?
Can't you add a smooth= function to the toBasic list? https://github.com/ropensci/plotly/blob/master/R/trace_generation.R#L290-L382
Or add a smooth= function to the geom2trace list? https://github.com/ropensci/plotly/blob/master/R/trace_generation.R#L438
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code in trace_generation.R seems to assume a layer consists of one geom (is that right?), but a
geom_smooth()
is reallygeom_path() + geom_ribbon()
. I suppose I could addsmooth
(instead ofsmoothRibbon
&smoothLine
) to these lists, but the downside is that we essentially have to copy/paste overribbon
andline
into this spot (so, if we happen to fix/changeribbon
orline
, those changes won't propagate tosmooth
). Would you prefer to take this approach instead? Or maybe there is a better way?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well actually the approach with smoothRibbon and smoothLine is fine with me, but I just think it will be easier to maintain in the future if we put all the geom-specific code inside of layer2traces (rather than being inside of gg2list as it is now).