# Basics

```
using Graphs
using MetaGraphsNext
```

## Creating an empty `MetaGraph`

We provide a convenience constructor for creating empty graphs, which looks as follows:

```
colors = MetaGraph(
Graph(); # underlying graph structure
label_type=Symbol, # color name
vertex_data_type=NTuple{3,Int}, # RGB code
edge_data_type=Symbol, # result of the addition between two colors
graph_data="additive colors", # tag for the whole graph
)
```

`Meta graph based on a SimpleGraph{Int64} with vertex labels of type Symbol, vertex metadata of type Tuple{Int64, Int64, Int64}, edge metadata of type Symbol, graph metadata given by "additive colors", and default weight 1.0`

The `label_type`

argument defines how vertices will be referred to. It can be anything you want, provided that pairs of labels can be compared with `<`

. Integer types are generally discouraged, to avoid confusion with the vertex codes used by Graphs.jl. The `vertex_data_type`

and `edge_data_type`

type determine what kind of data will be associated with each vertex and edge. Finally, `graph_data`

can contain an arbitrary object associated with the graph as a whole.

If you don't care about labels at all, using the integer vertex codes as labels may be reasonable. Just keep in mind that labels do not change with vertex deletion, whereas vertex codes get decreased, so the coherence will be broken.

## Modifying the graph

Modifications of graph elements and the associated metadata can always be done using `setindex!`

(as in a dictionary) with the relevant labels.

### Vertices

Use `setindex!`

with one key to add a new vertex with the given label and metadata. If a vertex with the given label does not exist, it will be created automatically. Otherwise, the function will simply modify the metadata for the existing vertex.

```
colors[:red] = (255, 0, 0);
colors[:green] = (0, 255, 0);
colors[:blue] = (0, 0, 255);
```

Note that you cannot use labels or metadata that is incoherent with the types you specified at construction.

### Edges

Use `setindex!`

with two keys to add a new edge between the given labels and containing the given metadata. Beware that this time, an edge will only be added when both node labels already exist in the graph.

```
colors[:red, :green] = :yellow;
colors[:red, :blue] = :magenta;
colors[:green, :blue] = :cyan;
```

## Creating a non-empty `MetaGraph`

There is an alternative constructor which allows you to build and fill the graph in one fell swoop. Here's how it works:

```
graph = Graph(Edge.([(1, 2), (1, 3), (2, 3)]))
vertices_description = [:red => (255, 0, 0), :green => (0, 255, 0), :blue => (0, 0, 255)]
edges_description = [
(:red, :green) => :yellow, (:red, :blue) => :magenta, (:green, :blue) => :cyan
]
colors2 = MetaGraph(graph, vertices_description, edges_description, "additive colors")
colors2 == colors
```

`false`

## Accessing graph properties

To retrieve graph properties, we still follow a dictionary-like interface based on labels.

### Existence

To check the presence of a vertex or edge, use `haskey`

:

`haskey(colors, :red)`

`true`

`haskey(colors, :black)`

`false`

`haskey(colors, :red, :green) && haskey(colors, :green, :red)`

`true`

`!haskey(colors, :red, :black)`

`true`

### Metadata

All kinds of metadata can be accessed with `getindex`

:

`colors[]`

`"additive colors"`

`colors[:blue]`

`(0, 0, 255)`

`colors[:green, :blue]`

`:cyan`

## Using vertex codes

In the absence of removal, vertex codes correspond to order of insertion in the underlying graph. They are the ones used by most algorithms in the Graphs.jl ecosystem.

`code_for(colors, :red)`

`1`

`code_for(colors, :blue)`

`3`

You can retrieve the associated labels as follows:

`label_for(colors, 1)`

`:red`

`label_for(colors, 3)`

`:blue`

## Listing labels

The functions `labels`

, `edge_labels`

, `(in/out)neighbor_labels`

iterate through labels the same way that `vertices`

, `edges`

and `(in/out)neighbors`

iterate through codes.

`collect(labels(colors))`

```
3-element Vector{Symbol}:
:red
:green
:blue
```

`collect(edge_labels(colors))`

```
3-element Vector{Tuple{Symbol, Symbol}}:
(:red, :green)
(:red, :blue)
(:green, :blue)
```

`collect(neighbor_labels(colors, :red))`

```
2-element Vector{Symbol}:
:green
:blue
```

## Handling weights

You can use the `weight_function`

field to specify a function which will transform edge metadata into a weight. This weight must always have the same type as the `default_weight`

, which is the value returned in case an edge does not exist.

```
weighted = MetaGraph(
Graph();
label_type=Symbol,
edge_data_type=Float64,
weight_function=ed -> ed^2,
default_weight=Inf,
);
weighted[:alice] = nothing;
weighted[:bob] = nothing;
weighted[:charlie] = nothing;
weighted[:alice, :bob] = 2.0;
weighted[:bob, :charlie] = 3.0;
```

`weight_matrix = Graphs.weights(weighted)`

`MetaWeights of size (3, 3)`

`default_weight(weighted)`

`Inf`

`size(weight_matrix)`

`(3, 3)`

`weight_matrix[1, 2]`

`4.0`

`weight_matrix[2, 3]`

`9.0`

`weight_matrix[1, 3]`

`Inf`

```
wf = get_weight_function(weighted)
wf(4.0)
```

`16.0`

You can then use all functions from Graphs.jl that require weighted graphs (see the rest of the tutorial).

*This page was generated using Literate.jl.*