I've tried searching for a solution to this seemingly easy problem, but to no avail. All I'm trying to do is plot a line in ggplot and its standard deviation around the line. However, I keep recovering this error:
Error: Discrete value supplied to continuous scale
My data frame plotdata is as follows:
sites Spoly Spolylower Spolyupper
526.790 0.03018671 0.1196077 0.1196077
1538.512 0.04106053 0.1429613 0.1429613
2540.500 0.02896953 0.1127456 0.1127456
3541.000 0.03560484 0.1200609 0.1200609
4560.143 0.06038193 0.1564464 0.1564464
5569.831 0.03608714 0.1296704 0.1296704
I can plot just the line perfectly fine:
ggplot(data = plotdata, aes(x = "Sites", y = "Mean Values")) +
geom_line(aes(x = sites, y = Spoly), color = "steelblue")
But when I try to add the ribbon, I get the error:
ggplot(data = plotdata, aes(x = "Sites", y = "Mean Values")) +
geom_line(aes(x = sites, y = Spoly), color = "steelblue") +
geom_ribbon(aes(x = sites, ymin = Spolylower, ymax = Spolyupper), alpha = 0.3)
Error: Discrete value supplied to continuous scale
What is going on? What am I doing wrong here?
one option is:
library(ggplot2)
library(cowplot)
data <- "
sites Spoly Spolylower Spolyupper
526.790 0.03018671 0.1196077 0.1196077
1538.512 0.04106053 0.1429613 0.1429613
2540.500 0.02896953 0.1127456 0.1127456
3541.000 0.03560484 0.1200609 0.1200609
4560.143 0.06038193 0.1564464 0.1564464
5569.831 0.03608714 0.1296704 0.1296704
"
dat <- read.table(text = data, header = TRUE)
#change Spolylower value (currently Spolylower= Spolyupper)
dat$Spolylower <- dat$Spolylower - .2
ggplot(data = dat, aes(x = sites, y = Spoly)) +
geom_line(color = "steelblue") +
geom_ribbon(aes(ymin = Spolylower, ymax = Spolyupper), alpha = 0.3) +
theme_cowplot()
I think you should try this:
ggplot(data = plotdata, aes(x = "Sites", y = "Mean Values")) +
geom_line(aes(x = sites, y = Spoly), color = "steelblue") +
geom_ribbon(aes(ymin = plotdata$Spolylower, ymax = plotdata$Spolyupper),fill="dimgray", alpha = 0.1)
let me know if it works
Related
I was wondering how I can scale geom_hex not on count, but rather by a variable and heat scale it? I am also having overfitting in my actual model and was wondering how to eliminate that? Here's an examples:
'''
ggplot(data = diamonds)+
geom_hex(mapping = aes(x = x, y = price, fill = depth, bins =
25))+
scale_fill_continuous(type = "viridis")
'''
Thanks!
I think this will do the trick, assuming you want to colour the hexagons according to the mean of depth...
ggplot(diamonds, aes(x = x, y = price, z = depth)) +
stat_summary_hex(fun = mean, bins = 25) +
scale_fill_continuous(type = "viridis")
I want to shade areas in a ggplot but I don't want to manually tell geom_rect() where to stop and where to start. My data changes and I always want to shade several areas based on a condition.
Here for example with the condition "negative":
library("ggplot2")
set.seed(3)
plotdata <- data.frame(somevalue = rnorm(10), indicator = 0 , counter = 1:10)
plotdata[plotdata$somevalue < 0,]$indicator <- 1
plotdata
I can do that manually like here or here:
plotranges <- data.frame(from = c(1,4,9), to = c(2,4,9))
ggplot() +
geom_line(data = plotdata, aes(x = counter, y = somevalue)) +
geom_rect(data = plotranges, aes(xmin = from - 1, xmax = to, ymin = -Inf, ymax = Inf), alpha = 0.4)
But my problem is that, so to speak, the set.seed() argument changes and I want to still automatically generate the plot without specifying min and max values of the shading manually. Is there a way (maybe without geom_rect() but instead geom_bar()?) to plot shading based directly on my indicator variable?
edit: Here is my own best attempt, as you can see not great:
ggplot(data = plotdata, aes(x = counter, y = somevalue)) + geom_line() +
geom_bar(aes(y = indicator*max(somevalue)), stat= "identity")
You can use stat_summary() to calculate the extremes of runs of your indicator. In the code below data.table::rleid() groups the data by runs of indicators. In the summary layer, y doesn't really do anything, so we use it to store the resolution of your datapoints, which we then later use to offset the xmin/xmax parameters. The after_stat() function is used to access computed variables after the ranges have been computed.
library("ggplot2")
plotdata <- data.frame(somevalue = rnorm(10), counter = 1:10)
plotdata$indicator <- as.numeric(plotdata$somevalue < 0)
ggplot(plotdata, aes(counter, somevalue)) +
stat_summary(
geom = "rect",
aes(group = data.table::rleid(indicator),
xmin = after_stat(xmin - y * 0.5),
xmax = after_stat(xmax + y * 0.5),
alpha = I((indicator) * 0.4),
y = resolution(counter)),
fun.min = min, fun.max = max,
orientation = "y", ymin = -Inf, ymax = Inf
) +
geom_line()
Created on 2021-09-14 by the reprex package (v2.0.1)
I have a task to plot histogram using my data (here) named NoPodsWeight, its density and normal distribution for this segment (min(NoPodsWeight) and max(NoPodsWeight)).
I am trying this:
myframe <- read.csv(filepath, fileEncoding = "UTF-8", stringsAsFactors = FALSE)
myframe <- myframe[rowSums(is.na(myframe)) <= 0,]
nopodsweight <- myframe$NoPodsWeight
height <- myframe$Height
ggplot(myframe, aes(x = NoPodsWeight, y = ..density..)) +
geom_histogram(color="black", fill="white") +
geom_density(color = "blue") +
stat_function(fun = dnorm, args = list(mean = mean(myframe$NoPodsWeight), sd = sd(myframe$NoPodsWeight)))
Using this code I get an error:
Error: Aesthetics must be valid computed stats. Problematic aesthetic(s): y =
..density...
Did you map your stat in the wrong layer?
I don't understand how to plot two or more functions on one plot. For example I can solve my problem using standard plot (but without density):
hist(x = nopodsweight, freq = F, ylim = c(0, 0.45), breaks = 37)
n_norm<-seq(min(nopodsweight)-1, max(nopodsweight)+1, 0.0001)
lines(n_norm, dnorm(n_norm), col = "red")
Is there any function in ggplot to plot (normal) distribution (or maybe using another function) like in lines?
You need to take ..density.. out of the ggplot() layer and put it specifically in the geom_histogram layer. I didn't download and import your data, but here's an example on mtcars:
ggplot(mtcars, aes(x = mpg)) +
geom_histogram(aes(y = ..density..)) +
geom_density(color = "blue") +
stat_function(fun = dnorm, args = list(mean = mean(mtcars$mpg), sd = sd(mtcars$mpg)))
The error message says "did you map your stat in the wrong layer?"; that's a hint. Moving aes(y=..density..) to apply specifically to geom_histogram() seems to make everything OK ...
ggplot(myframe, aes(x = NoPodsWeight)) +
geom_histogram(color="black", fill="white",
aes(y = ..density..)) +
## [... everything else ...]
I'd like to annotate all y-values greater than a y-threshold using ggplot2.
When you plot(lm(y~x)), using the base package, the second graph that pops up automatically is Residuals vs Fitted, the third is qqplot, and the fourth is Scale-location. Each of these automatically label your extreme Y values by listing their corresponding X value as an adjacent annotation. I'm looking for something like this.
What's the best way to achieve this base-default behavior using ggplot2?
Updated scale_size_area() in place of scale_area()
You might be able to take something from this to suit your needs.
library(ggplot2)
#Some data
df <- data.frame(x = round(runif(100), 2), y = round(runif(100), 2))
m1 <- lm(y ~ x, data = df)
df.fortified = fortify(m1)
names(df.fortified) # Names for the variables containing residuals and derived qquantities
# Select extreme values
df.fortified$extreme = ifelse(abs(df.fortified$`.stdresid`) > 1.5, 1, 0)
# Based on examples on page 173 in Wickham's ggplot2 book
plot = ggplot(data = df.fortified, aes(x = x, y = .stdresid)) +
geom_point() +
geom_text(data = df.fortified[df.fortified$extreme == 1, ],
aes(label = x, x = x, y = .stdresid), size = 3, hjust = -.3)
plot
plot1 = ggplot(data = df.fortified, aes(x = .fitted, y = .resid)) +
geom_point() + geom_smooth(se = F)
plot2 = ggplot(data = df.fortified, aes(x = .fitted, y = .resid, size = .cooksd)) +
geom_point() + scale_size_area("Cook's distance") + geom_smooth(se = FALSE, show_guide = FALSE)
library(gridExtra)
grid.arrange(plot1, plot2)
I am creating a plot in ggplot2 with filled densities, a few of which I would like to truncate. I apologize for lack of images--apparently I'm not allowed to post them yet. A simple example of beginning code:
dd = with(density(rnorm(100,0,1)),data.frame(x,y))
ylimit = .3
ggplot(data = dd, mapping = aes(x = x, y = y), geom="line") +
layer(data = dd, mapping = aes(x = x, y = y), geom = "area",
geom_params=list(fill="red",alpha=.3)) +
scale_x_continuous(limits = c(-3,3)) +
scale_y_continuous(limits = c(0,ylimit))
This, however, results in an empty area in the middle of the filled density where dd$y > ylimit.
If I compensate for this with
dd$y = pmin(dd$y, ylimit)
The area is shaded but the plot displays an area slightly higher than ylimit, so the fill does not extend to the top of the graph.
Ideally I would like to know how to get ggplot display a plot exactly up to ylimit, but any other solutions for having the fill extend to the top of the plot would be welcome.
Edit:fixed the code.
I think this is what you meant. Note the use of ifelse to get the truncating behavior.
dd = with(density(rnorm(100,0,1)), data.frame(x, y))
ylimit = .3
dev.new(width=4, height=4)
ggplot(data = dd, mapping = aes(x = x, y = y), geom="line") +
layer(data = dd, mapping = aes(x = x, y = ifelse(y>ylimit, ylimit, y)), geom = "area",
geom_params=list(fill="red",alpha=.3)) +
scale_x_continuous(limits = c(-3,3)) +
coord_cartesian(ylim=c(0, ylimit))