I have my data:
x <- list(10,50,100,250,500,2500)
y <- list(0.09090909,0.01960784,0.003984064,0.003984064,0.001996008,0.0003998401)
I want to link my data to code found on this website
log_c <- seq(-12, 0, by = 0.1)
df <- data.frame(log_c = log_c, response = V(log_c, E, HS, log_EC50))
ggplot(df, aes(log_c, response)) +
geom_line()
I want to put the x data in place of log_c and y data in place of response. These are my beginnings in R, so I am asking for help
At a minimum this will work:
you have expressed your x and y values as lists; it will work better if they are (atomic) vectors (which you would have gotten using c() instead of list()). Put them into a data frame (not strictly necessary, but best practice):
df <- data.frame(x=unlist(x), y = unlist(y))
Use the data frame to draw your plot:
library(ggplot2)
ggplot(df, aes(x, y)) + geom_line()
To get your graph looking a little more like the example in your post,
scalefun <- function(y) (y-min(y))/diff(range(y))
ggplot(df, aes(x, y = scalefun(y))) + geom_line() + scale_x_log10()
Same logic as #Ben Bolker: Just another way:
library(tidyverse)
tibble(x,y) %>%
unnest() %>%
ggplot(aes(x, y))+
geom_line()
Related
I would like to draw a ggplot with a random theme (In fact, I want to draw many plots, each with a different theme). Consider the following reproducible example:
# Exmple data
df <- data.frame(x = 1:10, y = 1:10)
# Select theme randomly
random_theme <<- sample(c("theme_gray", "theme_bw", "theme_light", "theme_dark", "theme_minimal", "theme_classic"), 1)
# Draw ggplot
ggplot(df, aes(x, y)) +
geom_line() +
random_theme # This line does not work
Question: How can I select a ggtheme randomly?
Sample from the functions and not the names of the functions. Also, sample returns a list when sampling from anything more complex than a scalar, so you need the first list element. Eg:
> sample(c(sqrt, sqrt),2)
[[1]]
function (x) .Primitive("sqrt")
[[2]]
function (x) .Primitive("sqrt")
So get a random theme function with:
random_theme <- sample(c(theme_gray, theme_bw, theme_light, theme_dark, theme_minimal, theme_classic), 1)[[1]]
and call it when you plot:
ggplot(df, aes(x, y)) +geom_line() + random_theme()
Resample random_theme and plot again to update.
Also, you probably don't need the <<- which I guess is a hangover from desperately trying to make something work...
You could do this with match.fun():
random_theme = match.fun(sample(c("theme_gray", "theme_bw", "theme_light", "theme_dark", "theme_minimal", "theme_classic"), 1))
ggplot(df, aes(x, y)) +
geom_line() +
random_theme()
Sice your random_theme is a character vector, you can use eval and then parse to parse your theme.
library(tidyverse)
ggplot(df, aes(x, y)) +
geom_line() +
eval(parse(text = paste0(random_theme, "()")))
Or more directly:
ggplot(df, aes(x, y)) +
geom_line() +
eval(parse(text = paste0(sample(c("theme_gray",
"theme_bw",
"theme_light",
"theme_dark",
"theme_minimal",
"theme_classic"), 1) , "()")))
I have a distribution of data that is shown below in image 1. My goal is to show the likelihood that a variable is below a particular value for both X and for Y. For instance, I'd like to have a good way to show that ~95% of values are below 8000 on X-axis and below 6500 on the Y-axis. I am confident that there is a simple answer to this. I apologize if this has been asked many times before.
plot1 <- df %>% ggplot(mapping = aes(x = FLUID_TOT)) + stat_ecdf() + theme_bw()
plot2 <- df %>% ggplot(mapping = aes(x = FLUID_TOT, y = y)) + geom_point() + theme_bw()
I'm creating a frequency plot using ggplot and the stat_ecdf function. I would like to add the Y-value to the graph for specific X-values, but just can't figure out how. geom_point or geom_text seems likely options, but as stat_ecdf automatically calculates Y, I don't know how to call that value in the geom_point/text mappings.
Sample code for my initial plot is:
x = as.data.frame(rnorm(100))
ggplot(x, aes(x)) +
stat_ecdf()
Now how would I add specific y-x points here, e.g. y-value at x = -1.
The easiest way is to create the ecdf function beforehand using ecdf() from the stats package, then plot it using geom_label().
library(ggplot2)
# create a data.frame with column name
x = data.frame(col1 = rnorm(100))
# create ecdf function
e = ecdf(x$col1)
# plot the result
ggplot(x, aes(col1)) +
stat_ecdf() +
geom_label(aes(x = -1, y = e(-1)),
label = e(-1))
You can try
library(tidyverse)
# data
set.seed(123)
df = data.frame(x=rnorm(100))
# Plot
Values <- c(-1,0.5,2)
df %>%
mutate(gr=FALSE) %>%
bind_rows(data.frame(x=Values,gr=TRUE)) %>%
mutate(y=ecdf(x)(x)) %>%
mutate(xmin=min(x)) %>%
ggplot(aes(x, y)) +
stat_ecdf() +
geom_point(data=. %>% filter(gr), aes(x, y)) +
geom_segment(data=. %>% filter(gr),aes(y=y,x=xmin, xend=x,yend=y), color="red")+
geom_segment(data=. %>% filter(gr),aes(y=0,x=x, xend=x,yend=y), color="red") +
ggrepel::geom_label_repel(data=. %>% filter(gr),
aes(x, y, label=paste("x=",round(x,2),"\ny=",round(y,2))))
The idea is to add the y values in the beginning, together with the index gr specifing which Values you want to show.
Edit:
Since this code adds points to the actual data, which could be wrong for the curve, one should consider to remove these points at least in the ecdf function stat_ecdf(data=. %>% filter(!gr))
I have a sequence of points in the x-axis for each of which there are two points in the y-axis.
x<-seq(8.5,10,by=0.1)
y<-c(0.9990276914, 0.9973015358, 0.9931704801, 0.9842176288, 0.9666471511, 0.9354201700, 0.8851624615, 0.8119131899, 0.7152339504, 0.5996777045, 0.4745986612, 0.3519940258, 0.2431610835, 0.1556738744, 0.0919857178, 0.0500000000, 0.0249347645, 0.0113838852, 0.0047497169, 0.0018085048, 0.0006276833)
y1<-c(9.999998e-01,9.999980e-01,9.999847e-01,9.999011e-01,9.994707e-01,9.976528e-01,9.913453e-01, 9.733730e-01, 9.313130e-01, 8.504646e-01, 7.228116e-01, 5.572501e-01,3.808638e-01,2.264990e-01, 1.155286e-01, 5.000000e-02, 1.821625e-02, 5.554031e-03, 1.410980e-03, 2.976926e-04, 5.203069e-05)
I would now like to create two curves in ggplot2. This is quite easy to accomplish in the normal way in R. The result is in the plot below. I am not sure, however, how to do that in ggplot2. For just one curve, I can use
library(ggplot2)
p<-qplot(x,y,geom="line")
Could you please help me generalise the above? Any help is greatly appreciated, thank you.
Note that the lengths of your x and y values don't match. Combine your data and use a grouping variable:
x<-seq(8.5,10, length.out = 21)
DF <- data.frame(x=rep(x, 2), y=c(y, y1), g=c(y^0, y1^0*2))
library(ggplot2)
ggplot(DF, aes(x=x, y=y, colour=factor(g), linetype=factor(g))) +
geom_line()
As #Roland also pointed out first you should fix the length of x. A possible solution using the reshape2 package:
library(reshape2)
library(ggplot2)
x<-seq(8.5,10,length.out = 21)
y<-c(0.9990276914, 0.9973015358, 0.9931704801, 0.9842176288, 0.9666471511, 0.9354201700, 0.8851624615, 0.8119131899, 0.7152339504, 0.5996777045, 0.4745986612, 0.3519940258, 0.2431610835, 0.1556738744, 0.0919857178, 0.0500000000, 0.0249347645, 0.0113838852, 0.0047497169, 0.0018085048, 0.0006276833)
y1<-c(9.999998e-01,9.999980e-01,9.999847e-01,9.999011e-01,9.994707e-01,9.976528e-01,9.913453e-01, 9.733730e-01, 9.313130e-01, 8.504646e-01, 7.228116e-01, 5.572501e-01,3.808638e-01,2.264990e-01, 1.155286e-01, 5.000000e-02, 1.821625e-02, 5.554031e-03, 1.410980e-03, 2.976926e-04, 5.203069e-05)
df <- data.frame(x, y, y1)
df <- melt(df, id.var='x')
ggplot(df, aes(x = x, y = value, color = variable))+geom_line()
EDIT:
Changing the linetype and legend:
g <- ggplot(df, aes(x = x, y = value, color = variable, linetype=variable)) + geom_line()
g <- g + scale_linetype_discrete(name="Custom legend name",
labels=c("Curve1", "Curve2"))
g <- g + guides(color=FALSE)
print(g)
I can get a "filled" geom_line with either geom_ribbon or geom_area. Is there an equivalent for geom_step that doesn't require messing with polygons/barplots or creating the actual step points? Here is some sample data:
library(ggplot2)
set.seed(1)
df <- data.frame(
x=rep(sort(sample(1:20, 5)), 3),
y=ave(runif(15), rep(1:3, each=5), FUN=cumsum),
grp=letters[rep(1:3, each=5)]
)
ggplot(df, aes(x=x, y=y, color=grp)) + geom_step(position="stack")
Which produces:
Basically, I want exactly the same thing, but with filled areas. I know how to do this by actually creating the x/y values required for the steps and using geom_area, but I'm hoping there is something simpler.
Here is the answer I was thinking of, for reference, but I'm hoping for something simpler/built-in if possible:
df2 <- rbind(
df,
transform(df[order(df$x),],
x=x - 1e-9, # required to avoid crazy steps
y=ave(y, grp, FUN=function(z) c(z[[1]], head(z, -1L)))
) )
ggplot(df2, aes(x=x, y=y, fill=grp)) + geom_area()
I know the question is a few years old, but I had the same problem today. For reference here's my solution. It's not more concise than the original answer, but may be easier to understand for some.
library(ggplot2)
library(dplyr)
df <- data.frame(x = seq(10), y = sample(10))
df_areaStep <- bind_rows(old = df,
new = df %>% mutate(y = lag(y)),
.id = "source") %>%
arrange(x, source)
ggplot(df, aes(x,y)) +
geom_ribbon(aes(x = x, ymin = 0, ymax = y), data = df_areaStep)
See this gist for longer version with comments.