Spaces:
Running
Running
| #Developed by ruslanmv.com | |
| import gradio as gr | |
| import matplotlib.pyplot as plt | |
| import networkx as nx | |
| from owlready2 import * | |
| import difflib | |
| import tempfile | |
| import os | |
| def plot_ontology(search_term, owl_file): | |
| """ | |
| Loads an ontology OWL file, builds a graph of its classes and subclass relationships, | |
| performs fuzzy matching to find nodes similar to the search term, and returns a plot | |
| highlighting the matching nodes (and their immediate neighbors) in pink. | |
| Args: | |
| search_term (str): The search term used for fuzzy matching on node names. | |
| owl_file (file): An uploaded ontology file in OWL format. | |
| Returns: | |
| A tuple with: | |
| - The file path of the saved plot image. | |
| - A text message with search result details. | |
| """ | |
| if owl_file is None: | |
| return None, "Please upload an ontology OWL file." | |
| # Load the ontology from the provided file. | |
| try: | |
| # Append temporary directory to the ontology search path. | |
| onto_path.append(tempfile.gettempdir()) | |
| # Load the ontology using its file URI. | |
| onto = get_ontology("file://"+owl_file.name).load() | |
| except Exception as e: | |
| return None, f"Error loading ontology: {e}" | |
| # Build a directed graph: nodes represent ontology classes and edges represent subclass relationships. | |
| G = nx.DiGraph() | |
| for cls in onto.classes(): | |
| G.add_node(cls.name, iri=cls.iri) | |
| for parent in cls.is_a: | |
| if isinstance(parent, ThingClass): | |
| G.add_edge(parent.name, cls.name) | |
| # Define a helper function for fuzzy searching nodes. | |
| def fuzzy_search(query, cutoff=0.6): | |
| query = query.lower() | |
| lower_to_orig = {node.lower(): node for node in G.nodes} | |
| lower_nodes = list(lower_to_orig.keys()) | |
| matches = difflib.get_close_matches(query, lower_nodes, cutoff=cutoff) | |
| return [lower_to_orig[m] for m in matches] | |
| search_results = fuzzy_search(search_term) | |
| if not search_results: | |
| result_message = f"No matches found for '{search_term}'." | |
| else: | |
| result_message = f"Found nodes: {', '.join(search_results)}" | |
| # Determine which nodes to highlight: matched nodes plus their immediate neighbors (parents and children). | |
| highlight_nodes = set() | |
| for node in search_results: | |
| highlight_nodes.add(node) | |
| highlight_nodes.update(G.predecessors(node)) | |
| highlight_nodes.update(G.successors(node)) | |
| # Create the graph layout and plot. | |
| pos = nx.spring_layout(G, k=0.5, iterations=50) | |
| plt.figure(figsize=(12, 8)) | |
| node_colors = ['pink' if node in highlight_nodes else 'lightblue' for node in G.nodes] | |
| nx.draw(G, pos, with_labels=True, node_size=1500, node_color=node_colors, font_size=10, arrows=True) | |
| plt.title("Ontology Graph with Highlighted Related Nodes\n" + result_message) | |
| # Save the plot to a temporary file and close the plot. | |
| tmpfile = tempfile.NamedTemporaryFile(suffix='.png', delete=False) | |
| plt.savefig(tmpfile.name, format="png") | |
| plt.close() | |
| return tmpfile.name, result_message | |
| # Load default file and search term | |
| default_owl_path = "genai.owl" | |
| default_search_term = "LoRa" | |
| with open(default_owl_path, "rb") as f: | |
| default_owl_bytes = f.read() | |
| # Create a temporary file to store the default OWL content | |
| temp_owl_file = tempfile.NamedTemporaryFile(delete=False, suffix=".owl") | |
| temp_owl_file.write(default_owl_bytes) | |
| temp_owl_file.close() | |
| # Define the Gradio interface. | |
| iface = gr.Interface( | |
| fn=plot_ontology, | |
| inputs=[ | |
| gr.Textbox(lines=1, label="Search Term", placeholder="Enter a search term (e.g., LoRa)", value=default_search_term), | |
| gr.File(label="Upload Ontology OWL File", value=temp_owl_file.name) | |
| ], | |
| outputs=[ | |
| gr.Image(type="filepath", label="Ontology Graph"), | |
| gr.Textbox(label="Search Result Details") | |
| ], | |
| title="Ontology Explorer", | |
| description="Upload an ontology OWL file and enter a search term to visualize the ontology graph. " | |
| "Nodes matching the search term and their immediate neighbors (parents and children) are highlighted in pink." | |
| "Reference of the Ontology Loaded: [GENAI](https://bioportal.bioontology.org/ontologies/GENAI)", | |
| examples=[ | |
| ["LoRa", "genai.owl"], | |
| ["LLM", "genai.owl"], | |
| ["RLHF", "genai.owl"] | |
| ], | |
| cache_examples=True | |
| ) | |
| if __name__ == "__main__": | |
| iface.launch(share=True) |