ggplot2 version of shepard plot, i.e. vegan::stressplot()? - r

There seems to be quite a bit of information for plotting NMDS outputs (i.e. NMDS1 vs NMDS1) using ggplot2 however I cannot find a way to plot the vegan::stressplot() (shepard's plot) using ggplot2.
Is there a way to produce a ggplot2 version of a metaMDS output?
Reproducible code
library(vegan)
set.seed(2)
community_matrix = matrix(
sample(1:100,300,replace=T),nrow=10,
dimnames=list(paste("community",1:10,sep=""),paste("sp",1:30,sep="")))
example_NMDS=metaMDS(community_matrix, k=2)
stressplot(example_NMDS)
Created on 2021-09-17 by the reprex package (v2.0.1)

Here's a workaround to plot a very similar plot using ggplot2.The trick was to get the structure of the stressplot(example_NMDS) and extract the data stored in that object. I used the tidyverse package that includes ggplot and other packages such as tidyr that contains the pivot_longer function.
library(vegan)
library(tidyverse)
# Analyze the structure of the stressplot
# Notice there's an x, y and yf list
str(stressplot(example_NMDS))
# Create a tibble that contains the data from stressplot
df <- tibble(x = stressplot(example_NMDS)$x,
y = stressplot(example_NMDS)$y,
yf = stressplot(example_NMDS)$yf) %>%
# Change data to long format
pivot_longer(cols = c(y, yf),
names_to = "var")
# Create plot
df %>%
ggplot(aes(x = x,
y = value)) +
# Add points just for y values
geom_point(data = df %>%
filter(var == "y")) +
# Add line just for yf values
geom_step(data = df %>%
filter(var == "yf"),
col = "red",
direction = "vh") +
# Change axis labels
labs(x = "Observed Dissimilarity", y = "Ordination Distance") +
# Add bw theme
theme_bw()

Related

R ggplot and gt outputs - how can I combine these on an output image

In base R I have some code that writes a table of statistics below a chart. I would like to do a similar process with a 'ggplot' chart and a 'gt' table. What is the best way to go about this? My attempt below using gridExtra failed.
# load requried packages
require(tidyverse)
require(gt)
require(gridExtra)
# make a ggplot chart
GGP <- ggplot(dat = iris, aes( x= Sepal.Width, y = Sepal.Length, colour = Species)) + geom_point()
# make a dt statistics table
GT <- gt(iris %>% group_by(Species) %>% summarise(n = n(), Mean = mean(Sepal.Width), SD = sd(Sepal.Width))
# Plot both on one page?
grid.arrange(GGP, GT, nrow = 2)
To combine plots using grid.arrange, both of the objects need to be graphical objects or grobs , and the output from gt isn't. One way is to use tableGrob() from gridExtra to create the grob:
tab = iris %>%
group_by(Species) %>%
summarise(n = n(), Mean = mean(Sepal.Width), SD = sd(Sepal.Width))
grid.arrange(GGP,tableGrob(tab))
An alternative way is to use ggpubr package:
library(tidyverse)
library(ggpubr)
# make a ggplot chart
GGP <- ggplot(dat = iris, aes( x= Sepal.Width, y = Sepal.Length, colour = Species)) + geom_point()
# construct table with desc_statby from ggpubr package
GT <- desc_statby(iris, measure.var = "Sepal.Width",grps = "Species")
GT <- GT[, c("Species", "length", "mean", "sd")]
GT <- ggtexttable(GT, rows = NULL,
theme = ttheme("lBlack"))
grid.arrange(GGP, GT, nrow = 2)

How to reverse x-axis in box-plot [duplicate]

This question already has answers here:
Order Bars in ggplot2 bar graph
(16 answers)
Closed 1 year ago.
People, please can you evaluate my code and give me a hand?
I need to reverse de X-axis of my box-plot, as you can see, the x-axis is the age in Ma, R plot the values in ascending range and I need them in the reverse form (ie 65-64, 64 -63, 63-62, 62-61, 61-60). I tried with scale_y_reverse (), but no good results
Please help me.
Thanks a lot.Box-plot
Install Tidiverse
install.packages("tidyverse")
Open library
library(tidyverse)
Usign qplot
qplot(data =Filogen, x = Filogen$EDAD_1, y = Filogen$AREA_SUR, fill = Filogen$EDAD_1, geom = "boxplot", ylab = 'Área (km²)', xlab = 'Edad (Ma)')
A potential solution is to use the fct_rev() function from the forcats package (part of the tidyverse), for instance, using the example dataset from the palmerpenguins package:
# Load libraries
library(tidyverse)
library(palmerpenguins)
# Create a minimal reproducible example
MRE <- penguins %>%
na.omit()
# Plot the penguins data
qplot(data = MRE, x = species, y = bill_length_mm, fill = species, geom = "boxplot", ylab = 'Área (km²)', xlab = 'Edad (Ma)')
And, using fct_rev():
# Load libraries
library(tidyverse)
library(palmerpenguins)
# Create a minimal reproducible example
MRE <- penguins %>%
na.omit()
# Plot the penguins data
qplot(data = MRE, x = fct_rev(species), y = bill_length_mm, fill = species, geom = "boxplot", ylab = 'Área (km²)', xlab = 'Edad (Ma)')
This solution relies on "species" being a factor. In your dataset, the equivalent variable is "EDAD_1". If "EDAD_1" is not a factor, before you plot the data, change it to a factor:
Filogen$EDAD_1 <- factor(Filogen$EDAD_1)

plotting boolean variable as geom_line

I am fairly new to R and ggplotting. I'm trying to line plot the total of TRUE observations across time, but the counts seem to be capped at 1.00.
dd <- data.frame(x = c(1,1,1,2,2,3,3),
y = c(TRUE,TRUE,TRUE,FALSE,TRUE,TRUE,TRUE))
ggplot(dd,aes(x,as.numeric(y)))+
geom_line()
count(as.numeric(y)) does not work, can you help me?
It is recommended to prepare the statistics before graphing them
library(ggplot2)
library(dplyr)
# summarized the TRUE count for each x value
graph_data <- dd %>%
group_by(x) %>%
summarise(count_y = sum(y))
# plot the data using geom_line
ggplot(data = graph_data) +
geom_line(aes(x, count_y)) +
# added the scale y for start the y-axis from 0
scale_y_continuous(limits = c(0, NA), expand = c(0, 0))
Created on 2021-05-22 by the reprex package (v2.0.0)

how to get geom_point and legend onto line plot in R?

This is my R-script, I've been trying to include a legend onto the line plot but it isn't working? Any guidance? I also can't seem to get the geom_point() working either (I've taken the code for it out below).
library(ggsignif)
library(readxl)
library(svglite)
library(tidyverse)
library(ggplot2)
library(tidyr)
library(dplyr)
url <-'https://static-content.springer.com/esm/art%3A10.1038%2Fs41586-020-2850-3/MediaObjects/41586_2020_2850_MOESM10_ESM.xlsx'
temp <-tempfile()
download.file(url, temp, mode='wb')
myData <- read_excel(path=temp, sheet = "ExFig.5f")
names(myData) <- NULL
view(myData)
Time_post_inj <- (myData[1])
Time_post_inj <- Time_post_inj[-c(1),]
dose_450_ug <- (myData[2])
dose_450_ug <- dose_450_ug[-c(1),]
dose_150_ug <- (myData[4])
dose_150_ug <- dose_150_ug[-c(1),]
dose_100_ug <- (myData[6])
dose_100_ug <- dose_100_ug[-c(1),]
dose_50_ug <- (myData[8])
dose_50_ug <- dose_50_ug[-c(1),]
colnames(Time_post_inj) <-c("Time_Post_Injection")
colnames(dose_450_ug) <-c("dose_450_µg")
colnames(dose_150_ug) <-c("dose_150_µg")
colnames(dose_100_ug) <-c("dose_100_µg")
colnames(dose_50_ug) <-c("dose_50_µg")
Newdata <-data.frame(Time_post_inj, dose_450_ug, dose_150_ug, dose_100_ug, dose_50_ug)
Newdata$Time_Post_Injection <-as.numeric(Newdata$Time_Post_Injection)
Newdata$dose_450_µg <-as.numeric(Newdata$dose_450_µg)
Newdata$dose_150_µg <-as.numeric(Newdata$dose_150_µg)
Newdata$dose_100_µg <-as.numeric(Newdata$dose_100_µg)
Newdata$dose_50_µg <-as.numeric(Newdata$dose_50_µg)
str(Newdata)
ggplot(data=Newdata, aes(x=Time_Post_Injection, y=hCD4_occupancy, group = 1)) + geom_line(aes(y=dose_450_µg)) + geom_line(aes(y=dose_150_µg)) + geom_line(aes(y=dose_100_µg)) + geom_line(aes(y=dose_50_µg))
Newdata
tidyr::pivot_longer(Time_Post_Injection, names_to = "DOSE", values_to = "VALUE") %>%
ggplot2::ggplot(aes(Time_Post_Injection, VALUE, group = DOSE, color = DOSE)) + ggplot2::geom_line()
The following is a full reprex, meaning that if you copy and paste, it will reproduce the plot exactly as below. You can see I have simplified your parsing considerably too; this starts with the url and produces the plot with a lot less data wrangling:
library(ggplot2) # Only load packages you really need
# This format is a handy way of keeping a long string on a single page
url <- paste0("https://static-content.springer.com/esm/art%3A10.",
"1038%2Fs41586-020-2850-3/MediaObjects/41586_2020",
"_2850_MOESM10_ESM.xlsx")
temp <- tempfile()
download.file(url, temp, mode = 'wb')
# Instead of loading an entire library to use one function, we can
# access read_excel by doing readxl::read_excel
myData <- readxl::read_excel(temp, sheet = "ExFig.5f")
# This single line subsets the data frame to chop out the first row
# and the empty columns. It also converts all columns to numeric
NewData <- as.data.frame(lapply(myData[-1, -c(3, 5, 7)], as.numeric))
names(NewData) <-c("Time_Post_Injection", "dose_450_ug",
"dose_150_ug", "dose_100_ug", "dose_50_ug")
# This switches your data to long format, which helps ggplot to work
# We put all the values in one column and have the dosages as labels
# in another column instead of having multiple columns. This allows us
# to map Color to the dosages.
NewData <- cbind(NewData[1], stack(NewData[-1]))
# Now we just tell ggplot to map colours to ind
ggplot(NewData, aes(x = Time_Post_Injection, y = values, color = ind)) +
geom_line() +
geom_point() +
scale_color_discrete(name = "Dose") +
labs(x = "Time Pist Injection") +
theme_bw()
Created on 2020-11-11 by the reprex package (v0.3.0)
Hi the main problem is that you did not get your data into a easy to handle format
library(dplyr)
library(tidyr)
library(ggplot2)
Newdata %>%
# get data in easy to handle format
tidyr::pivot_longer(-Time_Post_Injection, names_to = "DOSE", values_to = "VALUE") %>%
# plot and use the new DOSE column as group and color so you do not need one geom per line! (you can change geom_line() to geom_point also())
ggplot2::ggplot(aes(Time_Post_Injection, VALUE, group = DOSE, color = DOSE)) +
ggplot2::geom_line()

Plot MNIST digits with ggplot2

I want to plot the MNIST digits using ggplot2.
I tried this but I'm getting the numbers rotated 90 degrees. The code below is to plot the 2nd number in the dataset which corresponds to a 2.
trainData = read.csv(file = url("https://drive.google.com/uc?export=download&id=0B4Tqe9kUUfrBSllGY29pWmdGQUE"))
df = expand.grid(y = 0:27, x = 0:27)
df$col = unlist(trainData[2, -c(1,2)])
ggplot(df, aes(x, y)) + geom_tile(aes(fill = col))
If possible, please consider in your solution that I plan expand this to plotting a matrix of numbers using facet_grid or facet_wrap. I want to end with a function that I will pass a vector of rows and the function will get those rows from the dataset and create a matrix of plots (one for each number).
Thanks!
mnist is a build-in dataset in keras package.
Here is one example plot with ggplot2 and tidyverse functions:
To make geom_tile work, we need to transform the data a bit.
library(keras)
library(dplyr)
library(tibble)
library(tidyr)
library(stringr)
mnist <- keras::dataset_mnist()
mnist$test$x[sample(1:100,1), 1:28, 1:28] %>%
as_data_frame() %>%
rownames_to_column(var = 'y') %>%
gather(x, val, V1:V28) %>%
mutate(x = str_replace(x, 'V', '')) %>%
mutate(x = as.numeric(x),
y = as.numeric(y)) %>%
mutate(y = 28-y) %>%
ggplot(aes(x, y))+
geom_tile(aes(fill = val+1))+
coord_fixed()+
theme_void()+
theme(legend.position="none")

Resources