The data is
y0
y1
M
100
200
F
50
250
How to plot the histogram like this? Note that M and F do not block each other, so this is not the case in How to plot two histograms together in R. Thanks in advance.
First, convert your data to long format with pivot_longer().
library(ggplot2)
library(tidyr)
df_long <- pivot_longer(df, cols = c("y0","y1"))
ggplot(data = df_long) +
geom_col(aes(x = name, y = value, fill = sex)) +
scale_fill_manual(values = c("M" = "blue", "F" = "darkorange")) +
theme(legend.position = "bottom")
data:
df <- data.frame(sex = c("M","F"),
y0 = c(100,50),
y1 = c(200,250))
Here's a straight solution:
library(tidyverse)
my_df <- tribble(~ sex, ~ y0, ~ y1,
"M", 100, 200,
"F", 50, 250)
my_df %>%
pivot_longer(starts_with("y")) %>%
ggplot(aes(name, value, fill = sex)) +
geom_col(position = "stack")
If your data is like df below:
library(tidyverse)
df <- tibble::tribble(
~V1, ~y0, ~y1,
"M", 100L, 200L,
"F", 50L, 250L
)
df %>%
pivot_longer(-V1) %>%
ggplot(aes(x = name, y = value, fill = V1)) +
geom_bar(stat = 'identity')
Which gives:
Related
I want to create an interpolated plot of the concentration of 'x' over time at different locations. If possible, I would like to interpolate the points horizontally (i.e. over time) in a way that I get smooth color-changing horizontal lines for each sample.
df<-data.frame(Concentration = rnorm(30), Position = rep(c(0, 1), 15), Sample = rep(c("A", "B"), 15), Date = seq.Date(as.Date("2020-01-01"), as.Date("2020-01-30"), "days"))
df %>%
ggplot(aes(x = Date, y = Position)) +
geom_hline(yintercept = c(0,1),
size = 0.3) +
geom_tile(aes(fill = Concentration),
interpolate = T) +
xlab("Day")+
ylab("Sample")
I would appreciate any suggestions.
Lee
That's exactly what ggforce::geom_link was made for.
library(tidyverse)
library(ggforce)
set.seed(42)
df <- data.frame(Concentration = rnorm(30), Position = rep(c(0, 1), 15), Sample = rep(c("A", "B"), 15), Date = seq.Date(as.Date("2020-01-01"), as.Date("2020-01-30"), "days"))
df %>%
ggplot(aes(x = Date, y = Position)) +
geom_link2(aes(group = Position, color = Concentration), size = 10) +
labs(x = "Day", y = "Sample")
Created on 2021-10-25 by the reprex package (v2.0.1)
Not sure I fully understand the question, but here is one possible solution to what I think you are asking.
library(tidyverse)
library(gt)
df <-
data.frame(Concentration = rnorm(30),
Sample = rep(c("A", "B"), 15),
Date = seq.Date(as.Date("2020-01-01"),
as.Date("2020-01-30"), "days"))
interpolated_df <-
df %>%
arrange(Sample) %>%
complete(Sample, Date) %>%
## interpolated is average of value right before and right after
mutate(Interpolations = (lead(Concentration) +
lag(Concentration))/2 ) %>%
mutate(Final = coalesce(Concentration, Interpolations))
## plot
interpolated_df %>%
ggplot(aes(x = Date, y = Sample)) +
geom_tile(aes(fill = Final)) +
xlab("Day")+
ylab("Sample")
Created on 2021-10-25 by the reprex package (v2.0.1)
Am trying to do a graph but want to order the factor variable based on given values. It seems the plot does not mirror what I want. I would the languages be ordered based on the meanscore. Any ideas?
library(tidyverse)
set.seed(200) # reproducibility
df <- tibble(
language = gl(4, 10, labels = c("Python", "R", "Javascipt", "Excel")),
gender = factor(ifelse(sign(rnorm(40))==-1, 0, 1), labels = c("Male", "Female")),
score = floor(runif(40, 25, 80))
)
df <- df %>% group_by(gender, language) %>%
summarise(meanscore = mean(score))
df %>%
mutate(language = fct_reorder(language, meanscore)) %>%
ggplot(aes(language, meanscore, fill = gender)) +
geom_col() +
facet_wrap(~gender) +
coord_flip()
I believe this is what you want? Utilizing the reorder_within from the package tidytext.
library(tidytext)
set.seed(200)
df <- tibble(
language = gl(4, 10, labels = c("Python", "R", "Javascipt", "Excel")),
gender = factor(ifelse(sign(rnorm(40))==-1, 0, 1), labels = c("Male", "Female")),
score = floor(runif(40, 25, 80))
)
df <- df %>% group_by(gender, language) %>%
summarise(meanscore = mean(score))
ggplot(df, aes(reorder_within(language, meanscore, gender), meanscore, fill = gender)) +
geom_bar(stat = "identity") +
coord_flip() +
scale_x_reordered() +
facet_wrap(gender ~., scales = "free")
I am trying to achieve the attached hand drawn figure using the code below but its showing white spaces for all the years that i do not have data for. Any help would be appreciated.
library(lubridate)
library(tidyverse)
set.seed(123)
D1 <- data.frame(Date = seq(as.Date("2001-07-14"), to= as.Date("2001-07-21"), by="day"),
A = runif(8, 0,10),
D = runif(8,5,15)) %>%
gather(-Date, key = "Variable", value = "Value")
D2 <- data.frame(Date = seq(as.Date("1998-07-14"), to= as.Date("1998-08-30"), by="day"),
A = runif(48, 0,10),
D = runif(48,5,15)) %>%
gather(-Date, key = "Variable", value = "Value")
D <- bind_rows(D1,D2) %>% mutate(Year = year(Date))
my_linetype <- setNames(c("dashed", "solid"), unique(D$Year))
ggplot(data = D, aes(x = Date, y = Value, color = as.factor(Year), linetype = as.factor(Year)))+
geom_line(size = 1.1)+ facet_wrap(~Variable, scales = "free_y", nrow=2)
Desired Out
You can make a dummy Date variable in your data.frame where the year is equal among different groups. In the example below this added in the mutate() statement under the Unyear variable.
D <- bind_rows(D1,D2) %>% mutate(Year = year(Date),
Unyear = {year(Date) <- 0; Date})
my_linetype <- setNames(c("dashed", "solid"), unique(D$Year))
ggplot(data = D, aes(x = Unyear, y = Value, color = as.factor(Year), linetype = as.factor(Year)))+
geom_line(size = 1.1)+ facet_wrap(~Variable, scales = "free_y", nrow=2)
Consider this simple example
library(lubridate)
library(lattice)
library(latticeExtra)
library(tibble)
library(dplyr)
mydf <- tibble(time = c(ymd('2019-01-01'),
ymd('2019-01-02'),
ymd('2019-01-03'),
ymd('2019-01-04'),
ymd('2019-01-05')),
var1 = c(2,2,2,2,1),
var2 = c(2,1,1,4,5),
var3 = c(200, 200, 400, 500, 230))
Now this works
p1 <- mydf %>%
barchart(var1 + var2 ~ time,
data = .,
stack = TRUE,
horiz = FALSE,
par.settings = simpleTheme(col = c('red', 'blue'),
fill = c('red', 'blue'),
alpha = c(0.2)),
auto.key = TRUE)
and this works as well
p2 <- mydf %>%
xyplot(var3 ~ time, data = ., type = 'l')
However, combining them with latticeExtra::doubleYscale() does not work. The line is invisible (see below)
latticeExtra::doubleYScale(p1, p2, use.style = FALSE)
Strangely enough, the dual y scale is there, but the line is missing. Any ideas?
Thanks!!
I simplified your data a bit.
Using as.layer (also from latticeExtra) rather than doubleYScale:
library(lattice)
library(latticeExtra)
mydf <- data.frame(t=1:5,x=c(2,2,2,2,1),
y=c(2,1,1,4,5),z=c(200,200,400,500,230))
p1 <- barchart(x+y~t,mydf,stack=TRUE,horiz=FALSE,
par.settings = simpleTheme(col = c('red', 'blue'),
fill = c('red', 'blue'),
alpha = c(0.2)),
auto.key = TRUE)
p2 <- xyplot(z~t,mydf,type="l")
p1+as.layer(p2,x.same=TRUE,y.same=FALSE,outside=TRUE)
I trust it also works with lubridated objects and tibbles.
EDIT: to clarify as.layer is also in latticeExtra package and add the plot.
Using ggplot2, you could do:
library(tidyr)
library(ggplot2)
df1 <- mydf %>%
select(-var3) %>%
pivot_longer(
cols = c(var1, var2),
names_to = "type",
values_to = "value"
)
df2 <- mydf %>%
select(time, var3)
ggplot(df1) +
geom_col(aes(x = time, y = value, fill = type)) +
geom_line(data = df2, aes(x = time, y = var3/100), size = 2) +
ylab("var1, var2") +
scale_y_continuous(sec.axis = sec_axis(~.*100, name = "var3"))
I have been trying to plot x axes with increasing and the decreasing data values in R
i.e x-axes have values from [60 to 90 to 60], corresponding to different y-values
how can I do this?
This might not be an exact answer but you can use ggplot() and facet_wrap to achieve something similar:
library(ggplot2)
library(dplyr)
library(gridExtra)
# GGPLOT2
x = c(1:50, 50:1)
y = x + rnorm(1000)
group = rep(c("A", "B"), each = 50)
df <- data.frame(x, y, group)
p1 <- df %>%
filter(group == "A") %>%
ggplot(aes(x, y, color = "A")) + geom_point() + ggtitle("UP") + guides(color = F)
p2 <- df %>%
filter(group == "B") %>%
ggplot(aes(x, y, color = "B")) + geom_point() + scale_x_reverse() + ggtitle("DOWN") + guides(color = F)
grid.arrange(p1, p2, nrow = 1)
Recently the plotly package has been receiving a lot of attention. You could do the following using ploy_ly():
# PLOTLY
library(plotly)
p <- df %>%
filter(group == "A") %>%
plot_ly(x = x, y = y, mode = "markers") %>%
layout(xaxis = list(domain = c(0, 0.5)))
p <- df %>%
filter(group == "A") %>%
add_trace(p, x = x, y = y, mode = "markers", xaxis = "x2", yaxis = "y2", data = .) %>%
layout(xaxis2 = list(autorange = "reversed",
domain = c(0.5, 1)),
yaxis2 = list(overlaying = "y",
side = "right"))
p
Is this what you are looking for?
x = c(1,2,3,4,5,6,7,6,5,4,3,2,1)
y = c(4,5,6,7,8,11,12,23,45,25,11,16,2)
ggplot(data.frame(x=1:length(x), y))+
geom_point(aes(x=x, y=y))+
scale_x_discrete(labels = as.character(x))
This will not work so well if x is not in the proper order or has missing values. You should consider adding a MWE along with your attempts in your question.