MTG Tutorial - Analysis#

MTG is an OpenAlea model. MTG (Multiscale Tree Graph) allows to represent plant architecture on a graph at different scales.

Also, you may want to extract topological data from a MTG.

In this tutorial, we will work on a part of a Noylum MTG.

For that we will follow different steps:

  • Load the tree digitised MTG

  • Explore the MTG as an architectural database

    • number of vertices

    • class of vertices

    • number of scales

    • properties

In order to make all these graphs, we used Pyvis.

Introduction#

First, let’s import the packages we need for the tutorial.

[1]:
import openalea
from openalea.mtg import *
from openalea.mtg.data import data_dir
from openalea.widgets.mtg import plot
from openalea.widgets.plantgl import PlantGL

Some vocabulary :

  • MTG data structure : g

  • Vertex identifier: vid

Load and Display the MTG#

Now, we collect MTG data.

[2]:
g = MTG(data_dir/'boutdenoylum2.mtg')

We plot the MTG. Different colors represent different complexes and each complex begins with a box node which is the component root.

Notice that you can click and drag on a particuliar node to make it move. Also, you can see some properties of the node by putting you mouse over a node.

[3]:
plot(g)
[3]:

MTG Extraction and Visualisation#

Scales and Classes represent modularities#

Scale 1: P = Plant#

Scale 2: A = Axes#

Scale 3 : Growth Unit#

  • S : Shoot

  • U : Unit

Let’s find the number of scales in the MTG and print how many vertices per scale and the classes in each scale.

[4]:
nb_scales = g.nb_scales()

# Print the vertices at different scales
for scale in range(1, nb_scales):
    print('Nb vertices at scale ', scale, ': ', g.nb_vertices(scale=scale))
    print('Classes : ', list(set(g.class_name(vid) for vid in g.vertices(scale=scale))))
Nb vertices at scale  1 :  1
Classes :  ['P']
Nb vertices at scale  2 :  63
Classes :  ['A']
Nb vertices at scale  3 :  198
Classes :  ['U', 'S']

Actually, the default scale is the max scale (3 here) but you can change it to plot it at a different scale.

[5]:
plot(g, scale=g.max_scale()-1)
[5]:

We can select all the vertices of each class.

[6]:
classes = list(set(g.class_name(vid) for vid in g.vertices() if g.class_name(vid)))
print(classes)

def vertices(g, class_name='P'):
    return [vid for vid in g.vertices() if g.class_name(vid)==class_name]

vids_U = vertices(g, 'U')
print('Nb U', len(vids_U))
['P', 'U', 'S', 'A']
Nb U 84

Let’s plot the graph with the selected vertices corresponding to the U class.

[7]:
plot(g, selection=vids_U)
[7]:

Property Extraction#

Let’s go on by displaying a whole property through the graph.

[8]:
# Properties on the MTG: this exclude all the topological properties
print(g.property_names())

# Retrieve one property for the MTG (dict)
phi = g.property('phi')
['edge_type', 'label', 'index', 'Dist', 'El1', 'Az1', 'Inc', 'Azm', 'XX', 'YY', 'ZZ', 'psi', 'teta', 'phi', 'TopDia', 'NFe', 'Nf', 'Lum1', 'Lum2', 'Lum3', 'Lum4', '_line', 'position']

Once you’ve extracted the ‘phi’ dictionary. You can change the labels of the graph nodes with it.

Now, if you zoom in a node, you will see that the labels have changed.

[9]:
plot(g, labels=phi)
[9]:

Trunk Extraction#

In this part, we will make our first selections on the MTG and visualise them. Let’s begin with the trunk.

[10]:
root = next(g.roots_iter(scale=g.max_scale()))
trunk = g.Trunk(root)

Now we have the selection of the trunk, we can visualise it.

[11]:
plot(g, selection=trunk)
[11]:

Leaves Extraction#

Let’s select the leaves and display them.

[12]:
leaves = [vid for vid in g.vertices(scale=g.max_scale()) if g.is_leaf(vid)]
plot(g, selection=leaves)
[12]:

Component Roots Extraction#

Now, we select the first component of each complex, which are the component roots.

[13]:
c_roots = [next(g.component_roots_at_scale_iter(cid, scale=g.max_scale())) for cid in g.vertices(scale=g.max_scale()-1)]
plot(g, selection=c_roots)
[13]:

Descendants Extraction#

Here, we select all the descendants of one particuliar node.

[14]:
root_id = 139
s = g.Descendants(root_id)
plot(g, selection=s, cdn_resources='in_line')
[14]:

PlantFrame 3D#

Now, we can display the MTG in 3D. You can check the PlantFrame tutorial.

[15]:
drf = data_dir/'walnut.drf'
dressing_data = dresser.dressing_data_from_file(drf)
dressing_data = plantframe.DressingData(DiameterUnit=10)
pf = plantframe.PlantFrame(g, TopDiameter='TopDia', DressingData = dressing_data)
scene = pf.plot(gc=True, display=False)
PlantGL(scene)

[15]:
[ ]:

[ ]: