How can I crop the data points which lie inside the given polygon?
library(tidyverse)
tbl <- tibble(x = runif(100),
y = runif(100))
ggplot(data = tbl,
aes(x = x,
y = y)) +
geom_point() +
theme_bw() +
coord_equal()
poly <- tibble(A = c(0.5, 0),
B = c(1, 0.5),
C = c(0.5, 1),
D = c(0, 0.5))
One way could be to convert the points and polygon to sf objects, crop the points, then turn the data back into a tibble.
library(sf)
library(tidyverse)
library(gridExtra)
set.seed(345)
tbl <- tibble(x = runif(100),
y = runif(100))
poly <- tibble(
A = c(0.5, 0),
B = c(1, 0.5),
C = c(0.5, 1),
D = c(0, 0.5)
)
# Convert tbl to sf object.
tbl_sf <- sf::st_as_sf(tbl, coords = c("x", "y"))
# Convert polygon to sf polygon.
poly_sf <- as.data.frame(t(poly)) %>%
dplyr::rename(x = V1, y = V2) %>%
sf::st_as_sf(coords = c("x", "y")) %>%
dplyr::summarise() %>%
sf::st_cast("POLYGON") %>%
sf::st_convex_hull()
# Keep only points inside the polygon.
points <- sf::st_intersection(tbl_sf, poly_sf) %>%
# Get coordinates and convert back to tibble.
sf::st_coordinates() %>%
as_tibble() %>%
dplyr::rename(x = X, y = Y)
before <- ggplot(data = tbl,
aes(x = x,
y = y)) +
geom_point() +
theme_bw() +
coord_equal() +
ggtitle("Before")
after <- ggplot(data = points,
aes(x = x,
y = y)) +
geom_point() +
theme_bw() +
coord_equal() +
ggtitle("After")
grid.arrange(before, after, ncol = 2)
Output
I plotted a matrix using geom_tile. Then, I would like to add the track colors below the x-axis. I ran the following code from the similar topic answer (ggplot Adding Tracking Colors Below X-Axis), but it shows the error "Discrete value supplied to continuous scale".
sp <- c("sp1","sp1","sp1","sp2","sp2","sp2","sp3","sp3","sp3","sp4","sp4","sp4","sp5","sp5","sp5")
category <- c("a","b","c","a","b","c","a","b","c","a","b","c","a","b","c")
count <- c(1,2,1,1,4,2,3,1,3,1,4,5,2,5,1)
habitat <- c("A","A","A","B","B","B","C","C","C","A","A","A","B","B","B")
d <- data.frame(cbind(sp, category, count, habitat))
dm <- d %>%
select(sp, category, count)%>%
tidyr::pivot_wider(names_from = "sp", values_from = "count")%>%
replace(is.na(.),0)
dm <- as.matrix(dm[, -1]) # -1 to omit categories from matrix
clust <- hclust(dist(t(dm)), method = "single")
dmc <- data.frame(x = factor(d$sp), colour = factor(d$habitat))
my_fill <- scale_fill_gradient(low="grey90", high="red",
breaks=c(0,5,10,15,20, 25, 30),
rescale=function(x, ...) scales::rescale(x, from=c(0, 30)),
limits=c(0,30))
ggplot(d, aes(category, sp))+
geom_tile(aes(fill = as.numeric(count)))+
my_fill +
scale_y_discrete(limits = colnames(dm)[clust$order])+
geom_tile(data=dmc, aes(x = x, y = 1, fill = colour))
Here is one potential solution:
library(tidyverse)
library(ggpubr)
sp <- c("sp1","sp1","sp1","sp2","sp2","sp2","sp3","sp3","sp3","sp4","sp4","sp4","sp5","sp5","sp5")
category <- c("a","b","c","a","b","c","a","b","c","a","b","c","a","b","c")
count <- c(1,2,1,1,4,2,3,1,3,1,4,5,2,5,1)
habitat <- c("A","A","A","B","B","B","C","C","C","D","D","D","E","E","E")
d <- data.frame(cbind(sp, category, count, habitat))
dm <- d %>%
select(sp, category, count)%>%
tidyr::pivot_wider(names_from = "sp", values_from = "count")%>% #clusterで並び替え
replace(is.na(.),0)
dm <- as.matrix(dm[, -1]) # -1 to omit categories from matrix
clust <- hclust(dist(t(dm)), method = "single")
dmc <- data.frame(x = factor(d$sp), colour = factor(d$sp))
my_fill <- scale_fill_gradient(low="grey90", high="red",
breaks=c(0,5,10,15,20, 25, 30),
rescale=function(x, ...) scales::rescale(x, from=c(0, 30)),
limits=c(0,30))
plot1 <- ggplot(d, aes(category, sp))+
geom_tile(aes(fill = as.numeric(count)))+
my_fill +
scale_y_discrete(limits = colnames(dm)[clust$order]) +
theme(legend.position = "right")
plot2 <- ggplot(dmc) +
geom_tile(aes(x = 1, y = x, fill = colour)) +
theme_void() +
scale_fill_manual(values = viridis::viridis(5)) +
theme(legend.position = "none")
ggarrange(plot2, plot1, nrow = 1, widths = c(0.25, 10), align = "hv")
I have some troubles with my code. I'm very very beginner in R, so I would like some help. I have a dataframe and I need to make an hist chart and then highlight some points. But I cannot understand how to find those points in my dataset. Here is and example of what I have.
x <- c("a","b","c","d","f","g","h","i","j","k")
y <- c(197421,77506,130474,18365,30470,22518,70183,15378,29747,11148)
z <- data.frame(x,y)
hist(z$y)
For example, how can I find in the hist where is the "a" and "h" value placed? and in a barplot? I tried the function points, but I cannot find the coordinates. Please let me know how could I make that . Thanks in advance.
Here is a way with dplyr and ggplot2. The approach is to cut the y variable into bins and then use summarise to create the counts and the labels.
library(dplyr)
library(ggplot2)
z %>%
mutate(bins = cut(y, seq(0, 200000, 50000))) %>%
group_by(bins) %>%
summarise(xes = paste0(x, collapse = ", "),
count = n()) %>%
ggplot() +
geom_bar(aes(x = bins, y = count), stat = "identity", color = "black", fill = "grey") +
geom_text(aes(x = bins, y = count + 0.5, label = xes)) +
xlab("y")
Here is a more complicated way that makes a plot that looks more like what hist() produces.
z2 <- z %>%
mutate(bins = cut(y, seq(0, 200000, 50000))) %>%
group_by(bins) %>%
summarise(xes = paste0(x, collapse = ", "),
count = n()) %>%
separate(bins, into = c("start", "end"), sep = ",") %>%
mutate(across(start:end, ~as.numeric(str_remove(., "\\(|\\]"))))
ggplot() +
geom_histogram(data = z, aes(x = y), breaks = seq(0, 200000, 50000),
color = "black", fill = "grey") +
geom_text(data = z2, aes(x = (start + end) / 2, y = count + 0.5, label = xes))
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)
I'm making a stacked barplot. The width of the bar is set according to variable w.
library(plotly)
library(tidyverse)
df = data.frame(x = c("a","b","c"),
w = c(1.2, 1.3, 4),
y = c(9, 10, 6) )
dat = df %>% mutate(pos = 0.5 * (cumsum(w) + cumsum(c(0, w[-length(w)]))))
g= dat %>% ggplot(aes(x = pos, y = y, fill = x)) +
geom_bar(aes( width = w), stat = "identity") +
scale_x_continuous(labels = df$x, breaks = dat$pos)
ggplotly(g)
The ggplot is fine. But when I tried to convert it to interactive using ggplotly, I got error message as below:
Error in nchar(axisObj$ticktext) : 'nchar()' requires a character vector
Does anyone know why this failed? Thanks.
The Problem is your x-axis scaling.
This should work:
library(plotly)
library(tidyverse)
df = data.frame(x = c("a","b","c"),
w = c(1.2, 1.3, 4),
y = c(9, 10, 6) )
dat = df %>% mutate(pos = 0.5 * (cumsum(w) + cumsum(c(0, w[-length(w)]))))
g= dat %>% ggplot(aes(x = pos, y = y, fill = x)) +
geom_bar(aes(width = w), stat = "identity") +
scale_x_continuous(labels = levels(df$x), breaks = dat$pos)
ggplotly(g)
ggplot seems to keep your x-axis labels as factor-levels which ggplotly doesn't understand.
So you just need to convert them to character.