Visualization

fs.viz is a VizView — it builds renderable slices of the graph (the interactive Layer A tree, entity neighbourhoods, the backbone, ontology subtrees) and hands them to a pluggable renderer. See the visualization guide for usage.

VizView

.. py:class:: VizView(fs)

module:

foodscholar.viz.view

Bases: :py:class:object

User-facing visualization handle. Exposed as fs.viz.

Each method builds a VizGraph for one abstraction level and wraps it in a RenderableGraph so the caller can immediately chain .render(...).

.. py:method:: VizView.entity_histogram(*, prefix=None, k=30)

module:

foodscholar.viz.view

Top-k entities by chunk_count. Best rendered with matplotlib.

.. py:method:: VizView.entity_neighborhood(ontology_id, *, max_chunks=12, max_co_entities=25)

module:

foodscholar.viz.view

Anchor entity + mentioning chunks + co-mentioned entities.

.. py:method:: VizView.shelf(shelf_id, *, max_chunks=12)

module:

foodscholar.viz.view

One shelf + its themes + chunks (requires Layer A).

.. py:method:: VizView.backbone(*, facet=None, include_cards=True)

module:

foodscholar.viz.view

Full Layer A/B/C backbone — shelves, themes, cards.

.. py:method:: VizView.layer_a_tree(facet=’foods’)

module:

foodscholar.viz.view

Full Layer A shelf tree, themes grouped by origin + their Layer C cards.

facet=None renders the entire graph across all facets in one tree. Best rendered with the "tree" backend: fs.viz.layer_a_tree("foods").render("tree", output="tree.html") or fs.viz.layer_a_tree(facet=None).render("tree", output="full_graph.html").

.. py:method:: VizView.bertopic_pernode(*, facet=’foods’, scope=None, min_chunks=None)

module:

foodscholar.viz.view

Per-node BERTopic explorer — fits BERTopic per shelf node and surfaces its flat topics + the Layer C card for its theme, as a collapsible HTML.

facet=None renders every facet (each a top-level branch), so it covers non-foods / non-FOODON: entities too. scope / min_chunks default to config.layer_b.bertopic. Render with::

fs.viz.bertopic_pernode(facet="foods").render(output="explorer.html")

Needs the [bertopic] extra (lazy-imported). Returns a PernodeExplorer whose .render(output=...) writes the HTML.

.. py:method:: VizView.ontology_subtree(ontology_id, *, max_descendants=30, include_ancestors=True)

module:

foodscholar.viz.view

FoodOn ancestors + descendants of ontology_id.

Renderable graph model

The renderer-agnostic intermediate representation a view produces.

.. py:pydantic_model:: VizGraph

module:

foodscholar.viz.model

Bases: :py:class:~pydantic.main.BaseModel

A typed graph the renderers consume.

Layout is the renderer’s job — VizGraph only describes structure + styling hints. Build it via foodscholar.viz.builder.* functions, render it via foodscholar.viz.renderers.*.

Fields:
  • py:

    obj:attrs (dict[str, Any]) <foodscholar.viz.model.VizGraph.attrs>

  • py:

    obj:edges (list[foodscholar.viz.model.VizEdge]) <foodscholar.viz.model.VizGraph.edges>

  • py:

    obj:level (Literal['L0', 'L1', 'L2', 'L3', 'L4']) <foodscholar.viz.model.VizGraph.level>

  • py:

    obj:nodes (list[foodscholar.viz.model.VizNode]) <foodscholar.viz.model.VizGraph.nodes>

  • py:

    obj:title (str) <foodscholar.viz.model.VizGraph.title>

.. py:pydantic_field:: VizGraph.level

module:

foodscholar.viz.model

type:

Literal[‘L0’, ‘L1’, ‘L2’, ‘L3’, ‘L4’]

required:

.. py:pydantic_field:: VizGraph.attrs :module: foodscholar.viz.model :type: dict[str, Any] :optional:

.. py:pydantic_model:: VizNode

module:

foodscholar.viz.model

Bases: :py:class:~pydantic.main.BaseModel

A single node in a VizGraph.

Fields:
  • py:

    obj:attrs (dict[str, Any]) <foodscholar.viz.model.VizNode.attrs>

  • py:

    obj:facet (str | None) <foodscholar.viz.model.VizNode.facet>

  • py:

    obj:id (str) <foodscholar.viz.model.VizNode.id>

  • py:

    obj:kind (Literal['entity', 'chunk', 'shelf', 'theme', 'card', 'ontology_term', 'anchor']) <foodscholar.viz.model.VizNode.kind>

  • py:

    obj:label (str) <foodscholar.viz.model.VizNode.label>

  • py:

    obj:weight (float) <foodscholar.viz.model.VizNode.weight>

.. py:pydantic_field:: VizNode.id

module:

foodscholar.viz.model

type:

str

required:

.. py:pydantic_field:: VizNode.label :module: foodscholar.viz.model :type: str :required:

.. py:pydantic_field:: VizNode.weight :module: foodscholar.viz.model :type: float :value: 1.0

.. py:pydantic_field:: VizNode.facet :module: foodscholar.viz.model :type: str | None :value: None

.. py:pydantic_field:: VizNode.attrs :module: foodscholar.viz.model :type: dict[str, Any] :optional:

.. py:pydantic_model:: VizEdge

module:

foodscholar.viz.model

Bases: :py:class:~pydantic.main.BaseModel

A directed edge between two VizNodes.

Fields:
  • py:

    obj:attrs (dict[str, Any]) <foodscholar.viz.model.VizEdge.attrs>

  • py:

    obj:kind (str) <foodscholar.viz.model.VizEdge.kind>

  • py:

    obj:source (str) <foodscholar.viz.model.VizEdge.source>

  • py:

    obj:target (str) <foodscholar.viz.model.VizEdge.target>

  • py:

    obj:weight (float) <foodscholar.viz.model.VizEdge.weight>

.. py:pydantic_field:: VizEdge.kind

module:

foodscholar.viz.model

type:

str

required:

.. py:pydantic_field:: VizEdge.weight :module: foodscholar.viz.model :type: float :value: 1.0