Skip to content

Instantly share code, notes, and snippets.

@verginer
Last active March 30, 2016 21:06
Show Gist options
  • Save verginer/8d0a000ce50b4221400503695a0a9bbe to your computer and use it in GitHub Desktop.
Save verginer/8d0a000ce50b4221400503695a0a9bbe to your computer and use it in GitHub Desktop.
A script to create a minimalist TikZ graph (i.e. network) given an edge list. For the command line arguments, see help at bottom.
#!/usr/local/bin/python
from __future__ import division
import math
TIKZ = (r"""
\documentclass[tikz,border=10pt]{{standalone}}
\usetikzlibrary{{positioning}}
\tikzset{{main node/.style={{circle,draw,minimum size=.5cm,inner sep=0pt}},
}}
\begin{{document}}
\begin{{tikzpicture}}
{node_anchors}
\path[draw,thick]
{tikz_path}
\end{{tikzpicture}}
\end{{document}}
""")
def _group(flat, size):
return [flat[i:i + size] for i in range(0, len(flat), size)]
def _create_grid(n, offset=2):
width = int(math.ceil(math.sqrt(n)))
height = int(math.ceil(n / width))
node_main = r"\node[main node] ({node_number}) {{${node_number}$}};"
node_position = r"\node[main node] ({node_number}) [{position} = {dist}cm of {of}] {{${node_number}$}};"
grid_matrix = _group(list(range(1, (width * height) + 1)), width)
node_list = [node_main.format(node_number=1)]
for i in range(height):
for j in range(width):
if grid_matrix[i][j] > n:
break
elif grid_matrix[i][j] == 1:
continue
else:
if j == 0:
parameters = {"node_number": grid_matrix[i][j],
"dist": str(offset),
"of": grid_matrix[i - 1][0],
"position": "below"}
else:
parameters = {"node_number": grid_matrix[i][j],
"dist": str(offset * j),
"of": grid_matrix[i][0],
"position": "right"}
node_list.append(node_position.format(**parameters))
return "\n".join(node_list)
def create_tikz_path_graph(edge_list):
"""
returns a tikz document to be compiled by by pdftex of the edge_list
in a grid layout
Parameters
----------
edge_list
i.e. [(1,2), (3,5)]
Returns (str)
-------
a string containing the standalone tikz document
"""
path_temp = "({u_node}) edge node {{}} ({v_node})"
path_list = []
if len(edge_list[0]) is 1:
edges = zip(edge_list, edge_list[1:])
else:
edges = edge_list
nodes_set = set()
for u, v in edges:
path_list.append(path_temp.format(v_node=v, u_node=u))
nodes_set.add(u)
nodes_set.add(v)
number_of_nodes = max(nodes_set)
tikz_path = "\n".join(path_list)
tikz_path += ";"
node_anchors = _create_grid(number_of_nodes, offset=2)
return TIKZ.format(tikz_path=tikz_path, node_anchors=node_anchors)
if __name__ == '__main__':
import os
import sys
try:
params = dict(map(lambda x: x.lstrip('-').split('='), sys.argv[1:]))
edges = params["path"].split(",")
path = [edge.split(":") for edge in edges]
path = [(int(v), int(u)) for v, u in path]
tex_string = create_tikz_path_graph(path)
file_name = params["f"] + ".tex"
with open(file_name, "w") as f:
f.write(tex_string)
os.system("pdflatex {file}".format(file=file_name))
except (IOError, KeyError):
print ("\n"
"Help for graphtikz.py \n"
"this script creates a tikz graph in grid layout for the given edge list\n"
"an edge is a pair `u:v` separated by `,`\n"
"\n"
"Parameters\n"
"-------\n"
"\n"
"or a set of edges separated by :\n"
"-path=1:2,3:1,4:1\n"
"\n"
"-f=<filename> for output\n"
"\n"
"Example\n"
"-------\n"
"$ ./graphtikz.py -path=1:2,3:1,4:1 -f=\"separate\"\n"
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment