# Data Providers
Networks and trees can be represented in different data structures. For instance, in `igraph` nodes are ordered and numbered, while in `networkx` they are neither.

`iplotx` is designed to accept data of any kinds as long as it can understand how to
process it into a visualisation. This flexibility is achieved through **data providers**.

A **network data provider** is a class that satisfies the `NetworkDataProvider` protocol, i.e. it implements a few functions that help `iplotx` understand how to ingest
data.

Similarly, a **tree data provider** is a class that satisfies the `TreeDataProvider` protocol, i.e. it implements those few functions. It is the tree-specific equivalent of the previous case.

See <project:api/providers.md> for the exact protocols.

## An example: Simple network data provider
While `igraph`, `networkx` and the likes can be quite complicated, `iplotx` also provides a simple dict-based `NetworkDataProvider` for educational purposes. The network data structure in this case is the following:

```python
  network : dict[str, Sequence | bool] = {
      "vertices": ["alice", "bob", "jago"],
      "edges": [
          ("alice", "bob"),
          ("bob", "jago"),
          ("alice", "jago"),
      ],
      "directed": False,
  }
```

It is a simple dictionary with a key for vertices, one for edges, and one for directedness. Only the key for edges is required. If missing, directedness is assumed to be `False`. If vertices are missing, they are inferred from the edges (singletons will be missed - there are none in the example above).


A straightforward `NetworkDataProvider` implementation for this network data structure is found in `iplotx/ingest/providers/network/simple.py`. As a result, it is possible to ingest networks in this new format for visualisation:

```python
    import iplotx as ipx
    network = {
        "edges": [
            ("alice", "bob"),
            ("bob", "jago"),
            ("alice", "jago"),
        ]
    }
    layout = {
        "alice": (0, 0),
        "bob": (1, 1),
        "jago": (1, 0),
    }
    ipx.plot(
        network,
        layout,
    )
```

See <project:gallery/plot_simpledataprovider.md> for the full gallery example including vertex labels and styling.

```{tip}
  This example also shows how to use `iplotx` without installing any network analysis
  library. You'll still need `matplotlib` for plotting and `numpy` and `pandas` for
  internal number crunching.
```


## Creating a custom data provider
`iplotx` is able to seek new data providers at runtime, but they need to be registered in a specific way (keyword: `entry point`).

The expected entry point for a `NetworkDataProvider` is: `iplotx.network_data_providers`.

The expected entry point for a `TreeDataProvider` is: `iplotx.tree_data_providers`.

```{note}
  If you would like to make a library compatible with `iplotx` (by developing a provider), we are here to help! Just reach out on GitHub issues and we will try to help.
```
