How to get useful information from pycallgraph tracing?

1.6k Views Asked by At

In my question about tracking the python execution I was recommended to use pycallgraph so I decided to give it a try on following code:

#!/bin/env python

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 2, 100)

# The first call to plt.plot will automatically create
# the necessary figure and axes to achieve the desired plot.
plt.plot(x, x, label='linear')

# Subsequent calls to plt.plot re-use
# the current axes and each add another line.
plt.plot(x, x**2, label='quadratic')
plt.plot(x, x**3, label='cubic')

# Setting the title, legend, and axis labels also automatically
# use the current axes and set the title,
# create the legend, and label the axis respectively.
plt.xlabel('x label')
plt.ylabel('y label')

plt.title("Simple Plot")

plt.legend()

plt.show()

This code is from my another question where I've been asking about hierarchy in matplotlib, and I get the following answer:

If you're really keen to see how the auto creation is done - it's all open source. You can see the call to plot() creates an Axes instance by a call to gca() in the code here. This in turn calls gcf(), which looks for a FigureManager (which is what actually maintains the state). If one exists, it returns the figure it's managing, otherwise it creates a new one using plt.figure(). Again, this process to some degree inherits from matlab, where the initial call is usually figure before any plotting operation.

First, I was trying pycallgraph with graphviz option, but it gives me following error:

$ pycallgraph graphviz -- matplotlib.py
libpath/shortest.c:324: triangulation failed
libpath/shortest.c:192: source point not in any triangle
Error: in routesplines, Pshortestpath failed
Segmentation fault
Traceback (most recent call last):
  File "/usr/local/bin/pycallgraph", line 26, in <module>
    exec(__file_content)
  File "/usr/local/lib/python2.7/dist-packages/pycallgraph/pycallgraph.py", line 38, in __exit__
    self.done()
  File "/usr/local/lib/python2.7/dist-packages/pycallgraph/pycallgraph.py", line 81, in done
    self.stop()
  File "/usr/local/lib/python2.7/dist-packages/pycallgraph/pycallgraph.py", line 90, in generate
    output.done()
  File "/usr/local/lib/python2.7/dist-packages/pycallgraph/output/graphviz.py", line 112, in done
    'code %(ret)i.' % locals())
pycallgraph.exceptions.PyCallGraphException: The command "dot -Tpng -opycallgraph.png /tmp/tmpObsZGK" failed with error code 35584.

Second I've tried to generate gephi format and it worked:

$ pycallgraph gephi -- matplotlib.py

When I've opened this in gephi I get huge graph (Nodes: 1062, Edges: 1362) which was almost useless and I cannot saw anything useful here. So I've tried limit the output:

$ pycallgraph --max-depth 5 gephi -- traceme.py

This gives me graph with 254 nodes and 251 edges which was basically also useless because I still cannot saw nothing useful here. So, I've decided to try following:

egrep -i 'gcf|gca|plot' pycallgraph.gdf

But it returns me nothing. Then I've started wondering what exactly is pycallgraph tracing and I've made this hello world:

#!/bin/env python
print "This line will be printed."

And I've run it with (graphviz):

pycallgraph graphviz -- hello_world.py

The output (read from png file that was generated) was:

__main__ ---> <module>
  1. What tool can I use to get similar answer as I've referred? In another words, how can I know that this is the order of calling the functions: plot() -> gca() -> gcf()?
  2. What is pycallgraph actually tracing?
  3. Why hello world example is working with graphviz option but more complex example is working only with gephi option?
  4. How to preserve the DOT format which is pycallgraph generating and passing to graphviz?
0

There are 0 best solutions below