Ggplot2 and Geom_Density: How to Remove Baseline

Remove baseline color for geom_histogram

geom_histogram draws its bars using using rectGrob from the grid package, and a zero-width / zero-height rectGrob is depicted as a vertical / horizontal line in the outline colour, at least in my set-up for RStudio (& OP's as well, I presume). Demonstration below:

library(grid)

r1 <- rectGrob(width = unit(0, "npc"), gp = gpar(col = "red", fill = "grey")) # zero-width
r2 <- rectGrob(height = unit(0, "npc"), gp = gpar(col = "red", fill = "grey")) # zero-height

grid.draw(r1) # depicted as a vertical line, rather than disappear completely
grid.draw(r2) # depicted as a horizontal line, rather than disappear completely

demonstration

In this case, if we check the data frame associated with the histogram layer, there are many rows with ymin = ymax = 0, which are responsible for the 'baseline' effect seen in the question.

p <- ggplot(data, aes(x = value)) +
geom_histogram(color = "red") +
facet_wrap(~ key, ncol = 1)

View(layer_data(p) %>% filter(PANEL == 2)) # look at the data associated with facet panel 2

Workaround: Since the data calculations are done in StatBin's compute_group function, we can define an alternative version of the same function, with an additional step to drop the 0-count rows from the data frame completely:

# modified version of StatBin2 inherits from StatBin, except for an
# additional 2nd last line in compute_group() function
StatBin2 <- ggproto(
"StatBin2",
StatBin,
compute_group = function (data, scales, binwidth = NULL, bins = NULL,
center = NULL, boundary = NULL,
closed = c("right", "left"), pad = FALSE,
breaks = NULL, origin = NULL, right = NULL,
drop = NULL, width = NULL) {
if (!is.null(breaks)) {
if (!scales$x$is_discrete()) {
breaks <- scales$x$transform(breaks)
}
bins <- ggplot2:::bin_breaks(breaks, closed)
}
else if (!is.null(binwidth)) {
if (is.function(binwidth)) {
binwidth <- binwidth(data$x)
}
bins <- ggplot2:::bin_breaks_width(scales$x$dimension(), binwidth,
center = center, boundary = boundary,
closed = closed)
}
else {
bins <- ggplot2:::bin_breaks_bins(scales$x$dimension(), bins,
center = center, boundary = boundary,
closed = closed)
}
res <- ggplot2:::bin_vector(data$x, bins, weight = data$weight, pad = pad)

# drop 0-count bins completely before returning the dataframe
res <- res[res$count > 0, ]

res
})

Usage:

ggplot(data, aes(x = value)) +
geom_histogram(color = "red", stat = StatBin2) + # specify stat = StatBin2
facet_wrap(~ key, ncol = 1)

result

How to remove colored line on the x axis with geom_density from ggplot2?

ggplot(...) + stat_density(geom = "line")

The default geom is area, but you can change it to line. The benefit of the default is being able to shade the area (with a fill = aesthetic), rather than outline it.

R / ggplot2 / geom_density: how to use values in cells rather than number of entries

Since you have already calculated the y value, you probably want geom_area not geom_density.

data = as.data.frame(cbind(Gender, as.numeric(Year), as.numeric(Total))) 

ggplot(data, aes(x = Year, y = Total, fill = Gender)) +
geom_area(alpha = .6, position = "identity")

Sample Image

What is the best way to calculate and display peaks of a ggplot2::geom_density() object?

Here is a simple workaround. The idea is to call ggplot_build, let ggplot do the calculations for you and then extract the needed y aesthetic from the resulting object, which is density in your case.

library(ggplot2)
library(ggpmisc)

p <- ggplot(iris, aes(x = Petal.Length)) +
geom_density()

pb <- ggplot_build(p)
p + stat_peaks(
data = pb[['data']][[1]], # take a look at this object
aes(x = x, y = density),
colour = "red",
size = 3
)

Sample Image

I'm sure that this approach can be improved by one of the ggplot2 wizards around that can explain why this is not working...

ggplot(iris, aes(x = Petal.Length, y = stat(density))) +
geom_density() +
stat_peaks()

error: stat_peaks requires the following missing aesthetics: y

... which was my first guess.

Line at the top of a ridgeline density plot is cut off

Adding

scale_y_discrete(expand = c(0.01, 0))

did the trick.



Related Topics



Leave a reply



Submit