ccc_circle_plot
Visualize cell-cell communication networks using a circular plot to analyze interactions between cell types, leveraging LIANA results for insights without coding.
Instructions
Visualize cell-cell communication network using a circular plot.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| edge_alpha | No | The transparency of the edges. | |
| edge_arrow_size | No | The size of the arrow. | |
| edge_width_scale | No | The scale of the edge width. | |
| figure_size | No | Figure x,y size. | |
| groupby | No | Key to be used for grouping or clustering cells. | |
| inverse_score | No | Whether to invert the score. If True, the score will be -log10(score). | |
| ligand_complex | No | List of ligand complexes to filter the interactions to be plotted. | |
| mask_mode | No | The mode of the mask: 'or' to include source or target, 'and' to include source and target. | or |
| node_alpha | No | The transparency of the nodes. | |
| node_label_alpha | No | The transparency of the node label. | |
| node_label_offset | No | The offset of the node label. | |
| node_label_size | No | The size of the node label. | |
| node_size_scale | No | The scale of the node size. | |
| orderby | No | If top_n is not None, order the interactions by this column. | |
| orderby_absolute | No | If top_n is not None, whether to order by the absolute value of the orderby column. | |
| orderby_ascending | No | If top_n is not None, specify how to order the interactions. | |
| pivot_mode | No | The mode of the pivot table: 'counts' for number of connections, 'mean' for mean of score values. | counts |
| receptor_complex | No | List of receptor complexes to filter the interactions to be plotted. | |
| score_key | No | Column name of the score in liana_res. If None, the score is inferred from the method. | |
| source_key | No | Column name of the sender/source cell types in liana_res. | source |
| source_labels | No | List of labels to use as source, the rest are filtered out. | |
| specificity_cutoff | No | specificity or pval threshold for filtering results. | |
| target_key | No | Column name of the receiver/target cell types in liana_res. | target |
| target_labels | No | List of labels to use as target, the rest are filtered out. | |
| top_n | No | Top N entities to plot. | |
| uns_key | No | Key in adata.uns that contains the LIANA results. | liana_res |
Implementation Reference
- src/scmcp/tool/ccc.py:64-72 (handler)The core handler function that executes the circle plot visualization using liana's li.pl.circle_plot, applying specificity cutoff filtering and parameter validation.def plot_circleplot(adata, **kwargs): pval = kwargs.pop("specificity_cutoff", 0.05) res_key = kwargs.get("uns_key", "liana_res") pval_col = adata.uns[res_key].columns[-1] kwargs["filter_fun"] = lambda x: x[pval_col] <= pval parameters = inspect.signature( li.pl.circle_plot).parameters kwargs = {k: kwargs.get(k) for k in parameters if k in kwargs} ax = li.pl.circle_plot(adata, **kwargs) return ax
- src/scmcp/schema/ccc.py:181-313 (schema)Pydantic model defining the input schema (parameters and types) for the ccc_circle_plot tool, including plot configuration options like keys, cutoffs, labels, and styling.class CirclePlotModel(JSONParsingModel): """Input schema for LIANA's circle_plot visualization for cell-cell communication networks.""" uns_key: Optional[str] = Field( default="liana_res", description="Key in adata.uns that contains the LIANA results." ) groupby: Optional[str] = Field( default=None, description="Key to be used for grouping or clustering cells." ) source_key: str = Field( default="source", description="Column name of the sender/source cell types in liana_res." ) target_key: str = Field( default="target", description="Column name of the receiver/target cell types in liana_res." ) score_key: Optional[str] = Field( default=None, description="Column name of the score in liana_res. If None, the score is inferred from the method." ) inverse_score: bool = Field( default=False, description="Whether to invert the score. If True, the score will be -log10(score)." ) top_n: Optional[int] = Field( default=None, description="Top N entities to plot." ) orderby: Optional[str] = Field( default=None, description="If top_n is not None, order the interactions by this column." ) orderby_ascending: Optional[bool] = Field( default=None, description="If top_n is not None, specify how to order the interactions." ) orderby_absolute: bool = Field( default=False, description="If top_n is not None, whether to order by the absolute value of the orderby column." ) source_labels: Optional[Union[List[str], str]] = Field( default=None, description="List of labels to use as source, the rest are filtered out." ) target_labels: Optional[Union[List[str], str]] = Field( default=None, description="List of labels to use as target, the rest are filtered out." ) ligand_complex: Optional[Union[List[str], str]] = Field( default=None, description="List of ligand complexes to filter the interactions to be plotted." ) receptor_complex: Optional[Union[List[str], str]] = Field( default=None, description="List of receptor complexes to filter the interactions to be plotted." ) pivot_mode: Literal["counts", "mean"] = Field( default="counts", description="The mode of the pivot table: 'counts' for number of connections, 'mean' for mean of score values." ) mask_mode: Literal["and", "or"] = Field( default="or", description="The mode of the mask: 'or' to include source or target, 'and' to include source and target." ) specificity_cutoff: float = Field( default=0.05, description="specificity or pval threshold for filtering results. " ) figure_size: Tuple[float, float] = Field( default=(5, 5), description="Figure x,y size." ) edge_alpha: float = Field( default=0.5, description="The transparency of the edges." ) edge_arrow_size: int = Field( default=10, description="The size of the arrow." ) edge_width_scale: Tuple[float, float] = Field( default=(1, 5), description="The scale of the edge width." ) node_alpha: float = Field( default=1.0, description="The transparency of the nodes." ) node_size_scale: Tuple[float, float] = Field( default=(100, 400), description="The scale of the node size." ) node_label_offset: Tuple[float, float] = Field( default=(0.1, -0.2), description="The offset of the node label." ) node_label_size: int = Field( default=8, description="The size of the node label." ) node_label_alpha: float = Field( default=0.7, description="The transparency of the node label." )
- src/scmcp/tool/ccc.py:29-33 (registration)Definition and registration of the MCP Tool object named 'ccc_circle_plot' with its description and input schema.circle_plot_tool = types.Tool( name="ccc_circle_plot", description="Visualize cell-cell communication network using a circular plot.", inputSchema=CirclePlotModel.model_json_schema(), )
- src/scmcp/tool/ccc.py:92-98 (registration)Mapping of tool name 'ccc_circle_plot' to its handler function plot_circleplot in the ccc_func dictionary, used by the dispatcher.ccc_func = { "ls_ccc_method": ls_ccc_method, "ccc_rank_aggregate": li.mt.rank_aggregate, "ccc_circle_plot": plot_circleplot, "ccc_dot_plot": plot_dotplot, "ccc": run_ccc, }
- src/scmcp/tool/ccc.py:109-141 (helper)Dispatcher function that invokes the specific handler (like plot_circleplot) for plot tools, handles adata access, logging, and figure saving.def run_ccc_func(ads, func, arguments): if func not in ccc_func: raise ValueError(f"不支持的函数: {func}") run_func = ccc_func[func] adata = ads.adata_dic[ads.active] try: logger.info(f"Running function {func} with arguments {arguments}") if func == "ls_ccc_method": res = run_func() elif func == "ccc": # Extract method from arguments and pass remaining args method = arguments.get("method", "cellphonedb") method_args = {k: v for k, v in arguments.items() if k != "method"} res = run_func(adata, method, **method_args) elif "plot" in func: from ..util import savefig ax = run_func(adata, **arguments) fig_path = Path(os.getcwd()) / f"figures/{func}.png" res = savefig(ax, fig_path, format="png") add_op_log(adata, run_func, arguments) # else: parameters = inspect.signature(run_func).parameters kwargs = {k: arguments.get(k) for k in parameters if k in arguments} res = run_func(adata, **kwargs) add_op_log(adata, run_func, kwargs) return res except Exception as e: logger.error(f"Error running function {func}: {e}") raise e