cc-spatial-trajectory-screening.Rmd
With spatial trajectory analysis SPATA2 introduces a new approach to find, analyze and visualize differently expressed genes in a spatial context. While the classic differential gene expression analyzes differences between groups as a whole it neglects changes of expression levels that can only be observed while maintaining the spatial dimensions. Spatial trajectories allow to answer questions that include such a spatial component. In how far do expression levels change the more one moves towards a region of interest or away from it? Which genes follow the same pattern along these paths?
The spatial trajectory screening algorithm can be divided in three parts.
This vignette explains all steps of part 1.) and 2.) of the algorithm. Part 3.) is explained in the tutorial on Model Fitting in Spatial Transcriptomic Studies.
As an example we are using a spatial transcriptomic sample of a central nervous system malignancy that features three different, adjacent histological areas: Tumor, a transition zone as well as infiltrated cortex.
library(SPATA2)
library(SPATAData)
library(tidyverse)
object_t269 <- downloadSpataObject(sample_name = "269_T")
# load example image annotations
data("image_annotations")
object_t269 <-
setImageAnnotations(
object = object_t269,
img_anns = image_annotations[["269_T"]],
overwrite = TRUE
)
# plot results
plotImageGgplot(object = object_t269) +
ggpLayerFrameByCoords(object = object_t269) +
ggpLayerThemeCoords()
plotImageAnnotations(
object = object_t269,
tags = "hist_example",
square = TRUE,
expand = 0.5,
encircle = FALSE,
nrow = 2,
display_caption = FALSE
)
The example spatial trajectory that we are using throughout this
vignette was drawn via the function addSpatialTrajectory()
and is displayed in figure 1.1. It shows a surface plot that is colored
by the expression of gene MPL. Next to it the example
trajectory is visualized which runs across the whole sample indicating a
from tumor to cortex-direction.
# creates trajectory manually
# alternatively you can draw it interactively with `createSpatialTrajectories()`
object_t269 <-
addSpatialTrajectory(
object = object_t269,
id = "horizontal_mid",
width = "1.5mm",
start = c(x = "1.35mm", y = "4mm"),
end = c(x = "6.35mm", y = "4mm"),
overwrite = TRUE
)
plotSurface(object = object_t269, color_by = "MAG")
plotSpatialTrajectories(object = object_t269, ids = "horizontal_mid", color_by = "MAG")
Both functions, createSpatialTrajectories()
and
addSpatialTrajectory()
result in the same. They set
up spatial trajectories by doing the necessary computations and by
storing the results in the spata2
object.
createSpatialTrajectories()
gives access to an interactive
interface where start- and endpoint are set by clicking on the plot.
With addSpatialTrajectory()
start- and endpoint are set
programmatically.
The process of setting up a trajectory can be splitted into three steps:
The chapters below elaborate on each of these three steps and shows
the underlying code that is needed to reproduce what is happening in the
functions createSpatialTrajectories()
or
addSpatialTrajectory()
.
In order to draw the trajectory a surface plot is required.
Extracting the coordinates of all barcode-spots via
getCoordinates()
provides the basic data.frame needed.
# get coordinate of barcode-spots
coords_df <- getCoordsDf(object = object_t269)
# show results
coords_df
## # A tibble: 3,213 x 6
## barcodes sample x y section outline
## <chr> <chr> <dbl> <dbl> <chr> <lgl>
## 1 AAACAAGTATCTCCCA-1 269_T 1450. 731. 1 FALSE
## 2 AAACACCAATAACTGC-1 269_T 411. 547. 1 FALSE
## 3 AAACAGAGCGACTCCT-1 269_T 1359. 1516 1 FALSE
## 4 AAACATTTCCCGGATT-1 269_T 1386. 493. 1 FALSE
## 5 AAACCCGAACGAAATC-1 269_T 1614. 838. 1 FALSE
## 6 AAACCGGGTAGGTACC-1 269_T 527. 916. 1 FALSE
## 7 AAACCGTTCGTCCAGG-1 269_T 700. 696 1 FALSE
## 8 AAACCTAAGCAGCCGG-1 269_T 1210. 408. 1 FALSE
## 9 AAACCTCATGAAGTTG-1 269_T 416. 1026. 1 FALSE
## 10 AAACGAGACGGTTGAT-1 269_T 1167. 1061. 1 FALSE
## # i 3,203 more rows
The start- and endpoint of the trajectory are determined and stored in a data.frame like the one shown below.
## [1] 338.9095 1004.1762 1594.1297
## attr(,"unit")
## [1] "px"
# using pixel units here
segm_df <-
tibble(
x = 340,
y = 1000,
xend = 1600,
yend = 1000,
part = "part_1"
)
# show results
segm_df
## # A tibble: 1 x 5
## x y xend yend part
## <dbl> <dbl> <dbl> <dbl> <chr>
## 1 340 1000 1600 1000 part_1
Mapping the x- and y-coordinates of the barcode-spots to the respective x- and y-aesthetics results in a basic surface plot. The data.frame above contains information about start- and endpoint of the trajectory which can be used to plot the trajectory’s course.
no_panel_grid <-
theme(
panel.grid.major = element_blank(),
panel.grid.minor = element_blank()
)
# display x- and y-coordinates of all barcode-spots
surface_plot <-
ggplot(data = coords_df, mapping = aes(x = x, y = y)) +
geom_point(color = "lightgrey", alpha = 0.5, size = 2) + # provide point geometry
scale_color_add_on(aes = "fill", variable = "discrete", clrp = "milo") + # SPATA-intern wrapper
theme_bw() +
coord_equal() +
no_panel_grid +
labs(x = NULL, y = NULL)
# save the trajectory layer
trajectory <-
geom_segment(
data = segm_df,
mapping = aes(x = x, y = y, xend = xend, yend = yend),
size = 1.75,
arrow = arrow(length = unit(0.125, "inches"))
)
# plot results
surface_plot +
labs(subtitle = "a) Surface")
surface_plot +
trajectory +
labs(subtitle = "b) Surface + trajectory")
A trajectory includes only a subset of barcode-spots. To determine the barcode-spots that fall into the trajectory’s reach the trajectory’s width needs to be determined.
With that value two additional vectors can be computed that each cross the trajectory’s start- and endpoint orthogonally. Start- and endpoint of these crossing vectors determine the vertices of the rectangle that includes all the barcode-spots that fall into the trajectory’s reach. The higher the value for the trajectory’s width the wider it gets and the more barcode-spots it includes.
# determines the width of the trajectory (in pixel)
trajectory_width <- 350
start_point <- as.numeric(segm_df[1:2])
end_point <- as.numeric(segm_df[3:4])
trajectory_vec <- end_point - start_point
# show results
trajectory_vec
## [1] 1260 0
# factor with which to compute the width vector
trajectory_magnitude <- sqrt((trajectory_vec[1])^2 + (trajectory_vec[2])^2)
trajectory_factor <- trajectory_width / trajectory_magnitude
# orthogonal trajectory vector
orth_trajectory_vec <- (c(-trajectory_vec[2], trajectory_vec[1]) * trajectory_factor)
# show results
orth_trajectory_vec
## [1] 0 350
# determine trajectory frame points 'tfps' making up the square that embraces
# the points
tfp1.1 <- start_point + orth_trajectory_vec
tfp1.2 <- start_point - orth_trajectory_vec
tfp2.1 <- end_point - orth_trajectory_vec
tfp2.2 <- end_point + orth_trajectory_vec
rectangular_df <-
tibble(
x = c(tfp1.1[1], tfp1.2[1], tfp2.1[1], tfp2.2[1]),
y = c(tfp1.1[2], tfp1.2[2], tfp2.1[2], tfp2.2[2]),
label = c("A", "D", "C", "B")
)
# show results
rectangular_df
## # A tibble: 4 x 3
## x y label
## <dbl> <dbl> <chr>
## 1 340 1350 A
## 2 340 650 D
## 3 1600 650 C
## 4 1600 1350 B
The function point.in.polygon()
of the
sp-package allows to filter the data.frame that
contains information about all barcode-spots for those spots that fall
into the polygon and thus in the trajectory’s reach.
# get a logical vector indicating if a barcode spot falls into the trajectory's reach or not
positions <-
sp::point.in.polygon(
point.x = coords_df$x,
point.y = coords_df$y,
pol.x = rectangular_df$x,
pol.y = rectangular_df$y
)
# show results
head(positions, 10)
## [1] 1 0 0 0 0 1 1 0 1 1
# keep only those that fall into the trajectory's reach (not 0)
barcode_spots_of_interest <- coords_df[as.logical(positions), ]
# visualize filtered spots
trajectory_spots <-
geom_point(
data = barcode_spots_of_interest,
mapping = aes(x = x, y = y),
alpha = 0.5,
size = 2,
color = "steelblue"
)
# visualize the vertices of the polygon
# based on which the barcode-spots were filtered
vertices <-
geom_text(
data = rectangular_df,
mapping = aes(x = x, y = y, label = label),
size = 7.5
)
# plot results
surface_plot + trajectory_spots + trajectory + vertices
In order to integrate the direction of the trajectory as an informative variable every barcode-spot needs to be set into relation to the trajectory’s course. The closer a barcode-spot is located towards the trajectory’s origin the smaller the respective value needs to be.
This is achieved by projecting the barcode-spots position onto the vector that corresponds to the trajectory’s course. The local coordinate system of the figure below is build around all relevant barcode-spots whereby it’s x- and y-axis correspond to the trajectory’s width (local width axis, lwa) and the trajectory itself (local length axis, lla), albeit displaced towards the edge.
# set up a local coordinate system
lcs <- data.frame(
x = c(tfp1.1[1], tfp1.1[1]),
y = c(tfp1.1[2], tfp1.1[2]),
xend = c(tfp2.2[1], tfp1.2[1]),
yend = c(tfp2.2[2], tfp1.2[2]),
use = c("local length axis", "local width axis")
)
# show results
lcs
## x y xend yend use
## 1 340 1350 1600 1350 local length axis
## 2 340 1350 340 650 local width axis
# local coordinate system layer
local_coordinate_system <-
list(
geom_segment(
data = lcs,
mapping = aes(x = x, y = y, xend = xend, yend = yend),
arrow = arrow(length = unit(0.125, "inches")),
size = 1.5
)
)
# plot results
surface_plot +
trajectory_spots +
local_coordinate_system
The local length axis inherits it’s direction and course from the original trajectory. In order to arrange the barcode-spots according to the trajectory’s direction their projection onto the local length axis needs to be calculated via vector-projection which requires two main steps.
1.) Calculate vector a that connects the barcode-spot of interest to the origin of the local coordinate system. Then project vector a onto the local length axis (lla) such that \(\vec{proj} = \frac{\vec{sto} * \vec{traj}}{||\vec{traj}||^2} * \vec{traj}\)
2.) Calculate the magnitude of the vector that corresponds to the projection: \(proj.length = |\vec{proj}|\)
The higher the calculated projection length the higher the distance between the barcode-spot and the origin of the trajectory.
vector_projection <- function(lcs, x_coordinate, y_coordinate){
# vector from point of interest to origin of local coord system: vector to origin 'vto'
vto <- c((x_coordinate - lcs$x[1]), (y_coordinate - lcs$y[1]))
# define local length axis (= relocated trajectory): 'lla'
lla <- c((lcs$xend[1] - lcs$x[1]), (lcs$yend[1] - lcs$y[1]))
# define lambda coefficient
lambda <- ((vto[1] * lla[1]) + (vto[2] * lla[2])) / sqrt((lla[1])^2 + (lla[2])^2)^2
# projecting vector on local length axis
pv <- lambda * (lla)
# compute the length of the projected vector -> projection length!
res <- sqrt((pv[1])^2 + (pv[2])^2)
# return the result
return(res)
}
# points of interest data.frame
barcode_spots_arranged <-
group_by(.data = barcode_spots_of_interest, barcodes) %>%
mutate(projection_length = vector_projection(lcs = lcs, x, y)) %>%
arrange(projection_length) %>% # arrange barcodes according to their projection value
ungroup()
# show results
barcode_spots_arranged
## # A tibble: 1,623 x 7
## barcodes sample x y section outline projection_length
## <chr> <chr> <dbl> <dbl> <chr> <lgl> <dbl>
## 1 GATCGGATAGAACCAT-1 269_T 340. 939. 1 TRUE 0.225
## 2 ACGCTGTGAGGCGTAG-1 269_T 341. 983. 1 FALSE 0.624
## 3 GTCTACTCAATTACAA-1 269_T 341. 1026. 1 FALSE 1.02
## 4 CACTCGGTTAGGAGGA-1 269_T 341. 1070 1 FALSE 1.42
## 5 GGTTGTGTAGCCTGGC-1 269_T 342. 1113. 1 FALSE 2.22
## 6 GCGTTATATTTGGAAC-1 269_T 343. 1157. 1 FALSE 2.62
## 7 GTCAGTTTGGTAGTCG-1 269_T 343. 1200. 1 FALSE 3.02
## 8 GCTAAGTAAAGGCGAT-1 269_T 343. 1244 1 FALSE 3.42
## 9 GCTCGCGGTTCCGCTC-1 269_T 344. 1288. 1 FALSE 3.82
## 10 GCAGATCCTCGCAAAT-1 269_T 344. 1331. 1 FALSE 4.22
## # i 1,613 more rows
The projection length of every barcode spot in relation to the spatial trajectory can be visualized by coloring the spots accordingly.
# projection length layer
projected_length <-
list(
geom_point(
data = barcode_spots_arranged,
size = 2,
mapping = aes(x = x, y = y, color = projection_length)
),
scale_color_add_on(clrsp = "plasma"),
labs(color = "Projection-\nLength (PL)")
)
# plot results
surface_plot + projected_length + local_coordinate_system
This is what happens when a spatial trajectory is added via
addSpatialTrajectory()
or created interactively by
createSpatialTrajectories()
(which in turn uses
addSpatialtrajectory()
). The results, namely the projection
length information of the barcode-spots in combination with the course
of the trajectory are stored in an S4 object of class
SpatialTrajectory
within the spata2
object.
traj_obj <- getSpatialTrajectory(object = object_t269, id = "horizontal_mid")
traj_obj
## An object of class "SpatialTrajectory"
## Slot "coords":
## # A tibble: 3,213 x 6
## barcodes sample x y section outline
## <chr> <chr> <dbl> <dbl> <chr> <lgl>
## 1 AAACAAGTATCTCCCA-1 269_T 1450. 731. 1 FALSE
## 2 AAACACCAATAACTGC-1 269_T 411. 547. 1 FALSE
## 3 AAACAGAGCGACTCCT-1 269_T 1359. 1516 1 FALSE
## 4 AAACATTTCCCGGATT-1 269_T 1386. 493. 1 FALSE
## 5 AAACCCGAACGAAATC-1 269_T 1614. 838. 1 FALSE
## 6 AAACCGGGTAGGTACC-1 269_T 527. 916. 1 FALSE
## 7 AAACCGTTCGTCCAGG-1 269_T 700. 696 1 FALSE
## 8 AAACCTAAGCAGCCGG-1 269_T 1210. 408. 1 FALSE
## 9 AAACCTCATGAAGTTG-1 269_T 416. 1026. 1 FALSE
## 10 AAACGAGACGGTTGAT-1 269_T 1167. 1061. 1 FALSE
## # i 3,203 more rows
##
## Slot "info":
## $current_dim
## [1] 1939 2000 3
##
## $current_just
## $current_just$angle
## [1] 0
##
## $current_just$flipped
## $current_just$flipped$horizontal
## [1] FALSE
##
## $current_just$flipped$vertical
## [1] FALSE
##
##
##
##
## Slot "width_unit":
## [1] "mm"
##
## Slot "comment":
## [1] ""
##
## Slot "id":
## [1] "horizontal_mid"
##
## Slot "projection":
## # A tibble: 1,733 x 6
## barcodes sample x y projection_length trajectory_part
## <chr> <chr> <dbl> <dbl> <dbl> <chr>
## 1 TGCGAATATGGGATTT-1 269_T 339. 852. 0.116 Part 1
## 2 TTGTGAGGCATGACGC-1 269_T 340. 896. 0.915 Part 1
## 3 GATCGGATAGAACCAT-1 269_T 340. 939. 1.32 Part 1
## 4 ACGCTGTGAGGCGTAG-1 269_T 341. 983. 1.71 Part 1
## 5 GTCTACTCAATTACAA-1 269_T 341. 1026. 2.11 Part 1
## 6 CACTCGGTTAGGAGGA-1 269_T 341. 1070 2.51 Part 1
## 7 GGTTGTGTAGCCTGGC-1 269_T 342. 1113. 3.31 Part 1
## 8 GCGTTATATTTGGAAC-1 269_T 343. 1157. 3.71 Part 1
## 9 GTCAGTTTGGTAGTCG-1 269_T 343. 1200. 4.11 Part 1
## 10 GCTAAGTAAAGGCGAT-1 269_T 343. 1244 4.51 Part 1
## # i 1,723 more rows
##
## Slot "sample":
## [1] "269_T"
##
## Slot "segment":
## x y xend yend part
## 1 338.9095 1004.176 1594.13 1004.176 part_1
##
## Slot "width":
## [1] 376.5661
The barcode-spots are now arranged according to their projection onto the trajectory. By assigning them to groups by their projection_length-values they are sorted into bins for which the average expression values are calculated and in return plotted against the trajectory’s direction. The example sorts the barcode-spots in 7 bins.
(A higher number of bins is recommended to increase the resolution. In fact, we recommend to determine the number of bins by specifying the binwidth. We stick to 7 during this example to keep the plots clear and easy to understand.)
# use n_bins to specify the number of bins explicitly for visualization purposes
# scroll down to the end of the vignette on why binwidth might be better
n_bins <- 10
barcode_spots_binned <-
mutate(
.data = barcode_spots_arranged,
bins_order = cut(projection_length, breaks = n_bins)
)
# show results
barcode_spots_binned
## # A tibble: 1,623 x 8
## barcodes sample x y section outline projection_length bins_order
## <chr> <chr> <dbl> <dbl> <chr> <lgl> <dbl> <fct>
## 1 GATCGGATAGAA~ 269_T 340. 939. 1 TRUE 0.225 (-1.03,12~
## 2 ACGCTGTGAGGC~ 269_T 341. 983. 1 FALSE 0.624 (-1.03,12~
## 3 GTCTACTCAATT~ 269_T 341. 1026. 1 FALSE 1.02 (-1.03,12~
## 4 CACTCGGTTAGG~ 269_T 341. 1070 1 FALSE 1.42 (-1.03,12~
## 5 GGTTGTGTAGCC~ 269_T 342. 1113. 1 FALSE 2.22 (-1.03,12~
## 6 GCGTTATATTTG~ 269_T 343. 1157. 1 FALSE 2.62 (-1.03,12~
## 7 GTCAGTTTGGTA~ 269_T 343. 1200. 1 FALSE 3.02 (-1.03,12~
## 8 GCTAAGTAAAGG~ 269_T 343. 1244 1 FALSE 3.42 (-1.03,12~
## 9 GCTCGCGGTTCC~ 269_T 344. 1288. 1 FALSE 3.82 (-1.03,12~
## 10 GCAGATCCTCGC~ 269_T 344. 1331. 1 FALSE 4.22 (-1.03,12~
## # i 1,613 more rows
averaged_points <-
group_by(.data = barcode_spots_binned, bins_order) %>%
summarise(x = mean(x), y = mean(y)) %>%
mutate(
trajectory_order = as.numeric(bins_order) # convert factor levels to numbers
)
projection_length_binned <-
list(
geom_point(
data = barcode_spots_binned,
mapping = aes(x = x, y = y, color = bins_order)
)
)
order_averaged <-
list(
geom_point(
data = barcode_spots_binned,
mapping = aes(x = x, y = y, color = bins_order),
alpha = 0.3
),
geom_text(
data = averaged_points,
mapping = aes(x = x, y = y, color = bins_order, label = trajectory_order),
size = 10
)
)
# plot results
surface_plot +
projection_length_binned +
trajectory +
legendNone()
surface_plot +
order_averaged
Using the barcodes-variable as the id variable expression-values (or any other kind of numeric variable) can be joined to the data.frame containing the arranged and grouped barcode-spots as shown in the data.frame below.
genes_of_interest <- c("EGFR", "MAG")
joined_df <-
joinWith(
object = object_t269,
spata_df = barcode_spots_binned,
genes = genes_of_interest
)
# show results
joined_df
## # A tibble: 1,623 x 10
## barcodes sample x y section outline projection_length bins_order
## <chr> <chr> <dbl> <dbl> <chr> <lgl> <dbl> <fct>
## 1 GATCGGATAGAA~ 269_T 340. 939. 1 TRUE 0.225 (-1.03,12~
## 2 ACGCTGTGAGGC~ 269_T 341. 983. 1 FALSE 0.624 (-1.03,12~
## 3 GTCTACTCAATT~ 269_T 341. 1026. 1 FALSE 1.02 (-1.03,12~
## 4 CACTCGGTTAGG~ 269_T 341. 1070 1 FALSE 1.42 (-1.03,12~
## 5 GGTTGTGTAGCC~ 269_T 342. 1113. 1 FALSE 2.22 (-1.03,12~
## 6 GCGTTATATTTG~ 269_T 343. 1157. 1 FALSE 2.62 (-1.03,12~
## 7 GTCAGTTTGGTA~ 269_T 343. 1200. 1 FALSE 3.02 (-1.03,12~
## 8 GCTAAGTAAAGG~ 269_T 343. 1244 1 FALSE 3.42 (-1.03,12~
## 9 GCTCGCGGTTCC~ 269_T 344. 1288. 1 FALSE 3.82 (-1.03,12~
## 10 GCAGATCCTCGC~ 269_T 344. 1331. 1 FALSE 4.22 (-1.03,12~
## # i 1,613 more rows
## # i 2 more variables: EGFR <dbl>, MAG <dbl>
averaged_df <-
group_by(joined_df, bins_order) %>%
summarise(
across(
.cols = any_of(genes_of_interest),
.fns = ~ mean(.x)
)
)
# show results
averaged_df
## # A tibble: 10 x 3
## bins_order EGFR MAG
## <fct> <dbl> <dbl>
## 1 (-1.03,126] 0.707 0.00738
## 2 (126,251] 0.734 0.00474
## 3 (251,376] 0.749 0.00920
## 4 (376,502] 0.748 0.0381
## 5 (502,627] 0.666 0.278
## 6 (627,753] 0.483 0.325
## 7 (753,878] 0.350 0.110
## 8 (878,1e+03] 0.275 0.0615
## 9 (1e+03,1.13e+03] 0.202 0.0501
## 10 (1.13e+03,1.26e+03] 0.223 0.0458
normalized_df <-
ungroup(averaged_df) %>%
mutate(
across(
.cols = any_of(genes_of_interest),
.fns = confuns::normalize
)
)
# show results
normalized_df
## # A tibble: 10 x 3
## bins_order EGFR MAG
## <fct> <dbl> <dbl>
## 1 (-1.03,126] 0.924 0.00824
## 2 (126,251] 0.973 0
## 3 (251,376] 1 0.0139
## 4 (376,502] 0.999 0.104
## 5 (502,627] 0.849 0.852
## 6 (627,753] 0.513 1
## 7 (753,878] 0.270 0.328
## 8 (878,1e+03] 0.133 0.177
## 9 (1e+03,1.13e+03] 0 0.141
## 10 (1.13e+03,1.26e+03] 0.0384 0.128
plot_df <-
# shift to use facet_wrap
pivot_longer(
data = normalized_df,
cols = any_of(genes_of_interest),
names_to = "genes",
values_to = "values"
) %>%
mutate(trajectory_order = as.numeric(bins_order))
traj_plots <-
map(
.x = genes_of_interest,
.f = ~
plotSpatialTrajectories(
object = object_t269,
ids = "horizontal_mid",
color_by = .x,
sgmt_size = 1
)
)
# plot results
ggplot(plot_df, mapping = aes(x = trajectory_order, y = values)) +
geom_point(color = "blue", size = 2.5) +
geom_path(color = "blue") +
geom_smooth(
alpha = 0.5,
color = "red",
method = "loess",
formula = y ~ x,
span = 0.5
) +
theme_bw() +
scale_x_continuous(breaks = 1:n_bins, labels = 1:n_bins) +
facet_wrap(facets = . ~ genes, ncol = 1) +
labs(x = "Trajectory Order (Bins)", y = "Inferred Expression") | # use patchwork | operator
(traj_plots[[1]] / traj_plots[[2]])
This is what happens in plotTrajectoryLineplot()
and
plotTrajectoryHeatmap()
.
traj_df <-
getTrajectoryDf(
object = object_t269,
id = "horizontal_mid",
variables = genes_of_interest,
format = "wide"
)
# show results
traj_df
## # A tibble: 1,733 x 8
## barcodes sample x y projection_length trajectory_part EGFR MAG
## <chr> <chr> <dbl> <dbl> <dbl> <chr> <dbl> <dbl>
## 1 TGCGAATATGG~ 269_T 339. 852. 0.116 Part 1 0.746 0
## 2 TTGTGAGGCAT~ 269_T 340. 896. 0.915 Part 1 0.746 0.245
## 3 GATCGGATAGA~ 269_T 340. 939. 1.32 Part 1 0.624 0
## 4 ACGCTGTGAGG~ 269_T 341. 983. 1.71 Part 1 0.659 0
## 5 GTCTACTCAAT~ 269_T 341. 1026. 2.11 Part 1 0.867 0
## 6 CACTCGGTTAG~ 269_T 341. 1070 2.51 Part 1 0.659 0
## 7 GGTTGTGTAGC~ 269_T 342. 1113. 3.31 Part 1 0.813 0
## 8 GCGTTATATTT~ 269_T 343. 1157. 3.71 Part 1 0.624 0
## 9 GTCAGTTTGGT~ 269_T 343. 1200. 4.11 Part 1 0.813 0
## 10 GCTAAGTAAAG~ 269_T 343. 1244 4.51 Part 1 0.483 0
## # i 1,723 more rows
plotTrajectoryLineplot(
object = object_t269,
id = "horizontal_mid",
variables = genes_of_interest,
ncol = 1,
n_bins = n_bins,
smooth_span = 0.5
) + geom_point()
plotTrajectoryHeatmap(
object = object_t269,
id = "horizontal_mid",
variables = genes_of_interest,
smooth_span = 0.2
)
The resolution of the binning is set up via the argument
n_bins
which explicitly specifies the number of bins
or binwidth
which specifies the width of
each bin. For visualization purposes we chose n_bins
in the
example above but we recommend to use the argument binwidth
and setting it to the distance between the barcode-spots using
getCCD()
. This results in bins that contain one layer of
barcode-spot each.
bcsp_dist <- getCCD(object = object_t269, unit = "px")
# show results
bcsp_dist
## [1] 25.1044
## attr(,"unit")
## [1] "px"
traj_df_small <-
traj_obj@projection %>%
filter(projection_length <= (getCCD(object_t269, "px")*20)) %>%
mutate(projection_length = round(projection_length, 5)) %>%
bin_projection_df(binwidth = bcsp_dist, n_bins = NA) %>%
mutate(proj_length_binned = as.factor(proj_length_binned))
# plot results
surface_plot +
geom_point(
data = traj_df_small,
mapping = aes(x = x, y = y, color = proj_length_binned)
) +
scale_color_add_on(
variable = traj_df_small[["proj_length_binned"]],
clrp = "milo"
) +
trajectory
Click here to be guided to the vignette that explains how the inferred expression changes are fitted to models to find biologically relevant dynamics along the trajectory.