draw_graph
Visualize single-cell RNA sequencing data using force-directed graph drawing. Customize layouts (fa, fr, kk), define node positions, and ensure reproducibility for clear, interpretable representations.
Instructions
Force-directed graph drawing for visualization
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| init_pos | No | Initial position for nodes ('paga'/True, False, or .obsm key) | |
| key_added_ext | No | Suffix for storing results in .obsm | |
| layout | No | Graph layout algorithm ('fa', 'fr', 'kk', etc.) | fa |
| n_jobs | No | Number of jobs for parallel computation | |
| neighbors_key | No | Key for neighbors settings in .uns | |
| obsp | No | Key for adjacency matrix in .obsp | |
| random_state | No | Random seed for reproducibility | |
| root | No | Root node for tree layouts |
Implementation Reference
- src/scmcp/schema/tl.py:155-207 (schema)Pydantic input schema model for the 'draw_graph' tool defining parameters like layout, init_pos, root, etc., with validation.class DrawGraphModel(JSONParsingModel): """Input schema for the force-directed graph drawing tool.""" layout: str = Field( default='fa', description="Graph layout algorithm ('fa', 'fr', 'kk', etc.)", ) init_pos: Optional[Union[str, bool]] = Field( default=None, description="Initial position for nodes ('paga'/True, False, or .obsm key)", ) root: Optional[int] = Field( default=None, description="Root node for tree layouts", ge=0 ) random_state: int = Field( default=0, description="Random seed for reproducibility" ) n_jobs: Optional[int] = Field( default=None, description="Number of jobs for parallel computation", gt=0 ) key_added_ext: Optional[str] = Field( default=None, description="Suffix for storing results in .obsm" ) neighbors_key: Optional[str] = Field( default=None, description="Key for neighbors settings in .uns" ) obsp: Optional[str] = Field( default=None, description="Key for adjacency matrix in .obsp" ) @field_validator('layout') def validate_layout(cls, v: str) -> str: """Validate layout is supported""" valid_layouts = ['fa', 'fr', 'grid_fr', 'kk', 'lgl', 'drl', 'rt'] if v.lower() not in valid_layouts: raise ValueError(f"layout must be one of {valid_layouts}") return v.lower() @field_validator('root', 'n_jobs') def validate_positive_integers(cls, v: Optional[int]) -> Optional[int]: """Validate positive integers where applicable""" if v is not None and v <= 0: raise ValueError("must be a positive integer") return v
- src/scmcp/tool/tl.py:27-31 (registration)Creates the MCP Tool object for 'draw_graph' with name, description, and input schema from DrawGraphModel.draw_graph_tool = types.Tool( name="draw_graph", description="Force-directed graph drawing for visualization", inputSchema=DrawGraphModel.model_json_schema(), )
- src/scmcp/tool/tl.py:148-148 (registration)Registers the draw_graph_tool in the tl_tools dictionary used for tool collection."draw_graph": draw_graph_tool,
- src/scmcp/tool/tl.py:128-128 (helper)Maps the 'draw_graph' tool name to the underlying scanpy.tl.draw_graph function in tl_func dictionary."draw_graph": sc.tl.draw_graph,
- src/scmcp/tool/tl.py:164-177 (handler)Generic handler that executes tl tools including 'draw_graph' by looking up the function from tl_func, passing validated arguments, running on active adata, and logging.def run_tl_func(ads, func, arguments): adata = ads.adata_dic[ads.active] if func not in tl_func: raise ValueError(f"Unsupported function: {func}") run_func = tl_func[func] parameters = inspect.signature(run_func).parameters kwargs = {k: arguments.get(k) for k in parameters if k in arguments} try: res = run_func(adata, **kwargs) add_op_log(adata, run_func, kwargs) except Exception as e: logger.error(f"Error running function {func}: {e}") raise return