Insert Layer underneath existing layers in ggplot2 object
Thanks @baptiste for pointing me in the right direction. To insert a layer underneath all other layers, just modify the layers
element of the plot object.
## For example:
P$layers <- c(geom_boxplot(), P$layers)
Answer to the Bonus Question:
This handy little function inserts a layer at a designated z-level:
insertLayer <- function(P, after=0, ...) {
# P : Plot object
# after : Position where to insert new layers, relative to existing layers
# ... : additional layers, separated by commas (,) instead of plus sign (+)
if (after < 0)
after <- after + length(P$layers)
if (!length(P$layers))
P$layers <- list(...)
else
P$layers <- append(P$layers, list(...), after)
return(P)
}
Animate the process of adding layers to a ggplot2 plot
You can manually add a frame
aesthetic to each layer, though it will include the legends for all of the frames immediately (Intentionally, I believe, to keep ratios/margins, etc. correct:
saveAnimate <-
ggplot(mtcars, aes(x = hp, y = mpg)) +
# frame 1
geom_point(aes(frame = 1)) +
# frame 2
geom_point(aes(color = factor(cyl)
, frame = 2)
) +
# frame 3
geom_point(aes(color = factor(cyl), size = wt
, frame = 3)) +
# frame 4
geom_point(aes(color = factor(cyl), size = wt
, frame = 4)) +
# I don't think I can add this one
labs(title = "MTCARS")
gg_animate(saveAnimate)
If you want to be able to add things yourself, and even see how legends, titles, etc. move things around, you may need to step back to a lower-level package, and construct the images yourself. Here, I am using the animation
package which allows you to loop through a series of plots, with no limitations (they need not be related at all, so can certainly show things moving the plot area around. Note that I believe this requires ImageMagick to be installed on your computer.
p <- ggplot(mtcars, aes(x = hp, y = mpg))
toSave <- list(
p + geom_point()
, p + geom_point(aes(color = factor(cyl)))
, p + geom_point(aes(color = factor(cyl), size = wt))
, p + geom_point(aes(color = factor(cyl), size = wt)) +
labs(title = "MTCARS")
)
library(animation)
saveGIF(
{lapply(toSave, print)}
, "animationTest.gif"
)
if else condition in ggplot to add an extra layer
What you are seeing is a syntax error. The most robust way I can think of is:
tmp.data<-c(1,2,3)
if(tmp.data[1]!="no value") {
p = p + geom_point()
}
p + geom_line()
So you compose the object p
in a sequence, only adding geom_point()
when the if statements yields TRUE
.
adding multiple layers to a ggplot with a function
From help("+.gg")
:
You can also supply a list, in which case each element of the list will be added in turn.
add_points <- function(x) {
list(geom_point(aes(x = x - 1, y = 0), color = "red"),
geom_point(aes(x = x + 1, y = 0), color = "red"))
}
p + add_points(x = 0)
#works
multiple layer with ggplot in R
This is the max I can produce so far. I have problems to plot density of P.S_tc
as a layer because the x axis of a density plot is the variable itself: so in your case Date
(desired x axis) competes with P.S_tc
:
library(ggplot2)
library(hrbrthemes)
# Value used to transform the data
coeff <- 10000
# constants
CloseColor <- "#69b3a2"
P.S_EWColor <- rgb(0.2, 0.6, 0.9, 1)
p <- ggplot(example, aes(x=Date)) +
geom_line( aes(y=Close), size=1, color=CloseColor) +
geom_line( aes(y=P.S_EW * coeff), size=1, color=P.S_EWColor) +
scale_y_continuous(
# Features of the first axis
name = "Close",
# Add a second axis and specify its features
sec.axis = sec_axis(~.*coeff, name="P.S_EW ($)")
) +
theme_ipsum() +
theme(
axis.title.y = element_text(color = CloseColor, size=13),
axis.title.y.right = element_text(color = P.S_EWColor, size=13)
) +
ggtitle("Close, P.S_EW")
Adding points from other dataset to ggplot2
The issue is that you are assigning fill = factor(colorname)
for the whole plot in your qplot
call.
So testplot2
will also try to map colorname
to the fill
aesthetic but there is no colorname
column in the pointdata
data.frame which is why you have this error message. If you rewrite it using ggplot
, it looks like this :
ggplot(bardata, aes(xname, yvalue, fill = factor(colorname))) +
geom_bar(stat = "identity")+
geom_point(data = pointdata,
mapping = aes(x = xname, y = ypos, shape = factor(ptyname)))
What you need to do is to apply the mapping only to the geom_bar
call, like this :
ggplot(bardata, aes(xname, yvalue)) +
geom_bar(stat = "identity", aes(fill = factor(colorname)))+
geom_point(data = pointdata,
mapping = aes(x = xname, y = ypos, shape = factor(ptyname)))
Related Topics
Fill Missing Values Rowwise (Right/Left)
R - Stuck with Plot() - Colouring Shapefile Polygons Based Upon a Slot Value
R: Why Does Strptime Always Return Na When I Try to Format a Date String
Function to Change Blanks to Na
Meaning of Error Using . Shorthand Inside Dplyr Function
How to Show Directlabels After Geom_Smooth and Not After Geom_Line
How to Use Stat_Function by Group
Disable Gui, Graphics Devices in R
How to Suppress R Startup Message
Combining Pipes and The Magrittr Dot (.) Placeholder
Find Match of Two Data Frames and Rewrite The Answer as Data Frame
Tidyr Separate Column Values into Character and Numeric Using Regex
Terminating an Apply-Based Function Early (Similar to Break)
Find Max Per Group and Return Another Column
Assigning/Referencing a Column Name in Data.Table Dynamically (In I, J and By)