Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use facet_matrix's labels in aes() #255

Closed
mattansb opened this issue Feb 19, 2022 · 4 comments
Closed

Use facet_matrix's labels in aes() #255

mattansb opened this issue Feb 19, 2022 · 4 comments

Comments

@mattansb
Copy link

I'd like the have shapes vary by the rows of a facet_matrix, is this possible? How does one access the x/y panel ID?

library(ggplot2)
library(ggforce)

ggplot(mtcars) + 
  geom_point(aes(.panel_x, .panel_y)) + 
  facet_matrix(vars(mpg, cyl), vars(am, hp))

# How to have aes(shape = (.panel_x_var == "hp))?
@thomasp85
Copy link
Owner

There is a secret PANEL variable added to all data in R... while it is honestly not meant to be used like this it is there:

ggplot(mtcars) + 
    geom_point(aes(.panel_x, .panel_y, shape = factor(PANEL))) + 
    facet_matrix(vars(mpg, cyl), vars(am, hp))

@thomasp85
Copy link
Owner

With some mathematics you should be able to target each row

@mattansb
Copy link
Author

Oh that is some nice magic.

If anyone ever comes looking here...:

library(ggplot2)
library(ggforce)

p <- ggplot(mtcars) + 
  geom_point(aes(.panel_x, .panel_y)) + 
  facet_matrix(vars(mpg, am, cyl, carb), vars(am, cyl, hp))

factor_to_row <- function(f, nrow) {
  ncol <- max(as.numeric(f)) / nrow
  factor((as.numeric(f) - 1) %/% ncol)
}

factor_to_col <- function(f, ncol) {
  factor((as.numeric(f) - 1) %% ncol)
}

p + aes(shape = factor_to_row(PANEL, 4))
#> Warning in rows == cols: longer object length is not a multiple of shorter
#> object length

p + aes(shape = factor_to_col(PANEL, 3))
#> Warning in rows == cols: longer object length is not a multiple of shorter
#> object length

Created on 2022-08-31 by the reprex package (v2.0.1)

@Pancreas-Pratik
Copy link

Pancreas-Pratik commented Aug 1, 2024

There is a secret PANEL variable added to all data in R... while it is honestly not meant to be used like this it is there:

ggplot(mtcars) + 
    geom_point(aes(.panel_x, .panel_y, shape = factor(PANEL))) + 
    facet_matrix(vars(mpg, cyl), vars(am, hp))

Yes!! This is everything I needed!
I've been struggling how to color specific plots within the plot grid conditionally. This will help me do this!

Please do not ever remove this @thomasp85 🙏🏾 I've been struggling for hours now, and this (factor(PANEL)) was the key I needed!


EDIT: If anyone comes looking for this.... this is how I accomplished my use-case of coloring specific plots' points and trend lines different colors:

Summary
I created a color matrix that matched the ordering of my ggforce facet matrix with the coloring cut-offs I wanted, flattened the color matrix to a vector appropriately to match the order of the coloring sequence, and then with color = factor(PANEL) set within the geom_point(aes()), and geom_smooth(aes()). I applied the output flattened color vector like so: scale_color_manual(values = color_vector). This is how it looks all together with my simulated data:

Code:
Generate simulated data


# Step 1: Generate Simulated Data for 30 genes and 30 cells
set.seed(42)
gene_data <- matrix(rnorm(900), nrow = 30)
gene_data <- as.data.frame(gene_data)
colnames(gene_data) <- paste("Gene", 1:30, sep = "_")
rownames(gene_data) <- paste("Cell", 1:30, sep = "_")

# Step 2: Make some genes have all zeros
set.seed(42)
genes_to_zero <- sample(1:ncol(gene_data), 3)
gene_data[, genes_to_zero] <- 0

# Step 3: Compute the Full Correlation Matrix
correlation_matrix <- cor(gene_data)

correlation_matrix <- correlation_matrix[rowSums(!is.na(correlation_matrix)) > 1, , drop = FALSE]

correlation_matrix <- correlation_matrix[, colSums(!is.na(correlation_matrix)) > 0, drop = FALSE]
subset_matrix <- correlation_matrix 

set.seed(42)
rows_to_na <- sample(1:nrow(subset_matrix), 4)
cols_to_na <- sample(1:ncol(subset_matrix), 7)
subset_matrix[rows_to_na, ] <- NA
subset_matrix[, cols_to_na] <- NA

subset_matrix <- subset_matrix[rowSums(!is.na(subset_matrix)) > 0, , drop = FALSE]

subset_matrix <- subset_matrix[, colSums(!is.na(subset_matrix)) > 0, drop = FALSE]

subset_matrix[!(subset_matrix >= 0.30 | subset_matrix <= -0.30)] <- NA

subset_matrix <- subset_matrix[rowSums(!is.na(subset_matrix)) > 0, , drop = FALSE]

subset_matrix <- subset_matrix[, colSums(!is.na(subset_matrix)) > 0, drop = FALSE]

############

count_matrix_combined <- gene_data
cor_matrix_combined <- subset_matrix

Mapping colors to plots on the facet_matrix

# Step 1: Generate the color matrix based on the correlation values
color_matrix <- matrix("grey", nrow = nrow(cor_matrix_combined), ncol = ncol(cor_matrix_combined))
color_matrix[cor_matrix_combined > 0] <- "red"
color_matrix[cor_matrix_combined < 0] <- "blue"
color_matrix[is.na(cor_matrix_combined)] <- "grey"

# Step 2: Flatten the color matrix into a vector that matches the PANEL order
color_vector <- as.vector(t(color_matrix))  # Use `t()` to transpose so it matches the PANEL sequence

# Step 3: Generate scatter plots using facet_matrix with color mapping
scatter_plot_matrix_ggforce <- ggplot(count_matrix_combined) +
  geom_point(aes(x = .panel_x, y = .panel_y, color = factor(PANEL)), alpha = 0.6) +
  geom_smooth(aes(x = .panel_x, y = .panel_y, color = factor(PANEL)), method = "lm", se = FALSE) +
  facet_matrix(
    rows = vars(rownames(cor_matrix_combined)), 
    cols = vars(colnames(cor_matrix_combined))
  ) +
  scale_color_manual(values = color_vector) +  # Apply the color vector
  theme(
    strip.text = element_text(size = 20, face = "italic"), 
    axis.text = element_text(size = rel(1.25))
  ) + theme(legend.position="none")

Output:

Screenshot 2024-07-31 at 9 58 33 PM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants