dpeerlab/Palantir

Problem when running plot_trajectory with FDL

Closed this issue · 5 comments

Hi,
I tried the tutorial with FDL instead of the UMAP in the tutorial.
However, when I ran plot_trajectory, the trajectory did not display the arrow shapes as in the tutorial example, as shown below.
image
image

Is it possible to fix this?

Hi @miloAhn,

Thank you for reaching out! I believe we can address this. For a first approach, I’d recommend adjusting the smoothness parameter in plot_trajectory (see documentation). By default, this is set to 1, but from your plot, the trajectory appears overly smooth (almost constant in a certain point). Reducing smoothness—for example, trying a value like 0.1—should help introduce more flexibility in the curve.

Let me know how it goes! If this doesn’t resolve the issue, we can look into exposing additional parameters from the underlying inference process for more control.

Best,
Dominik

Thank you for your quick response!
By the way, I tried reducing the smoothness to 0.1 as you suggested, but it didn't make much difference.
image

Looking at the description of the plot_trajectory function, it says “Plot a trajectory on the UMAP embedding of single-cell data.” and “To visualize a trajectory on the UMAP, we interpolate the UMAP coordinates of cells specific to each branch across pseudotime, enabling us to draw a continuous path.” .
In other words, if I visualize with FDL, can't I use this function to represent a trajectory?

And one more question. Where is the trajectory data stored in anndata?

Best regards,
Milo

Technically, there is no reason why it should not work on the FDL representation, and I would continue to go lower on the smoothness. Unfortunately, however, the trajectory data is not stored in the anndata. But you can generate it yourself like so:

import mellon

pt = ad.obs["palantir_pseudotime"]
umap = ad.obsm["X_draw_graph_fa"]
mask = ad.obsm["branch_masks"]["Ery"].astype(bool)

pseudotime = pt[mask]
pseudotime_grid = np.linspace(np.min(pseudotime), np.max(pseudotime), 200)
umap_est = mellon.FunctionEstimator(ls=10, sigma=1, n_landmarks=50)
umap_trajectory = umap_est.fit_predict(pseudotime, umap[mask, :], pseudotime_grid)

The parameters to play around are ls and sigma. Both relate to the smoothness of the curve and larger values make it more smooth.

Edit: There is also a chance for the current smoothness/ls being much too low. Both ways could result in your observations. If you can share the data (the FDL embeddings would be enough) I could have a look at this.

I tried reducing the smoothness further as you recommended and at 0.001 the trajectory is long and smooth as in the tutorial.
image

I also created umap_trajectory as you suggested and was able to plot the graph.
When I set ls=10 and sigma=1, the trajectory was straight. I thought FDL embeddings and ls you mentioned might have something to do with the curve, so I looked up the source code on palantir's github.
In the formula below, I replaced umap with FDL embeddings and got about 1.2, so I set ls=1 and it plotted well as a curved trajectory.

   ls = (
           smoothness
           * np.sqrt(np.sum((np.max(umap, axis=0) - np.min(umap, axis=0)) ** 2))
           / 20
       )

image

Thank you so much!

P.S. Since you asked me to share the FDL embeddings, I've attached them just in case.
fdl_coordinates.csv

Thank you for reaching out about this! I am glad to see it work now. Your result makes me wonder what would be a better way to set ls and sigma in our code.