You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
sitc/sna/2_Working_with_Graphs.ipynb

1014 lines
45 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"![](images/EscUpmPolit_p.gif \"UPM\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"# Course Notes for Learning Intelligent Systems"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"Department of Telematic Engineering Systems, Universidad Politécnica de Madrid, © Carlos A. Iglesias"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"## [Introduction to Network Analysis](0_Intro_Network_Analysis.ipynb)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"# Table of Contents\n",
"\n",
"* [Working with Graphs](#Working-with-Graphs)\n",
"* [First steps](#First-steps)\n",
"* [Reading Data from a File](#Reading-Data-from-a-File)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Working with Graphs\n",
"\n",
"\n",
"## Import networkx\n",
"The first thing is importing the package.\n"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"import networkx as nx"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Graph"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"G = nx.Graph()"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Nodes\n",
"NetworkX is very flexible. Nodes can be any hashable object, such as strings, numbers, files, functions, etc."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"G.add_node(1) # integer"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"G.add_node('A') #string"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"import math\n",
"G.add_node(math.cos) #cosine function"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[1, 'A', <built-in function cos>]\n"
]
}
],
"source": [
"print(G.nodes)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Edges\n",
"Edges (links) are represented as tuples of nodes."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"G.add_edge(1, 'A')"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"G.add_edge('B', math.cos)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[(1, 'A'), (<built-in function cos>, 'B')]\n"
]
}
],
"source": [
"print(G.edges)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"## Edge data\n",
"\n",
"Edge data is assigned using a tuple (node1, node2, data). \n",
"\n",
"Default data is {} (empty dictionary), but any Python object is allowed."
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"W = nx.Graph()"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"W.add_edge('A', 'B', weight = 1)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"W.add_weighted_edges_from([('A', 'C', 3), ('A', 'D', 4), ('B', 'D', 2)])"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"data": {
"text/plain": [
"{('A', 'B'): Text(0.34360816042257025, 0.03772295893763749, '1'),\n",
" ('A', 'C'): Text(-0.6125262066395303, 0.16919086402801908, '3'),\n",
" ('A', 'D'): Text(0.04386563293789962, -0.17119492412470283, '4'),\n",
" ('B', 'D'): Text(0.6125262066395304, -0.16919086402801906, '2')}"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAV0AAADnCAYAAAC9roUQAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAAsTAAALEwEAmpwYAAAr80lEQVR4nO3deXxM5/4H8M85s5isY4kkKkiUkFiili4StVRRSxFbGzv5WVtub12t25bS6163V+u2imhvEYJKlaqtVItKLCUVscVSgkQWSibbjFnO8/tjSByTTLaZOTPJ931ffU36PWee853ck2/PPOd5nsMxxkAIIcQxeKkTIISQ2oSKLiGEOBAVXUIIcSAquoQQ4kBUdAkhxIHk1jb6+PiwwMBAB6VCCCE1Q1JS0l3GWMPStlktuoGBgTh16pR9siKEkBqK47gbZW2j7gVCCHEgKrqEEOJAVrsXHEkQDNDrs8GYHhynhFLpB55XSJ0WIYTYlGRFlzEGjSYRWVlrodEkQKe7Do5TgON4MCaAMQNUqiCo1RHw958ItTocHMdJlS4hhNiEw4suYwzZ2XFIS1sAvT4HglAEgD3cZhDtq9VehlZ7BTk5W6BU+iIwcCH8/MZQ8SWEuCyH9unqdOlITu6By5enQ6e7DkEoxKOCWzYGQSiETncdly9PR3JyD+h06Y5IlxBCbM5hRTc3NwEnT4YiL+/ow2JbeYJQiLy8ozh5MhQaTaKNMySEEPtzSNHNzU1ASkpfmEz5YMxYrbYYM8JkyseZM32o8BJCXI7di65Ol46zZ/s/7Lu1HUEoQkrKK9TVQAhxKXYtuowxXLwYBUHQ2qV9QdDi4sXRoIXYCSGuwq6jF7Kz45Cf/3u5XQo3bwLffw+cPg3cuQM8eACo1UCLFkC3bsDLLwNKpeX7GDMiPz8J2dkb4e8/xj4fghBCbIizdpXYuXNnVtW1FxhjOHHiaeh0163uFxsLrF8PCALQpg0QHAy4uQH37wNnzgC3b5tjq1eX3YZK1RzPPXeVhpIRQpwCx3FJjLHOpW2z25WuRpMIvT7H6j5xccC6dYCvL7BgARAaarnPsWNAfLz1Y+n12cjLOwq1OrzqCRNCiAPYrehmZa21evMsK8t8lSuXA0uWAEFBpe/3wgtAp07WjyUIRcjMXENFlxDi9Ox2I02jSYC1iQ979wJGI/Dii2UX3EdK688VYzR8jBDiEuxSdAXBUG5f7tmz5teOHW1zTJ3uGgTBUP6OhBAiIbsUXb0+GxxnfYWwe/fMrw1LXVu98jhOAb0+2zaNEUKIndil6JqXZ3T0Ur08GNM7+JiEEFI5dqmMHKcEY4LVferXN7/euWOrowrguHI7fwkhRFJ2KbpKpZ/FMo1PatfO/Pr777Y5JmMGKJV+tmmMEELsxC5Fl+cVUKmsD0l45RXzcLEjR4C0NOvt6SvQa6BSNacnTRBCnJ7dOl7V6ggAZc8Q8/cHxo8HDAZg3jzg0qXS9/vtN+Ddd8s7GkdjdAkhLsFukyP8/SciJ2eL1bVzx4wBTCbzNOBp08zTgFu1KpkGnJICpKebY9bwvDsaNZpk409ACCG2Z7eiq1aHQ6n0LXe87vjxQI8ewI4d5gVvfvzR3J3g7W1e8Oa118wL3liTozPgaqEKndS2y58QQuzBbkWX4zgEBi7E5cvTy31SRLNmwKxZVTuO1gSs/kOPX44/i9nPzcainovgqfSsWmOEEGJndh1M6+c3Bl5encBx9qntBgG4lA8cyAEEJmDZ8WVos7INdl3eZZfjEUJIddm16HIch5CQjeB5N7u0zyDH4ovi2E3NTQzaPAgjvh2B2/m37XJcQgipKrtPG1OpAtC+/V7wvLtN2+V5dzzX6RBih+9GM3Uzi+1bL2xFyIoQrDq5CkI5EzUIIcRRHDJXV60OR1jYfshkXtXuauA4OWQyL4SF7YdaHY7+Lfvj/IzzePuFtyHjZKJ98x7kYcaeGQhfE46z2WerdVxCCLEFhy2QoFaHo0uXC/D27gqe96hSGzzvAW9vczuPj8v1UHpgaZ+lOPl/J9H5KcvF2o+nH0fHLzti3oF50Brs87w2QgipCIeuSqNSBaBDh0MIDo55OIPMA9YmUJhx4HkPqFTNERwcgw4dDkKlCih1z2caPYPjk4/js36fWYxgMApGLElcgrar2uKnP36yzQcihJBKstsz0srDGENe3lFkZq6BRpMIne7aw+UgeQACGDNApWoOtTocjRpNgrd310o9A+2W5hbe3PsmdlzaUer2qHZRWNZ3GXw9fG3zgQgh5CFrz0iTrOg+SRAM0OuzHy4LqYRS6WeTtRS2X9yON/e+iYz8DItt9VT1sLTPUkzsMJEeakkIsRlrRdfRi96WybxITgDc3JpDpQqw2eI1Q0OG4sLMC3ijyxvgnujKuK+7j8k/TEaP2B5IvZtqk+MRQog1TlN07cm7jjeW91+OY5OPob1fe4vtv974FWExYfjw0Id4YHwgQYaEkNqiVhTdR54LeA6n/u8UPu79Mdzk4gkbepMeCw8vRFhMGA6nHZYoQ0JITVerii4AKGQK/C38bzg/4zz6tehnsf3Sn5fQI7YHJu+YjHvae45PkBBSo9W6ovtIUL0g7Inag83DNsPPw/KJE2uS16D1F60RlxIHazcbCSGkMmpt0QXMa0O81vY1XJx5EVM6TrHYfqfoDsZuH4u+cX3xx70/JMiQEFLT1Oqi+0g9t3pYPWg1jkw8ghCfEIvtP137CW1XtcW/jvwLBpP1Z78RQog1VHQfE9E0AsnTkvFRz49QR1ZHtE1n1OHvv/wdHb/siGO3jkmUISHE1VHRfYJSpsT7L76PlOkp6BnY02L7uZxzCF8Tjhm7ZyBXl+v4BAkhLo2KbhmCGwTj53E/Y93gdWjg1kC0jYFh1alVCFkRgm/Pf0s32gghFUZF1wqO4zC+w3ikvpGK8WHjLbZnFWRh5NaRGLR5EG7k3pAgQ0KIq6GiWwE+7j5YN2Qdfh73M1rUb2GxffeV3QhdGYpPj30Ko2CUIENCiKugolsJvYJ64ez0s3i/2/tQPLE2RJGhCG/vfxvhX4dDZ9RZbcdYVITMxEQYCq0/sJMQUvNQ0a0klVyFj3p9hORpyQhvEm6xvWdQz3Kvdm/98gsufP019kRG4tLGjfZKlRDihKjoVlFow1D8OvFXrB64Guo6agBAM3UzfPDiB+U+Aj6gZ0+ERkej5YgROL96NQ6/8QYe5OY6IGtCiNSo6FYDz/GY0mkKUt9IxWttX0PskFgoZUqr72GMQeHhgUZdu6L1hAmIWLYMBTdvIuMwLbJDSG1ARdcG/D39sXnYZoQ3DYdCVvY6wIwx0WLpvFyO+m3agFcokJmYCMFopOFnhNRwVHRtSM5bf9Ixx3G4n5qK1NjY4lhRZiaYIICXycDL5fQEC0JquOo9D51UWv7Nmzi9dCn+2L4dT0VE4PaRIyjKyUG3zz4DYHk1TAipWehK10GYIAAAmvbpg1e++w4ypRK5ly8jZMIE9IyJgVfTpmCCQAWXkBqOiq6dae/ehUmvB8eX/KrrBgejcY8eKMjIQLP+/eETFgYAon0IITUT/ZXbEWMMJ+bPx6X162HUakXb6oWEQJuTg6KsLImyI4RIgfp07UgwGFCvVStc2bIF4HkEDhgAVf360OfnIzU2FuoWLeDVrJnF+4yCsdybcoQQ10R/2XYkUyoRNns23P38kLJ8OTJ++QUyNzcU3LoF7d276P7FFxbvKdQXIuq7KHTw74B53eZBJVdJkDkhxF44a+NCO3fuzE6dOuXAdGoufV4eUh91MzCGgJdegm+nTuJ9THrs/2M/Bm0eBMC8vGTMgBj0DLJc15cQ4rw4jktijHUudRsVXedRoC9Ay+UtkVUg7ued0GEClr68FA3cG5TxTkKIM7FWdOlGmpNgjOHS3Uulzkhbl7wOrVe0xoYzG2jGGiEujoquk+A4Dp2e6oTUN1IxtdNUi+13i+5i3Pfj8PKGl3H13lUJMiSE2AIVXSdTV1UXMQNjkDAxAaENQy22/3z9Z7Rb1Q7/PPJP6E16CTIkhFQHFV0nFd40HKennsY/ev6j1CcTv/f
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"pos = nx.spring_layout(W) # positions for all nodes\n",
"labels = nx.get_edge_attributes(W,'weight')\n",
"nx.draw_networkx(W, pos=pos, node_size=800, node_color='y', font_size=20)\n",
"nx.draw_networkx_edges(W,pos,width=4, edge_color='g', arrows=False)\n",
"nx.draw_networkx_edge_labels(W,pos,edge_labels=labels, font_color='brown', font_size=15)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"For more info about draw_networkx see the [NetworkX manual](https://networkx.github.io/documentation/networkx-1.10/reference/generated/networkx.drawing.nx_pylab.draw_networkx.html#networkx.drawing.nx_pylab.draw_networkx)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Let's access edges"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'D')]\n"
]
}
],
"source": [
"print(W.edges) # List of all edges; same than W.edges() with default parameters"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[('A', 'B', {'weight': 1}), ('A', 'C', {'weight': 3}), ('A', 'D', {'weight': 4}), ('B', 'D', {'weight': 2})]\n"
]
}
],
"source": [
"print(W.edges(data=True)) # List of all edges with data"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[('A', 'B', 1), ('A', 'C', 3), ('A', 'D', 4), ('B', 'D', 2)]\n"
]
}
],
"source": [
"print(W.edges(data='weight')) # List of all edges with attribute 'weight'"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Let's calculate Dijsktra shortest weighted path:"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"data": {
"text/plain": [
"{('A', 'B'): Text(-0.17186208433735098, -0.2876883893655454, '1'),\n",
" ('A', 'C'): Text(0.10060091197009038, 0.6027184602573036, '3'),\n",
" ('A', 'D'): Text(0.1315138115456491, -0.10959315037715107, '4'),\n",
" ('B', 'D'): Text(-0.10060091197009048, -0.6027184602573037, '2')}"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"pos = nx.spring_layout(W) # positions for all nodes\n",
"labels = nx.get_edge_attributes(W,'weight')\n",
"nx.draw_networkx(W, pos=pos, node_color='red', node_size=600)\n",
"nx.draw_networkx_edges(W,pos,width=4, edge_color='yellow', arrows=False)\n",
"nx.draw_networkx_edge_labels(W,pos,edge_labels=labels, font_color='brown', font_size=15)"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"['C', 'A', 'B', 'D']"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nx.dijkstra_path(W, 'C', 'D')"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## NetworkX design principles\n",
"* \"Node centric\" view of networks\n",
"* Nodes: any hashable object\n",
"* Edges: three tuples (n1, n2, d) with optional edge data\n",
"* Edge data can be defined by users"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"## Network data structure\n",
"* Uses a \"dictionary of dictionaries\""
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"* **G.adj** is the Graph adjacency object: \n",
" * **key**: node; \n",
" * **value**: neighbor-dicts"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'A': {'B': {'weight': 1}, 'C': {'weight': 3}, 'D': {'weight': 4}}, 'B': {'A': {'weight': 1}, 'D': {'weight': 2}}, 'C': {'A': {'weight': 3}}, 'D': {'A': {'weight': 4}, 'B': {'weight': 2}}}\n"
]
}
],
"source": [
"print(W.adj)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Simple operations\n",
"In this way, it is easy..."
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Test if a node is in the graph\n",
"'A' in W"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"A\n",
"B\n",
"C\n",
"D\n"
]
}
],
"source": [
"# loop over all the nodes\n",
"for n in W:\n",
" print(n)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Edge attributes"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"{'weight': 1}"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Access an edge\n",
"\n",
"W['A']['B']"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"{'weight': 1}"
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"W.adj['A']['B']"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"1"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Access an attribute\n",
"W['A']['B']['weight']"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"## Multigraphs"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"0"
]
},
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"MG = nx.MultiGraph()\n",
"MG.add_edge('A', 'B', relation = 'friend', color = 'b', weight = 3)\n",
"MG.add_edge('A', 'B', relation = 'neighbour', color = 'r', weight = 8)\n",
"MG.add_edge('A', 'C', relation = 'father', color = 'c', weight = 1)\n",
"MG.add_edge('A', 'D', relation = 'friend', color = 'b', weight = 2)\n"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{0: {'relation': 'friend', 'color': 'b', 'weight': 3}, 1: {'relation': 'neighbour', 'color': 'r', 'weight': 8}}\n"
]
}
],
"source": [
"#Dictionary per every edge\n",
"print(MG['A']['B'])"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Node attributes"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"G = nx.Graph()"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"G.add_edge('Predeal', 'Bucharest', distance=158)"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"G.add_edge('Predeal', 'Brasov', distance=26.7)"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"G.add_node('Predeal', population=4755)"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"G.add_node('Bucharest', population=1812290)"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"G.add_node('Brasov', population=550547)"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['Predeal', 'Bucharest', 'Brasov']\n"
]
}
],
"source": [
"# List of nodes \n",
"print(G.nodes())"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[('Predeal', {'population': 4755}), ('Bucharest', {'population': 1812290}), ('Brasov', {'population': 550547})]\n"
]
}
],
"source": [
"#list of nodes attributes\n",
"print(G.nodes(data=True))"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"4755\n"
]
}
],
"source": [
"#Access one attribute\n",
"print(G.nodes['Predeal']['population'])"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"# References\n",
"* Networkx tutorial https://networkx.github.io/documentation/stable/tutorial.html"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"## Licence"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"The notebook is freely licensed under under the [Creative Commons Attribution Share-Alike license](https://creativecommons.org/licenses/by/2.0/). \n",
"\n",
"© Carlos A. Iglesias, Universidad Politécnica de Madrid."
]
}
],
"metadata": {
"celltoolbar": "Slideshow",
"datacleaner": {
"position": {
"top": "50px"
},
"python": {
"varRefreshCmd": "try:\n print(_datacleaner.dataframe_metadata())\nexcept:\n print([])"
},
"window_display": false
},
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.7"
},
"latex_envs": {
"LaTeX_envs_menu_present": true,
"autocomplete": true,
"bibliofile": "biblio.bib",
"cite_by": "apalike",
"current_citInitial": 1,
"eqLabelWithNumbers": true,
"eqNumInitial": 1,
"hotkeys": {
"equation": "Ctrl-E",
"itemize": "Ctrl-I"
},
"labels_anchors": false,
"latex_user_defs": false,
"report_style_numbering": false,
"user_envs_cfg": false
}
},
"nbformat": 4,
"nbformat_minor": 4
}