Get the class landscape of an ontology as SVG, colored by role
type: Nanopublication
has assertion: assertion
has provenance: provenance
has publication info: pubinfo
created: 2026-08-26T14:17:15Z
creator: Tobias Kuhn
license: https://creativecommons.org/publicdomain/zero/1.0/
embeds: Get the class landscape of an ontology as SVG, colored by role

sig
has algorithm: RSA
signed by: Tobias Kuhn

Get the class landscape of an ontology as SVG, colored by role
type: grlc-query
description: Renders the classes of the given ontology or vocabulary as an inline SVG figure: an Euler ('Venn-style') diagram in which every class is one small dot, positioned by which of four sets it belongs to and colored by its role. The four sets are: whether the class sits in a chemical group (it declares an rdfs:subClassOf other than the vocabulary's top class peh:BioChemEntity), whether it is a metabolite of another entity (peh:isMetaboliteOf), whether it is an isomer of another entity (peh:isIsomerOf), and whether it has a role (obo:RO_0000087). Metabolite and isomer are disjoint in this data and every isomer is also in a chemical group, so the isomer set is drawn nested inside the chemical-group set; the sets are drawn as overlapping rounded rectangles rather than circles, so that each resulting region holds an exactly aligned grid of dots, and a class in none of the four sets sits in the surrounding 'universe' frame. Each region is annotated with its own count and each set with its total. The eight largest roles get their own color, ranked at query time by how many classes of the vocabulary they cover, with separate shades for a smaller one and for classes that have none; the legend is generated from the same ranking and gives each one's full size. Within every region the dots are ordered by that same ranking before being laid out, so classes sharing a role form a contiguous run of one color rather than being scattered through the region. This query has a sibling that is identical except that it colors and orders by chemical group instead, so the two can be shown side by side; there is also an earlier, denser variant ('Get the class landscape of an ontology as SVG') that subdivides the chemical-group and role sets into labelled sub-boxes instead of using color. Role identifiers are normalised to a CHEBI:NNNNN key, so that the same role expressed as an obolibrary or an identifiers.org URI counts once, and their display names are supplied by a lookup table inside the que…
license: LICENSE-2.0
sparql: prefix owl: <http://www.w3.org/2002/07/owl#> prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> prefix dct: <http://purl.org/dc/terms/> prefix np: <http://www.nanopub.org/nschema#> prefix npa: <http://purl.org/nanopub/admin/> prefix npx: <http://purl.org/nanopub/x/> prefix gen: <https://w3id.org/kpxl/gen/terms/> prefix peh: <https://w3id.org/peh/terms/> prefix obo: <http://purl.obolibrary.org/obo/> prefix foaf: <http://xmlns.com/foaf/0.1/> prefix xsd: <http://www.w3.org/2001/XMLSchema#> select ?svg where { { select (group_concat(?cellBlock; separator="") as ?body) (sum(?ccount) as ?total) (sum(if(contains(?sets, "G"), ?ccount, 0)) as ?nGroup) (sum(if(contains(?sets, "M"), ?ccount, 0)) as ?nMet) (sum(if(contains(?sets, "I"), ?ccount, 0)) as ?nIso) (sum(if(contains(?sets, "R"), ?ccount, 0)) as ?nRole) where { { select ?sets ?x0 ?y0 ?cols (count(?class) as ?ccount) (group_concat(?dot; separator="") as ?dots) where { { select ?class ?label ?sets ?groupKey ?roleKey ?parentLabel ?ci (count(?o2) - 1 as ?rank) where { { select ?class ?label (?sets_ as ?sets) (?groupKey_ as ?groupKey) (?roleKey_ as ?roleKey) (?parentLabel_ as ?parentLabel) (?ci_ as ?ci) (min(?sortkey_) as ?sortkey) where { values ?_ontology_multi_iri {} service <https://w3id.org/np/l/nanopub-query-1.1/repo/spaces> { select (group_concat(?mpk; separator=" ") as ?memberPubkeys) where { graph npa:graph { npa:thisRepo npa:hasCurrentSpaceState ?stateG . } values ?_ontology_multi_iri {} graph ?stateG { ?_ontology_multi_iri npa:isMaintainedBy? ?space . ?ri a gen:RoleInstantiation ; npa:forSpace ?space ; npa:forAgent ?agent ; npa:hasRoleType ?rt . filter(?rt in (gen:AdminRole, gen:MaintainerRole, gen:MemberRole)) ?acct a npa:AccountState ; npa:agent ?agent ; npa:pubkey ?mpk . } } } graph npa:graph { ?np npx:hasNanopubType owl:Class ; npa:hasValidSignatureForPublicKeyHash ?pubkey ; dct:created ?date ; npx:introduces ?class ; np:hasAssertion ?a . filter not exists { ?npx npx:invalidates ?np ; npa:hasValidSignatureFo…