diff --git a/README.md b/README.md index 23536e8..06f5f58 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ Find paths between node A and node B in the Translator KG
Find a subnetwork given a list of nodes in the Translator KG
Developer-friendly wrappers for resolving labels/CURIEs, caching Translator resources, and returning parsed finder results
Connecting user's API with Translator API
+*Note: Visualization capabilities (pyvis, matplotlib, seaborn) can be installed separately via the `vision` extra.* ## How to use TCT @@ -34,8 +35,13 @@ pip install TCT # TCT is in development, to get the most recent update, user can install it through the github repo ``` -**This the recommended approach for installation.** +**This is the recommended approach for a minimal installation.** +Visualization support is optional. Install it with the `vision` extra when you need the plotting and graph-rendering utilities: + +```bash +pip install "TCT[vision]" +``` #### Development Installation @@ -57,6 +63,12 @@ cd Translator_component_toolkit uv sync ``` +To include visualization support in the UV environment: + +```bash +uv sync --extra vision +``` + #### Building and Deployment **Using pip:** - Build: `python -m build` diff --git a/TCT/TCT.py b/TCT/TCT.py index 63abcd5..ee42e0e 100644 --- a/TCT/TCT.py +++ b/TCT/TCT.py @@ -4,17 +4,12 @@ import requests import json import pandas as pd -import seaborn as sns -import matplotlib.pyplot as plt -import networkx as nx import numpy as np #import openai from . import name_resolver, node_normalizer, translator_query # plt.switch_backend('module://ipykernel.pylab.backend_inline') -from IPython.display import display - __all__ = [ 'TCT_help', 'list_functions', @@ -851,6 +846,9 @@ def plot_heatmap(predicates_by_nodes_df,num_of_nodes = 20, fontsize = 6, title_fontsize = 10, output_png="NE_heatmap.png"): + import matplotlib.pyplot as plt + import seaborn as sns + #matplotlib.use('Agg') #title = "Ranking of one-hop nodes by primary infores" @@ -891,7 +889,8 @@ def plot_heatmap_ui(predicates_by_nodes_df,num_of_nodes = 20, fontsize = 6, title_fontsize = 10, output_png="NE_heatmap.png"): - + import matplotlib.pyplot as plt + import seaborn as sns title = "Ranking of one-hop nodes by primary infores" ylab = "infores" @@ -1658,7 +1657,8 @@ def merge_by_ranking_index(result_ranked_by_primary_infores, title_fontsize = 12, fontsize = 12, ): - + import matplotlib.pyplot as plt + import seaborn as sns dic_rank1 = {} for i in range(0, result_ranked_by_primary_infores.shape[0]): @@ -1774,6 +1774,9 @@ def plot_path_bar(x, fontsize = 8, title_fontsize = 10, output_png="NE_heatmap.png"): + import matplotlib.pyplot as plt + import seaborn as sns + #matplotlib.use('Agg') # title = "Bridging nodes" # Unused variable @@ -1965,6 +1968,9 @@ def select_result_to_analysis(sele_genes,Temp_result_df1, Temp_result_df2 ): def plot_graph_by_predicates(for_plot): + import networkx as nx + from IPython.display import display + graph = nx.from_pandas_edgelist(for_plot, source='Subject', target='Object', @@ -2013,6 +2019,8 @@ def plot_graph_by_predicates(for_plot): def plot_graph_by_infores(for_plot): + import networkx as nx + from IPython.display import display graph = nx.from_pandas_edgelist(for_plot, source='Subject', @@ -2062,6 +2070,8 @@ def plot_graph_by_infores(for_plot): def plot_graph_by_API(for_plot): + import networkx as nx + from IPython.display import display graph = nx.from_pandas_edgelist(for_plot, source='Subject', @@ -2273,6 +2283,9 @@ def load_translator_resources(): def visulize_path(input_node1_id, intermediate_node, input_node3_id, result, result2): + import networkx as nx + from IPython.display import display + forplot_subject = [] forplot_object = [] forplot_predicate = [] diff --git a/TCT/TCT_Visualization.py b/TCT/TCT_Visualization.py index 1f00d0a..7f33279 100644 --- a/TCT/TCT_Visualization.py +++ b/TCT/TCT_Visualization.py @@ -1,9 +1,6 @@ from .node_normalizer import ID_convert_to_preferred_name_nodeNormalizer -import networkx as nx -from pyvis.network import Network - def visualize_neighborhood_graph(result, show_label=True, height="1000px", width="100%", output_filename_prefix=None): '''Visualize the neighborhood graph using pyvis Args: @@ -18,6 +15,9 @@ def visualize_neighborhood_graph(result, show_label=True, height="1000px", width dic_graph = visualize_neighborhood_graph(result, show_label=True, height="500", width="100%") ''' + import networkx as nx + from pyvis.network import Network + # Your JSON (as Python dict) data = result IDs = [] diff --git a/docs/source/intro.md b/docs/source/intro.md index 0f98471..ad4625b 100644 --- a/docs/source/intro.md +++ b/docs/source/intro.md @@ -12,6 +12,7 @@ Allowing testing whether a user defined API follows a [TRAPI](https://github.com Faciliting to explore knowledge graphs from both Translator ecosystem and user defined APIs.
Developer-friendly `pathfinder` and `neighborhood_finder` wrappers for resolving labels/CURIEs, caching Translator resources, and returning parsed finder results (`from TCT import pathfinder, neighborhood_finder`).
Connecting large language models to convert user's questions into TRAPI queries.
+*Note: Visualization capabilities (pyvis, matplotlib, seaborn) can be installed via the `vision` extra using `pip install TCT[vision]`* ### Contributing TCT is a tool that helps to explore knowledge graphs developed in the Biomedical Data Translator Consortium. Consortium members and external contributors are encouraged to submit issues and pull requests. @@ -22,7 +23,17 @@ Guangrong Qin, guangrong.qin@isbscience.org ## How to use TCT ### Install Requirements -To install TCT as a python library, you can install the library using `pip install TCT` from the command line. +To install the minimal TCT package, run: + +```bash +pip install TCT +``` + +Visualization support is optional. Install it with the `vision` extra when you need the plotting and graph-rendering utilities: + +```bash +pip install "TCT[vision]" +``` The TCT is continuously updated, if you would like to use the latest functions, you can also clone this most recent github repository (https://github.com/NCATSTranslator/Translator_component_toolkit/tree/main), `git clone https://github.com/NCATSTranslator/Translator_component_toolkit.git` diff --git a/pyproject.toml b/pyproject.toml index 89f02d8..9ed4db2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,20 +24,21 @@ dependencies = [ "requests", "jsons", "pandas", - "seaborn", - "matplotlib", - "ipycytoscape", - "networkx", "numpy", "openai", "ipykernel", - 'networkx', - 'igraph', - 'pyvis', - 'zstandard', + "igraph", + "zstandard", ] [project.optional-dependencies] +vision = [ + "ipycytoscape", + "matplotlib", + "networkx", + "pyvis", + "seaborn", +] mcp = [ "fastmcp>=2.12.2", "click>=8.2.1", diff --git a/uv.lock b/uv.lock index 7eb6e9c..bba587a 100644 --- a/uv.lock +++ b/uv.lock @@ -2788,19 +2788,13 @@ version = "0.2.0" source = { editable = "." } dependencies = [ { name = "igraph" }, - { name = "ipycytoscape" }, { name = "ipykernel" }, { name = "jsons" }, - { name = "matplotlib" }, - { name = "networkx", version = "3.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "networkx", version = "3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, { name = "numpy", version = "2.3.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "openai" }, { name = "pandas" }, - { name = "pyvis" }, { name = "requests" }, - { name = "seaborn" }, { name = "zstandard" }, ] @@ -2809,6 +2803,14 @@ mcp = [ { name = "click" }, { name = "fastmcp" }, ] +vision = [ + { name = "ipycytoscape" }, + { name = "matplotlib" }, + { name = "networkx", version = "3.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "networkx", version = "3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "pyvis" }, + { name = "seaborn" }, +] [package.dev-dependencies] dev = [ @@ -2824,20 +2826,20 @@ requires-dist = [ { name = "click", marker = "extra == 'mcp'", specifier = ">=8.2.1" }, { name = "fastmcp", marker = "extra == 'mcp'", specifier = ">=2.12.2" }, { name = "igraph" }, - { name = "ipycytoscape" }, + { name = "ipycytoscape", marker = "extra == 'vision'" }, { name = "ipykernel" }, { name = "jsons" }, - { name = "matplotlib" }, - { name = "networkx" }, + { name = "matplotlib", marker = "extra == 'vision'" }, + { name = "networkx", marker = "extra == 'vision'" }, { name = "numpy" }, { name = "openai" }, { name = "pandas" }, - { name = "pyvis" }, + { name = "pyvis", marker = "extra == 'vision'" }, { name = "requests" }, - { name = "seaborn" }, + { name = "seaborn", marker = "extra == 'vision'" }, { name = "zstandard" }, ] -provides-extras = ["mcp"] +provides-extras = ["vision", "mcp"] [package.metadata.requires-dev] dev = [