Commit 2db745b1 authored by Tiago Peixoto's avatar Tiago Peixoto

Several documentation fixes and extensions

This completes all the documentation up to this point.
parent bb499c3b
......@@ -14,3 +14,8 @@
{{ super() }}
{% endblock %}
{% block sidebarsearch %}
{{ super() }}
<a href="graph-tool.pdf">(Download PDF version)</a>
{% endblock %}
......@@ -26,7 +26,7 @@ sys.path.append(os.path.abspath('.'))
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest',
'sphinx.ext.intersphinx', 'sphinx.ext.jsmath',
'sphinxext.numpydoc']
'sphinxext.numpydoc', 'sphinxext.autosummary']
jsmath_path = "jsMath/easy/load.js"
......@@ -94,6 +94,38 @@ pygments_style = 'sphinx'
doctest_global_setup = \
r"""
from matplotlib import rc
from matplotlib import rcParams
font_size=12
rcParams["figure.figsize"] = (4,3)
rcParams["font.family"] = "serif"
rcParams["font.serif"] = ["Palatino"]
rcParams["font.size"] = font_size
rcParams["axes.labelsize"] = font_size
rcParams["xtick.labelsize"] = font_size
rcParams["ytick.labelsize"] = font_size
rcParams["legend.numpoints"] = 1
rcParams["legend.fontsize"] = "small"
rcParams["lines.markersize"] = 4
rcParams["figure.subplot.right"] = 0.95
rcParams["figure.subplot.top"] = 0.95
rcParams["figure.subplot.right"] = 0.95
rcParams["figure.subplot.top"] = 0.95
rcParams["figure.subplot.left"] = 0.2
rcParams["figure.subplot.bottom"] = 0.2
rcParams["text.usetex"] = True
rcParams["ps.usedistiller"] = "xpdf"
rcParams["pdf.compression"] = 9
rcParams["ps.useafm"] = True
rcParams["path.simplify"] = True
rcParams["text.latex.preamble"] = [#"\usepackage{times}",
"\usepackage{euler}",
"\usepackage{amssymb}",
"\usepackage{amsmath}"]
from numpy import array
import scipy
import scipy.stats
......@@ -107,7 +139,10 @@ import graph_tool.all as gt
# The style sheet to use for HTML and HTML Help pages. A file of that name
# must exist either in Sphinx' static/ path, or in one of the custom paths
# given in html_static_path.
html_style = 'default.css'
# html_style = 'default.css'
html_theme = "gt_theme"
html_theme_path = ["."]
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
......@@ -132,11 +167,11 @@ html_static_path = ['.static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
......@@ -172,35 +207,20 @@ htmlhelp_basename = 'graph-tooldoc'
# Options for LaTeX output
# ------------------------
# The paper size ('letter' or 'a4').
#latex_paper_size = 'letter'
# The font size ('10pt', '11pt' or '12pt').
#latex_font_size = '10pt'
# Grouping the document tree into LaTeX files. List of tuples (source start
# file, target name, title, author, document class [howto/manual]).
latex_documents = [
('index', 'graph-tool.tex', ur'graph-tool Documentation',
('index', 'graph-tool.tex', ur'graph-tool documentation',
ur'Tiago de Paula Peixoto', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
#latex_logo = "graph-draw.png"
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
latex_elements = {
'papersize' : "a4paper",
'fontpkg' : r"\usepackage{palatino}\usepackage{eulervm}"
}
# Additional stuff for the LaTeX preamble.
#latex_preamble = ''
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_use_modindex = True
# Example configuration for intersphinx: refer to the Python standard library.
......
......@@ -5,6 +5,7 @@ Available subpackages
=====================
.. toctree::
:maxdepth: 1
centrality
clustering
......
@import url("default.css");
table.docutils td {
padding-left: 0.5em;
}
/* stupid workaround to hide ugly c++ signature stuff from sphinx*/
dl.method dl.last {
visibility: collapse;
height: 0px;
width: 0px;
}
div.align-center {
text-align: center;
}
div.float-left {
float: left;
}
div.float-right {
float: right;
}
p.rubric {
clear: both;
}
\ No newline at end of file
[theme]
inherit = default
stylesheet = gt_style.css
......@@ -8,12 +8,13 @@ Welcome to graph-tool's documentation!
Contents:
.. toctree::
:maxdepth: 3
:glob:
quickstart
modules
Indices and tables
Indexes and tables
==================
* :ref:`genindex`
......
......@@ -56,11 +56,13 @@ for i in xrange(1, N):
in_hist = vertex_hist(g, "in")
clf()
figure(figsize=(4,3))
errorbar(in_hist[1], in_hist[0], fmt="o", yerr=sqrt(in_hist[0]), label="in")
gca().set_yscale("log")
gca().set_xscale("log")
legend(loc="best")
gca().set_ylim(1e-1,1e5)
gca().set_xlim(0.8,1e3)
subplots_adjust(left=0.2,bottom=0.2)
xlabel("$k_{in}$")
ylabel("$P(k_{in})$")
savefig("deg-hist.png")
......
......@@ -191,9 +191,9 @@ and :meth:`~graph_tool.Vertex.in_neighbours` respectively.
Property maps
-------------
Property maps are a way of associating additional to the vertices, edges or to
the graph itself. There are thus three types of property maps: vertex, edge and
graph. All of them are instances of the same class,
Property maps are a way of associating additional information to the vertices,
edges or to the graph itself. There are thus three types of property maps:
vertex, edge and graph. All of them are instances of the same class,
:class:`~graph_tool.PropertyMap`. Each property map has an associated *value
type*, which must be chosen from the predefined set:
......@@ -310,9 +310,18 @@ Graph classes can also be pickled with the :mod:`pickle` module.
An Example: Building a Price Network
------------------------------------
A Price network is the first known model of a "scale-free" graph, invented in
1976 by `de Solla Price
<http://en.wikipedia.org/wiki/Derek_J._de_Solla_Price>`_. It is defined
dynamically, and at each time step a new vertex is added to the graph, and
connected to an old vertex, with probability proportional to its in-degree. The
following program implements this construction method using ``graph-tool``.
.. literalinclude:: price.py
:linenos:
The following is what should happen when the program is run.
.. testcode::
:hide:
......@@ -333,6 +342,9 @@ An Example: Building a Price Network
vertex: 0 in-degree: 210 out-degree: 0 age: 0
Nowhere else to go... We found the main hub!
This is the degree distribution, with 100000 nodes. If you want to really see a
power law, try to increase the number of vertices to something like :math:`10^6`
or :math:`10^7`.
.. figure:: deg-hist.png
:align: center
......@@ -346,9 +358,130 @@ use the :func:`~graph_tool.draw.graph_draw` function.
g = load_graph("price.xml.gz")
g.remove_vertex_if(lambda v: g.vertex_index[v] >= 1000)
gt.graph_draw(g, output="price.png")
graph_draw(g, size=(10,10), layout="arf", output="price.png")
.. figure:: price.png
:align: center
First 1000 nodes of a price network.
Graph filtering
---------------
One of the very nice features from ``graph-tool`` is the "on-the-fly" filtering
of edges and/or vertices. Filtering means the temporary masking of
vertices/edges, which are not really removed, and can be easily
recovered. Vertices or edges which are to be filtered should be marked with a
:class:`~graph_tool.PropertyMap` with value type ``bool``, and then set with
:meth:`~graph_tool.Graph.set_vertex_filter` or
:meth:`~graph_tool.Graph.set_edge_filter` methods. By default, vertex or edges
with value "1" are `kept` in the graphs, and those with value "0" are filtered
out. This behaviour can be modified with the ``inverted`` parameter of the
respective functions. All manipulation functions and algorithms will work as if
the marked edges or vertices were removed from the graph, with minimum overhead.
Here is an example which obtains the minimum spanning tree of a graph, using
edge filtering.
.. testcode::
:hide:
seed(42)
.. testcode::
g = random_graph(100, lambda: (poisson(4), poisson(4)))
tree = min_spanning_tree(g)
graph_draw(g, size=(8,8), ecolor=tree, output="min_tree.png")
The ``tree`` property map has a bool type, with value "1" if the edge belongs to
the tree, and "0" otherwise. Below is an image of the original graph, with the
marked edges.
.. figure:: min_tree.png
:align: center
We can now filter out the edges which don't belong to the minimum spanning tree.
.. testcode::
g.set_edge_filter(tree)
graph_draw(g, size=(8,8), layout="arf", output="min_tree_filtered.png")
This is how the graph looks when filtered:
.. figure:: min_tree_filtered.png
:align: center
Everything should work transparently on the filtered graph, simply as if the
masked edges were removed.
.. testcode::
pr = pagerank(g)
print pr.a
Which outputs the following.
.. testoutput::
[ 1.21896533 0.2 0.28 0.36 0.28 0.2 0.2
0.2 0.2 0.44 0.2 0.53813333 0.344 0.2
0.52 0.4752 0.53066667 0.2 0.85066667 0.2
0.37813333 0.28 2.65013333 0.78133333 0.2 0.2 0.28
0.2 0.2 0.2 0.2 0.2 0.2 0.2
0.2 0.41333333 0.2 0.2 0.25333333 0.2
0.41333333 0.2 0.76 0.2 0.2 1.27370667
0.36 0.2 0.2 0.28 0.36 0.6 0.2
1.17517227 0.40266667 0.2 0.44533333 1.016 0.424 0.28
0.2 0.2 0.44 0.6 0.2 0.2 0.44
0.2 0.2 0.28 0.25333333 0.25333333 0.28 0.2
1.24213333 0.2 0.40266667 0.28 0.36 0.2 0.2
0.2 0.2 0.54133333 0.2 0.5552 0.2 0.44
0.44 0.2 0.2 0.28 0.2 0.6 0.2
0.44 0.2 0.28 0.344 0.472 ]
The original graph can be recovered by setting the edge filter to ``None``.
.. testcode::
g.set_edge_filter(None)
pr = pagerank(g)
print pr.a
Which outputs the following.
.. testoutput::
[ 0.39689941 0.2 1.38764556 0.31699172 0.66893137 0.80523725
0.67802789 0.40784401 0.29361908 1.22559931 0.750107 1.02862225
0.6472381 0.78447305 0.54791497 0.73210888 1.00329801 0.43209786
1.20758525 0.95797897 0.97106576 0.38080744 2.35690886 1.35609636
1.04694293 0.47676748 0.870367 0.9034519 0.60360189 0.24
0.35010316 0.81055356 0.59406634 0.68903488 0.3701726 0.50917786
0.819167 0.31490118 0.67404843 0.74766878 1.25501188 0.2
1.97251855 0.77583825 0.62509331 0.55088128 0.41242224 0.70903083
0.5918624 0.92565929 2.1083913 0.99864279 0.47676748 0.30583984
0.45919658 0.3551633 2.58583616 1.07020892 0.44358295 0.75860401
0.51277849 0.54073371 0.79816833 1.52121868 0.93996758 0.25077432
0.48392002 0.7181324 0.4789649 1.88431987 0.42763893 0.82713964
1.0133979 0.8693855 1.94140631 0.39321364 1.27413606 3.16059924
1.32889816 0.89569002 0.27990067 0.64233367 0.89888256 1.24365097
0.56000105 1.1805301 0.76991724 1.3304796 1.04003837 1.50556425
0.39110528 0.2762828 0.2 1.57628517 1.38463963 1.03787805
0.81171454 0.95811153 0.5728202 1.26472067]
Everything works in analogous fashion with vertex filtering.
.. note::
It is important to emphasize that the filtering functionality does not add
any overhead when the graph is not being filtered. In this case, the
algorithms run just as fast as if the filtering functionality didn't exist.
Additionally, the graph can also have its edges reversed with the
:meth:`~graph_tool.Graph.set_reversed` method. This is also an :math:`O(1)`
operation, which does not really modify the graph.
As mentioned previously, the directedness of the graph can also be changed
"on-the-fly" with the :meth:`~graph_tool.Graph.set_directed` method.
\ No newline at end of file
......@@ -189,8 +189,8 @@ def get_autosummary(names, state, no_signatures=False):
table = nodes.table('')
group = nodes.tgroup('', cols=2)
table.append(group)
group.append(nodes.colspec('', colwidth=30))
group.append(nodes.colspec('', colwidth=70))
group.append(nodes.colspec('', colwidth=45))
group.append(nodes.colspec('', colwidth=55))
body = nodes.tbody('')
group.append(body)
......
......@@ -49,35 +49,22 @@ Use the built-in ``help`` function to view a function's docstring::
>>> help(gt.Graph)
Available subpackages
---------------------
clustering
clustering (aka. transitivity)
community
community detection
correlations
vertex and edge correlations
draw
Graph drawing using graphviz
generation
random graph generation
misc
miscenalenous algorithms
stats
vertex and edge statistics
util
assorted utilities
Utilities
---------
show_config
Show ``graph_tool`` build configuration
__version__
``graph_tool`` version string
Classes
-------
.. autosummary::
:nosignatures:
Graph
Vertex
Edge
PropertyMap
load_graph
group_vector_property
ungroup_vector_property
value_types
show_config
"""
__author__="Tiago de Paula Peixoto <tiago@forked.de>"
......
This diff is collapsed.
This diff is collapsed.
......@@ -22,6 +22,19 @@
This module contains algorithms for the computation of community structure on
graphs.
Summary
+++++++
.. autosummary::
:nosignatures:
community_structure
modularity
condensation_graph
Contents
++++++++
"""
from .. dl_import import dl_import
......@@ -35,14 +48,14 @@ __all__ = ["community_structure", "modularity", "condensation_graph"]
def community_structure(g, n_iter, n_spins, gamma=1.0, corr= "erdos",
spins=None, weight=None, t_range=(100.0, 0.01),
verbose=False, history_file=None, seed=0):
verbose=False, history_file=None):
r"""
Obtain the community structure for the given graph, used a Potts model
approach.
Parameters
----------
g : Graph
g : :class:`~graph_tool.Graph`
Graph to be used.
n_iter : int
Number of iterations.
......@@ -53,10 +66,10 @@ def community_structure(g, n_iter, n_spins, gamma=1.0, corr= "erdos",
corr : string (optional, default: "erdos")
Type of correlation to be assumed: Either "erdos", "uncorrelated" and
"correlated".
spins : PropertyMap
spins : :class:`~graph_tool.PropertyMap`
Vertex property maps to store the spin variables. If this is specified,
the values will not be initialized to a random value.
weight : PropertyMap (optional, default: None)
weight : :class:`~graph_tool.PropertyMap` (optional, default: None)
Edge property map with the optional edge weights.
t_range : tuple of floats (optional, default: (100.0, 0.01))
Temperature range.
......@@ -67,7 +80,7 @@ def community_structure(g, n_iter, n_spins, gamma=1.0, corr= "erdos",
Returns
-------
spins : PropertyMap
spins : :class:`~graph_tool.PropertyMap`
Vertex property map with the spin values.
See Also
......@@ -79,7 +92,7 @@ def community_structure(g, n_iter, n_spins, gamma=1.0, corr= "erdos",
Notes
-----
The method of community detection covered here is an implementation of what
was proposed in [reichard_statistical_2006]_. It
was proposed in [reichard-statistical-2006]_. It
consists of a `simulated annealing`_ algorithm which tries to minimize the
following hamiltonian:
......@@ -92,7 +105,7 @@ def community_structure(g, n_iter, n_spins, gamma=1.0, corr= "erdos",
which reduces the problem of community detection to finding the ground
states of a Potts spin-glass model. It can be shown that minimizing this
hamiltonan, with :math:`\gamma=1`, is equivalent to maximizing
Newman's modularity ([newman_modularity_2006]_). By increasing the parameter
Newman's modularity ([newman-modularity-2006]_). By increasing the parameter
:math:`\gamma`, it's possible also to find sub-communities.
It is possible to select three policies for choosing :math:`p_{ij}` and thus
......@@ -131,13 +144,13 @@ def community_structure(g, n_iter, n_spins, gamma=1.0, corr= "erdos",
>>> spins = gt.community_structure(g, 10000, 20, t_range=(5, 0.1),
... history_file="community-history1")
>>> gt.graph_draw(g, pos=pos, pin=True, vsize=0.3, vcolor=spins,
... output="comm1.png")
... output="comm1.png", size=(10,10))
<...>
>>> spins = gt.community_structure(g, 10000, 40, t_range=(5, 0.1),
... gamma=2.5,
... history_file="community-history2")
>>> gt.graph_draw(g, pos=pos, pin=True, vsize=0.3, vcolor=spins,
... output="comm2.png")
... output="comm2.png", size=(10,10))
<...>
>>> clf()
>>> xlabel("iterations")
......@@ -158,32 +171,24 @@ def community_structure(g, n_iter, n_spins, gamma=1.0, corr= "erdos",
[...]
>>> savefig("comm2-hist.png")
.. figure:: comm1.png
:align: center
Community structure with :math:`\gamma=1`.
.. figure:: comm1-hist.png
:align: center
The community structure with :math:`\gamma=1`:
Algorithm evolution with :math:`\gamma=1`
.. image:: comm1.png
.. image:: comm1-hist.png
.. figure:: comm2.png
:align: center
The community structure with :math:`\gamma=2.5`:
Community structure with :math:`\gamma=2.5`.
.. figure:: comm2-hist.png
:align: center
.. image:: comm2.png
.. image:: comm2-hist.png
Algorithm evolution with :math:`\gamma=2.5`
References
----------
.. [reichard_statistical_2006] Joerg Reichardt and Stefan Bornholdt,
.. [reichard-statistical-2006] Joerg Reichardt and Stefan Bornholdt,
"Statistical Mechanics of Community Detection", Phys. Rev. E 74 (2006)
016110, arXiv:cond-mat/0603718
.. [newman_modularity_2006] M. E. J. Newman, "Modularity and community
.. [newman-modularity-2006] M. E. J. Newman, "Modularity and community
structure in networks", Proc. Natl. Acad. Sci. USA 103, 8577-8582 (2006),
arXiv:physics/0602124
.. _simulated annealing: http://en.wikipedia.org/wiki/Simulated_annealing
......@@ -196,8 +201,7 @@ def community_structure(g, n_iter, n_spins, gamma=1.0, corr= "erdos",
new_spins = False
if history_file == None:
history_file = ""
if seed != 0:
seed = random.randint(0, sys.maxint)
seed = random.randint(0, sys.maxint)
libgraph_tool_community.community_structure(g._Graph__graph, gamma, corr,
n_iter, t_range[1], t_range[0],
n_spins, new_spins, seed,
......@@ -212,11 +216,11 @@ def modularity(g, prop, weight=None):
Parameters
----------
g : Graph
g : :class:`~graph_tool.Graph`
Graph to be used.
prop : PropertyMap
prop : :class:`~graph_tool.PropertyMap`
Vertex property map with the community partition.
weight : PropertyMap (optional, default: None)
weight : :class:`~graph_tool.PropertyMap` (optional, default: None)
Edge property map with the optional edge weights.
Returns
......@@ -234,7 +238,7 @@ def modularity(g, prop, weight=None):
-----
Given a specific graph partition specified by `prop`, Newman's modularity
([newman_modularity_2006]_) is defined by:
[newman-modularity-2006]_ is defined by:
.. math::
......@@ -257,7 +261,7 @@ def modularity(g, prop, weight=None):
References
----------
.. [newman_modularity_2006] M. E. J. Newman, "Modularity and community
.. [newman-modularity-2006] M. E. J. Newman, "Modularity and community
structure in networks", Proc. Natl. Acad. Sci. USA 103, 8577-8582 (2006),
arXiv:physics/0602124
"""
......@@ -274,20 +278,20 @@ def condensation_graph(g, prop, weight=None):
Parameters
----------
g : Graph
g : :class:`~graph_tool.Graph`
Graph to be used.
prop : PropertyMap
prop : :class:`~graph_tool.PropertyMap`
Vertex property map with the community partition.
weight : PropertyMap (optional, default: None)
weight : :class:`~graph_tool.PropertyMap` (optional, default: None)
Edge property map with the optional edge weights.
Returns
-------
condensation_graph : Graph
condensation_graph : :class:`~graph_tool.Graph`
The community network
vcount : PropertyMap
vcount : :class:`~graph_tool.PropertyMap`
A vertex property map with the vertex count for each community.
ecount : PropertyMap
ecount : :class:`~graph_tool.PropertyMap`
An edge property map with the inter-community edge count for each edge.
See Also
......@@ -312,10 +316,10 @@ def condensation_graph(g, prop, weight=None):
>>> spins = gt.community_structure(g, 10000, 100)
>>> ng = gt.condensation_graph(g, spins)
>>> size = ng[0].new_vertex_property("double")
>>> size.get_array()[:] = log(ng[1].get_array()+1)
>>> size.a = log(ng[1].a+1)
>>> gt.graph_draw(ng[0], vsize=size, vcolor=size, splines=True,
... eprops={"len":20, "penwidth":10}, vprops={"penwidth":10},
... output="comm-network.png")
... output="comm-network.png", size=(10,10))
<...>
.. figure:: comm-network.png
......
This diff is collapsed.
......@@ -19,6 +19,22 @@
"""
``graph_tool.correlations`` - Correlations
------------------------------------------
Summary
+++++++
.. autosummary::
:nosignatures:
assortativity
scalar_assortativity
corr_hist
combined_corr_hist
avg_neighbour_corr
avg_combined_corr
Contents
++++++++