zktuong / ktplotspy Goto Github PK
View Code? Open in Web Editor NEWPython library for plotting Cellphonedb results. Ported from ktplots R package.
Home Page: https://ktplotspy.readthedocs.io/
License: MIT License
Python library for plotting Cellphonedb results. Ported from ktplots R package.
Home Page: https://ktplotspy.readthedocs.io/
License: MIT License
Need to check whether there's something wrong during slicing?
I am trying to run the plot_cpdb_heatmap function on the output of CellPhoneDB method 3. I used the relevant_interactions.txt for the pvals argument as recommended in the R documentation.
Here is the command I used:
kpy.plot_cpdb_heatmap(adata, pvals=pvals, celltype_key = "celltype", degs_analysis=True)
It created this error:
ValueError Traceback (most recent call last)
Cell In[8], line 1
----> 1 kpy.plot_cpdb_heatmap(adata, pvals=pvals, celltype_key = "celltype", degs_analysis=True, figsize=(5, 5), title="Sum of significant interactions")
File ~/anaconda3/lib/python3.10/site-packages/ktplotspy/plot/plot_cpdb_heatmap.py:96, in plot_cpdb_heatmap(adata, pvals, celltype_key, degs_analysis, log1p_transform, alpha, linewidths, row_cluster, col_cluster, low_col, mid_col, high_col, cmap, title, return_tables, symmetrical, **kwargs)
94 count_mat[pd.isnull(count_mat)] = 0
95 if symmetrical:
---> 96 count_matx = np.triu(count_mat) + np.tril(count_mat.T) + np.tril(count_mat) + np.triu(count_mat.T)
97 count_matx[np.diag_indices_from(count_matx)] = np.diag(count_mat)
98 count_matx = pd.DataFrame(count_matx)
ValueError: operands could not be broadcast together with shapes (11,12) (12,11)
I had no problem using Method 2 output without the degs_analysis argument.
Hi,
How to save figures? I used "plt.savefig()", but it did not work.
potential option to toggle this to help the visualisation? since people are mostly interested in what cell types are talking to other cell types
Hi, thanks for your great tool!
I kindly request you to add the parameter 'separator' to your plot functions. Previously, when running cpdb analysis, one may have used a custom separator to separate interacted cell pairs with the 'separator' parameter. The current plot functions do not seem compatible with this feature as they defaultly use '|' as the separator, resulting in errors.
Thanks again!
IndexError: only integers, slices (:
), ellipsis (...
), numpy.newaxis (None
) and i arrays are valid indices
when use the function kpy.plot_cpdb, what does it means?
Hello, thanks for this package to explore cpdb output.
I am facing the following issue with plot_cpdb
function:
import ktplotspy as kpy
pp = kpy.plot_cpdb(
adata = adata,
cell_type1 = '.',
cell_type2 = '.',
means = means,
pvals = relevant_interactions,
celltype_key = "celltype",
figsize = (7,10),
max_size = 6,
highlight_size = 0.75,
degs_analysis = True,
standard_scale = True,
)
pp
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
Input In [42], in <module>
1 import ktplotspy as kpy
----> 3 pp = kpy.plot_cpdb(
4 adata = adata,
5 cell_type1 = '.',
6 cell_type2 = '.',
7 means = means,
8 pvals = relevant_interactions,
9 celltype_key = "celltype",
10 figsize = (7,10),
11 max_size = 6,
12 highlight_size = 0.75,
13 degs_analysis = True,
14 standard_scale = True,
15 )
16 pp
File ~/my-conda-envs/sc_Harm/lib/python3.10/site-packages/ktplotspy/plot/plot_cpdb.py:218, in plot_cpdb(adata, cell_type1, cell_type2, means, pvals, celltype_key, degs_analysis, splitby_key, alpha, keep_significant_only, genes, gene_family, custom_gene_family, standard_scale, cluster_rows, cmap_name, max_size, max_highlight_size, default_style, highlight_col, highlight_size, special_character_regex_pattern, exclude_interactions, title, return_table, figsize)
216 # filter
217 means_matx = filter_interaction_and_celltype(data=means_mat, genes=query, celltype_pairs=ct_columns)
--> 218 pvals_matx = filter_interaction_and_celltype(data=pvals_mat, genes=query, celltype_pairs=ct_columns)
219 # reorder the columns
220 col_order = []
File ~/my-conda-envs/sc_Harm/lib/python3.10/site-packages/ktplotspy/utils/support.py:92, in filter_interaction_and_celltype(data, genes, celltype_pairs)
75 def filter_interaction_and_celltype(data: pd.DataFrame, genes: List, celltype_pairs: List) -> pd.DataFrame:
76 """Filter data to interactions and celltypes.
77
78 Parameters
(...)
90 Filtered dataframe.
91 """
---> 92 filtered_data = data[data.interacting_pair.isin(genes)][celltype_pairs]
93 return filtered_data
File ~/my-conda-envs/sc_Harm/lib/python3.10/site-packages/pandas/core/frame.py:3811, in DataFrame.__getitem__(self, key)
3809 if is_iterator(key):
3810 key = list(key)
-> 3811 indexer = self.columns._get_indexer_strict(key, "columns")[1]
3813 # take() does not accept boolean indexers
3814 if getattr(indexer, "dtype", None) == bool:
File ~/my-conda-envs/sc_Harm/lib/python3.10/site-packages/pandas/core/indexes/base.py:6113, in Index._get_indexer_strict(self, key, axis_name)
6110 else:
6111 keyarr, indexer, new_indexer = self._reindex_non_unique(keyarr)
-> 6113 self._raise_if_missing(keyarr, indexer, axis_name)
6115 keyarr = self.take(indexer)
6116 if isinstance(key, Index):
6117 # GH 42790 - Preserve name from an Index
File ~/my-conda-envs/sc_Harm/lib/python3.10/site-packages/pandas/core/indexes/base.py:6176, in Index._raise_if_missing(self, key, indexer, axis_name)
6173 raise KeyError(f"None of [{key}] are in the [{axis_name}]")
6175 not_found = list(ensure_index(key)[missing_mask.nonzero()[0]].unique())
-> 6176 raise KeyError(f"{not_found} not in index")
KeyError: "['thy_TH_processing>@<thy_TH_processing', 'thy_TH_processing>@<mes_CYGB', 'thy_TH_processing>@<thy_Lumen-forming', 'thy_TH_processing>@<end_Arterial', 'thy_TH_processing>@<mes_IGF1R', 'thy_TH_processing>@<mes_SCN7A', 'thy_TH_processing>@<mes_CCL19', 'end_Capillary>@<thy_TH_processing', 'end_Capillary>@<thy_Lumen-forming', 'end_Capillary>@<mes_IGF1R', 'end_Capillary>@<mes_SCN7A', 'thy_Lumen-forming>@<thy_TH_processing', 'thy_Lumen-forming>@<mes_CYGB', 'thy_Lumen-forming>@<thy_Lumen-forming', 'thy_Lumen-forming>@<end_Arterial', 'thy_Lumen-forming>@<mes_IGF1R', 'thy_Lumen-forming>@<mes_SCN7A', 'thy_Lumen-forming>@<mes_CCL19', 'end_Arterial>@<thy_TH_processing', 'end_Arterial>@<thy_Lumen-forming', 'end_Arterial>@<end_Arterial', 'end_Arterial>@<mes_IGF1R', 'end_Arterial>@<mes_CCL19', 'mes_IGF1R>@<thy_TH_processing', 'mes_IGF1R>@<thy_Lumen-forming', 'mes_IGF1R>@<end_Arterial', 'mes_IGF1R>@<mes_IGF1R', 'mes_IGF1R>@<mes_SCN7A', 'mes_IGF1R>@<mes_CCL19', 'mes_SCN7A>@<mes_SCN7A', 'mes_CCL19>@<thy_TH_processing', 'mes_CCL19>@<thy_Lumen-forming', 'mes_CCL19>@<end_Arterial', 'mes_CCL19>@<mes_IGF1R', 'mes_CCL19>@<mes_SCN7A', 'mes_CCL19>@<mes_CCL19', 'end_Cycling>@<end_Cycling', 'end_Cycling>@<mes_Cycling', 'end_Cycling>@<thy_Cycling', 'mes_Cycling>@<end_Cycling', 'mes_Cycling>@<mes_Cycling', 'mes_Cycling>@<thy_Cycling', 'thy_Cycling>@<end_Cycling', 'thy_Cycling>@<mes_Cycling', 'thy_Cycling>@<thy_Cycling'] not in index"
any hint what I did wrong ? thanks
Hello, I'm using plot_cpdb_heatmap() function to visualize my result from CPDB, and found a cell type row(B cell) is missing in the 9x10 heatmap.
It turns out that B cell in my pvals result have no significant interaction as cpdb target. And I expect a row with 0 interaction rather than just drop it.
metadata = adata.obs.copy()
all_intr = pvals.copy()
labels = metadata[celltype_key]
intr_pairs = all_intr.interacting_pair
all_int = all_intr.iloc[:, 12 : all_intr.shape[1]].T
all_int.columns = intr_pairs
all_count = all_int.melt(ignore_index=False).reset_index()
if degs_analysis:
all_count = all_count[all_count.value == 1]
else:
all_count = all_count[all_count.value < alpha]
count1x = all_count[["index", "interacting_pair"]].groupby("index").agg({"interacting_pair": "count"})
tmp = pd.DataFrame([x.split("|") for x in count1x.index])
Here is the code, seems it gets "tmp" by the filtered "all_counts", and cell without significant interaction were dropped in the filtered "all_counts".
Thanks for your time!
Hi,
In terms of plotting results of cellphonedb, this is an outstanding job.
However, while using ktplotspy, I am trying to reproduce the effect of plot_cpdb2 in ktplots. Can the ktplotspy.plot.plot_cpdb_chord function in Python achieve such results(Interactions between genes that mark different cells)?
Best,
xhxie
Hi,
I'm new to cellphonedb and just run it on a Seurat object in mtx format (as described here):
https://github.com/ventolab/CellphoneDB/blob/master/notebooks/DEGs_calculation/0_prepare_your_data_from_Seurat.ipynb
not in a .h5ad format. If I don't have a .h5ad, how can I define the adata parameter to plot using ktplotspy?
Thank you in advance,
Hi! please refer to this issue: ventolab/CellphoneDB#179
Could you add a parameter result_precision
according to cpdb_statistical_analysis_method.call
, which is default 3 but can be set to 5 when increasing test number to 1e5? like this:
def plot_cpdb(
...
result_precision: int = 3):
...
if df.at[i, "pvals"] == 0:
df.at[i, "pvals"] = 1**-result_precision
I'm not sure that if there are other places that need to be changed, Thank you for checking this!
Hi, thank you for developing such a great package.
I meet some problems in plotting my data with ktplotspy.
The "adata" file is the one analyzed by cellphnedb. However, it donot work with ktplotspy.
I run the plot like this:
kpy.plot_cpdb_heatmap(
adata = adata,
pvals = pvals,
celltype_key = "cluster_2",
figsize = (5,5),
title = "Number of significant interactions",
symmetrical = False,
)
It created this error:
AttributeError Traceback (most recent call last)
Cell In[19], line 1
----> 1 kpy.plot_cpdb_heatmap(
2 adata = adata,
3 pvals = pvals,
4 celltype_key = "cluster_2",
5 figsize = (5,5),
6 title = "Number of significant interactions",
7 symmetrical = False,
8 )
File ~/miniconda3/envs/cpdb/lib/python3.8/site-packages/ktplotspy/plot/plot_cpdb_heatmap.py:108, in plot_cpdb_heatmap(pvals, degs_analysis, log1p_transform, alpha, linewidths, row_cluster, col_cluster, low_col, mid_col, high_col, cmap, title, return_tables, symmetrical, **kwargs)
106 colmap = cmap
107 if not return_tables:
--> 108 g = sns.clustermap(
109 count_mat,
110 row_cluster=row_cluster,
111 col_cluster=col_cluster,
112 linewidths=linewidths,
113 tree_kws={"linewidths": 0},
114 cmap=colmap,
115 **kwargs
116 )
117 if title != "":
118 g.fig.suptitle(title)
File ~/miniconda3/envs/cpdb/lib/python3.8/site-packages/seaborn/matrix.py:1258, in clustermap(data, pivot_kws, method, metric, z_score, standard_scale, figsize, cbar_kws, row_cluster, col_cluster, row_linkage, col_linkage, row_colors, col_colors, mask, dendrogram_ratio, colors_ratio, cbar_pos, tree_kws, **kwargs)
1250 raise RuntimeError("clustermap requires scipy to be available")
1252 plotter = ClusterGrid(data, pivot_kws=pivot_kws, figsize=figsize,
1253 row_colors=row_colors, col_colors=col_colors,
1254 z_score=z_score, standard_scale=standard_scale,
1255 mask=mask, dendrogram_ratio=dendrogram_ratio,
1256 colors_ratio=colors_ratio, cbar_pos=cbar_pos)
-> 1258 return plotter.plot(metric=metric, method=method,
1259 colorbar_kws=cbar_kws,
1260 row_cluster=row_cluster, col_cluster=col_cluster,
1261 row_linkage=row_linkage, col_linkage=col_linkage,
1262 tree_kws=tree_kws, **kwargs)
File ~/miniconda3/envs/cpdb/lib/python3.8/site-packages/seaborn/matrix.py:1142, in ClusterGrid.plot(self, metric, method, colorbar_kws, row_cluster, col_cluster, row_linkage, col_linkage, tree_kws, **kws)
1139 yind = np.arange(self.data2d.shape[0])
1141 self.plot_colors(xind, yind, **kws)
-> 1142 self.plot_matrix(colorbar_kws, xind, yind, **kws)
1143 return self
File ~/miniconda3/envs/cpdb/lib/python3.8/site-packages/seaborn/matrix.py:1093, in ClusterGrid.plot_matrix(self, colorbar_kws, xind, yind, **kws)
1091 # Setting ax_cbar=None in clustermap call implies no colorbar
1092 kws.setdefault("cbar", self.ax_cbar is not None)
-> 1093 heatmap(self.data2d, ax=self.ax_heatmap, cbar_ax=self.ax_cbar,
1094 cbar_kws=colorbar_kws, mask=self.mask,
1095 xticklabels=xtl, yticklabels=ytl, annot=annot, **kws)
1097 ytl = self.ax_heatmap.get_yticklabels()
1098 ytl_rot = None if not ytl else ytl[0].get_rotation()
File ~/miniconda3/envs/cpdb/lib/python3.8/site-packages/seaborn/matrix.py:459, in heatmap(data, vmin, vmax, cmap, center, robust, annot, fmt, annot_kws, linewidths, linecolor, cbar, cbar_kws, cbar_ax, square, xticklabels, yticklabels, mask, ax, **kwargs)
457 if square:
458 ax.set_aspect("equal")
--> 459 plotter.plot(ax, cbar_ax, kwargs)
460 return ax
File ~/miniconda3/envs/cpdb/lib/python3.8/site-packages/seaborn/matrix.py:306, in _HeatMapper.plot(self, ax, cax, kws)
303 kws.setdefault("vmax", self.vmax)
305 # Draw the heatmap
--> 306 mesh = ax.pcolormesh(self.plot_data, cmap=self.cmap, **kws)
308 # Set the axis limits
309 ax.set(xlim=(0, self.data.shape[1]), ylim=(0, self.data.shape[0]))
File ~/miniconda3/envs/cpdb/lib/python3.8/site-packages/matplotlib/__init__.py:1446, in _preprocess_data.<locals>.inner(ax, data, *args, **kwargs)
1443 @functools.wraps(func)
1444 def inner(ax, *args, data=None, **kwargs):
1445 if data is None:
-> 1446 return func(ax, *map(sanitize_sequence, args), **kwargs)
1448 bound = new_sig.bind(ax, *args, **kwargs)
1449 auto_label = (bound.arguments.get(label_namer)
1450 or bound.kwargs.get(label_namer))
File ~/miniconda3/envs/cpdb/lib/python3.8/site-packages/matplotlib/axes/_axes.py:6227, in Axes.pcolormesh(self, alpha, norm, cmap, vmin, vmax, shading, antialiased, *args, **kwargs)
6223 C = C.ravel()
6225 kwargs.setdefault('snap', mpl.rcParams['pcolormesh.snap'])
-> 6227 collection = mcoll.QuadMesh(
6228 coords, antialiased=antialiased, shading=shading,
6229 array=C, cmap=cmap, norm=norm, alpha=alpha, **kwargs)
6230 collection._scale_norm(norm, vmin, vmax)
6232 coords = coords.reshape(-1, 2) # flatten the grid structure; keep x, y
File ~/miniconda3/envs/cpdb/lib/python3.8/site-packages/matplotlib/collections.py:1939, in QuadMesh.__init__(self, coordinates, antialiased, shading, **kwargs)
1936 self._bbox.update_from_data_xy(self._coordinates.reshape(-1, 2))
1937 # super init delayed after own init because array kwarg requires
1938 # self._coordinates and self._shading
-> 1939 super().__init__(**kwargs)
1940 self.set_mouseover(False)
File ~/miniconda3/envs/cpdb/lib/python3.8/site-packages/matplotlib/_api/deprecation.py:454, in make_keyword_only.<locals>.wrapper(*args, **kwargs)
448 if len(args) > name_idx:
449 warn_deprecated(
450 since, message="Passing the %(name)s %(obj_type)s "
451 "positionally is deprecated since Matplotlib %(since)s; the "
452 "parameter will become keyword-only %(removal)s.",
453 name=name, obj_type=f"parameter of {func.__name__}()")
--> 454 return func(*args, **kwargs)
File ~/miniconda3/envs/cpdb/lib/python3.8/site-packages/matplotlib/collections.py:201, in Collection.__init__(self, edgecolors, facecolors, linewidths, linestyles, capstyle, joinstyle, antialiaseds, offsets, offset_transform, norm, cmap, pickradius, hatch, urls, zorder, **kwargs)
198 self._offset_transform = offset_transform
200 self._path_effects = None
--> 201 self._internal_update(kwargs)
202 self._paths = None
File ~/miniconda3/envs/cpdb/lib/python3.8/site-packages/matplotlib/artist.py:1223, in Artist._internal_update(self, kwargs)
1216 def _internal_update(self, kwargs):
1217 """
1218 Update artist properties without prenormalizing them, but generating
1219 errors as if calling `set`.
1220
1221 The lack of prenormalization is to maintain backcompatibility.
1222 """
-> 1223 return self._update_props(
1224 kwargs, "{cls.__name__}.set() got an unexpected keyword argument "
1225 "{prop_name!r}")
File ~/miniconda3/envs/cpdb/lib/python3.8/site-packages/matplotlib/artist.py:1197, in Artist._update_props(self, props, errfmt)
1195 func = getattr(self, f"set_{k}", None)
1196 if not callable(func):
-> 1197 raise AttributeError(
1198 errfmt.format(cls=type(self), prop_name=k))
1199 ret.append(func(v))
1200 if ret:
AttributeError: QuadMesh.set() got an unexpected keyword argument 'adata'
is it simple to just implement from bokeh?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.