2 # NEPI, a framework to manage network experiments
3 # Copyright (C) 2013 INRIA
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License version 2 as
7 # published by the Free Software Foundation;
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
17 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
25 msg = "Networkx library is not installed, you will not be able to plot."
26 logger = logging.Logger("Plotter")
30 import matplotlib.pyplot as plt
32 msg = ("Matplotlib library is not installed or X11 is not enabled. "
33 "You will not be able generate PNG plots.")
34 logger = logging.Logger("Plotter")
41 class ECPlotter(object):
42 def plot(self, ec, dirpath = None, format= PFormats.FIGURE,
44 graph, labels = self._ec2graph(ec)
50 dirpath = tempfile.mkdtemp()
52 fpath = os.path.join(dirpath, "%s_%s" % (ec.exp_id, ec.run_id))
54 if format == PFormats.FIGURE:
55 pos = networkx.graphviz_layout(graph, prog="neato")
56 networkx.draw(graph, pos = pos, node_color="white",
57 node_size = 500, with_labels=True)
59 label = "\n".join(["%s: %s" % (v[0], v[1]) for v in iter(labels.items())])
60 plt.annotate(label, xy=(0.05, 0.95), xycoords='axes fraction')
64 plt.savefig(fpath, bbox_inches="tight")
69 elif format == PFormats.DOT:
72 networkx.write_dot(graph, fpath)
76 subprocess.call(["dot", "-Tps", fpath, "-o", "%s.ps" % fpath])
77 subprocess.call(["evince","%s.ps" % fpath])
81 def _ec2graph(self, ec):
82 graph = networkx.Graph(graph = dict(overlap = "false"))
87 for guid, rm in ec._resources.items():
88 label = rm.get_rtype()
91 label = "%d %s" % (guid, label),
92 width = 50/72.0, # 1 inch = 72 points
98 for guid2 in rm.connections:
99 # Avoid adding a same connection twice
100 if (guid2, guid) not in connections:
101 connections.add((guid, guid2))
103 for (guid1, guid2) in connections:
104 graph.add_edge(guid1, guid2)