Last active
March 30, 2016 21:06
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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