diff --git a/.gitignore b/.gitignore index 271ed498313..3e1a50c4982 100644 --- a/.gitignore +++ b/.gitignore @@ -15,9 +15,9 @@ doc/build *.class # Generated while building documentation. -doc/source/static/examples/* -doc/source/reference/generated/* -doc/source/examples/* +doc/source/auto_examples +doc/source/modules +doc/source/reference/generated # Generated when 'python setup_egg.py' networkx.egg-info/ diff --git a/README.rst b/README.rst index 929ad3b2f77..90c33234200 100644 --- a/README.rst +++ b/README.rst @@ -14,9 +14,9 @@ NetworkX .. image:: https://coveralls.io/repos/networkx/networkx/badge.svg?branch=master :target: https://coveralls.io/r/networkx/networkx?branch=master -NetworkX is a Python package for the creation, manipulation, and study of the -structure, dynamics, and functions of complex networks. - +NetworkX is a Python package for the creation, manipulation, +and study of the structure, dynamics, and functions +of complex networks. - **Website (including documentation):** http://networkx.github.io - **Mailing list:** https://groups.google.com/forum/#!forum/networkx-discuss @@ -54,9 +54,10 @@ Bugs ---- Please report any bugs that you find `here `_. -Or, even better, fork the repository on GitHub and create a pull request (PR). -We welcome all changes, big or small, and we will help you make the PR if you are -new to `git` (just ask on the issue and/or see `CONTRIBUTE.rst`). +Or, even better, fork the repository on `GitHub `_ +and create a pull request (PR). We welcome all changes, big or small, and we +will help you make the PR if you are new to `git` (just ask on the issue and/or +see `CONTRIBUTE.rst`). License ------- diff --git a/doc/Makefile b/doc/Makefile index 4138470ec97..33b582f8d8d 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -26,19 +26,11 @@ help: @echo " changes to make an overview of all changed/added/deprecated items" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" + @echo " gitwash to update the gitwash documentation" clean: - -rm -rf build/* source/reference/generated/* source/examples/* source/static/examples/* doc/source/*.pdf doc/source/*.zip - -rm -rf ../examples/*/*.png - -generate: build/generate-stamp -build/generate-stamp: $(wildcard source/reference/*.rst) - mkdir -p build - python make_gallery.py - python make_examples_rst.py ../examples source - touch build/generate-stamp - + -rm -rf build/* source/auto_examples source/modules source/reference/generated dist: html test -d build/latex || make latex @@ -48,33 +40,33 @@ dist: html (cd build/dist && tar czf ../dist.tar.gz .) -html: generate +html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) build/html @echo @echo "Build finished. The HTML pages are in build/html." -dirhtml: generate +dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) build/dirhtml @echo @echo "Build finished. The HTML pages are in build/dirhtml." -pickle: generate +pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) build/pickle @echo @echo "Build finished; now you can process the pickle files." -json: generate +json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) build/json @echo @echo "Build finished; now you can process the JSON files." -htmlhelp: generate +htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) build/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in build/htmlhelp." -qthelp: generate +qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) build/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ @@ -89,7 +81,7 @@ epub: @echo "Build finished. The epub file is in $(BUILDDIR)/epub." -latex: generate +latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) build/latex @echo @echo "Build finished; the LaTeX files are in build/latex." @@ -101,21 +93,19 @@ changes: @echo @echo "The overview file is in build/changes." -linkcheck: generate +linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) build/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in build/linkcheck/output.txt." -doctest: generate +doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) build/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in build/doctest/output.txt." -gh-pages: clean dist - python gh-pages.py $(tag) - gitwash-update: - python gitwash_dumper.py source/developer networkx \ - --project-url=http://networkx.github.io \ - --project-ml-url=http://groups.google.com/group/networkx-discuss/ + python ../tools/gitwash_dumper.py source/developer networkx \ + --project-url=http://networkx.github.io \ + --project-ml-url=http://groups.google.com/group/networkx-discuss/ \ + --gitwash-url git@github.com:matthew-brett/gitwash.git diff --git a/doc/gh-pages.py b/doc/gh-pages.py deleted file mode 100755 index c0d152e2bda..00000000000 --- a/doc/gh-pages.py +++ /dev/null @@ -1,139 +0,0 @@ -#!/usr/bin/env python -"""Script to commit the doc build outputs into the github-pages repo. - -Use: - - gh-pages.py [tag] - -If no tag is given, the current output of 'git describe' is used. If given, -that is how the resulting directory will be named. - -In practice, you should use either actual clean tags from a current build or -something like 'current' as a stable URL for the most current version""" -# Borrowed from IPython. - -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- -from __future__ import print_function -import os -import re -import shutil -import sys -from os import chdir as cd -from os.path import join as pjoin - -from subprocess import Popen, PIPE, CalledProcessError, check_call - -#----------------------------------------------------------------------------- -# Globals -#----------------------------------------------------------------------------- - -pages_dir = 'gh-pages' -html_dir = 'build/dist' -pdf_dir = 'build/latex' -pages_repo = 'git@github.com:networkx/documentation.git' - -#----------------------------------------------------------------------------- -# Functions -#----------------------------------------------------------------------------- -def sh(cmd): - """Execute command in a subshell, return status code.""" - return check_call(cmd, shell=True) - - -def sh2(cmd): - """Execute command in a subshell, return stdout. - - Stderr is unbuffered from the subshell.x""" - p = Popen(cmd, stdout=PIPE, shell=True) - out = p.communicate()[0] - retcode = p.returncode - if retcode: - raise CalledProcessError(retcode, cmd) - else: - return out.rstrip() - - -def sh3(cmd): - """Execute command in a subshell, return stdout, stderr - - If anything appears in stderr, print it out to sys.stderr""" - p = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=True) - out, err = p.communicate() - retcode = p.returncode - if retcode: - raise CalledProcessError(retcode, cmd) - else: - return out.rstrip(), err.rstrip() - - -def init_repo(path): - """clone the gh-pages repo if we haven't already.""" - sh("git clone %s %s"%(pages_repo, path)) - here = os.getcwdu() - cd(path) - sh('git checkout gh-pages') - cd(here) - -#----------------------------------------------------------------------------- -# Script starts -#----------------------------------------------------------------------------- -if __name__ == '__main__': - # The tag can be given as a positional argument - try: - tag = sys.argv[1] - except IndexError: - try: - tag = sh2('git describe --exact-match') - except CalledProcessError: - print("using development as label") - tag = "development" # Fallback - - startdir = os.getcwdu() - if not os.path.exists(pages_dir): - # init the repo - init_repo(pages_dir) - else: - # ensure up-to-date before operating - cd(pages_dir) - sh('git checkout gh-pages') - sh('git pull') - cd(startdir) - - dest = pjoin(pages_dir, tag) - - # don't `make html` here, because gh-pages already depends on html in Makefile - # sh('make html') - if tag != 'dev': - # only build pdf for non-dev targets - #sh2('make pdf') - pass - - # This is pretty unforgiving: we unconditionally nuke the destination - # directory, and then copy the html tree in there - shutil.rmtree(dest, ignore_errors=True) - shutil.copytree(html_dir, dest) - if tag != 'dev': - #shutil.copy(pjoin(pdf_dir, 'ipython.pdf'), pjoin(dest, 'ipython.pdf')) - pass - - try: - cd(pages_dir) - status = sh2('git status | head -1') - branch = re.match('\# On branch (.*)$', status).group(1) - if branch != 'gh-pages': - e = 'On %r, git branch is %r, MUST be "gh-pages"' % (pages_dir, - branch) - raise RuntimeError(e) - - sh('git add -A %s' % tag) - sh('git commit -m"Updated doc release: %s"' % tag) - print('\nMost recent 3 commits:') - sys.stdout.flush() - sh('git --no-pager log --oneline HEAD~3..') - finally: - cd(startdir) - - print('\nNow verify the build in: %r' % dest) - print("If everything looks good, 'git push'") diff --git a/doc/make_examples_rst.py b/doc/make_examples_rst.py deleted file mode 100755 index abee8ab8999..00000000000 --- a/doc/make_examples_rst.py +++ /dev/null @@ -1,179 +0,0 @@ -""" -generate the rst files for the examples by iterating over the networkx examples -""" -# This code was developed from the Matplotlib gen_rst.py module -# and is distributed with the same license as Matplotlib -from __future__ import print_function -import os, glob - -import os -import re -import sys -#fileList = [] -#rootdir = '../../examples' - - - -def out_of_date(original, derived): - """ - Returns True if derivative is out-of-date wrt original, - both of which are full file paths. - - TODO: this check isn't adequate in some cases. Eg, if we discover - a bug when building the examples, the original and derived - will be unchanged but we still want to fource a rebuild. We can - manually remove from _static, but we may need another solution - """ - return (not os.path.exists(derived) or - os.stat(derived).st_mtime < os.stat(original).st_mtime) - -def main(exampledir,sourcedir): - - noplot_regex = re.compile(r"#\s*-\*-\s*noplot\s*-\*-") - - datad = {} - for root, subFolders, files in os.walk(exampledir): - for fname in files: - if ( fname.startswith('.') or fname.startswith('#') or fname.startswith('_') or - fname.find('.svn')>=0 or not fname.endswith('.py') ): - continue - - fullpath = os.path.join(root,fname) - contents = file(fullpath).read() - # indent - relpath = os.path.split(root)[-1] - datad.setdefault(relpath, []).append((fullpath, fname, contents)) - - subdirs = datad.keys() - subdirs.sort() - output_dir=os.path.join(sourcedir,'examples') - if not os.path.exists(output_dir): - os.makedirs(output_dir) - fhindex = file(os.path.join(sourcedir,'examples','index.rst'), 'w') - fhindex.write("""\ -.. _examples-index: - -******** -Examples -******** - -.. only:: html - - :Release: |version| - :Date: |today| - -.. toctree:: - :maxdepth: 2 - -""") - - for subdir in subdirs: - output_dir= os.path.join(sourcedir,'examples',subdir) - if not os.path.exists(output_dir): - os.makedirs(output_dir) - - static_dir = os.path.join(sourcedir, 'static', 'examples') - if not os.path.exists(static_dir): - os.makedirs(static_dir) - - - subdirIndexFile = os.path.join(subdir, 'index.rst') - fhsubdirIndex = file(os.path.join(output_dir,'index.rst'), 'w') - fhindex.write(' %s\n\n'%subdirIndexFile) - #thumbdir = '../_static/plot_directive/mpl_examples/%s/thumbnails/'%subdir - #for thumbname in glob.glob(os.path.join(thumbdir,'*.png')): - # fhindex.write(' %s\n'%thumbname) - - fhsubdirIndex.write("""\ -.. _%s-examples-index: - - -############################################## -%s -############################################## - -.. only:: html - - :Release: |version| - :Date: |today| - -.. toctree:: - :maxdepth: 1 - -"""%(subdir, subdir.title())) - - - data = datad[subdir] - data.sort() - - #parts = os.path.split(static_dir) - #thumb_dir = ('../'*(len(parts)-1)) + os.path.join(static_dir, 'thumbnails') - - for fullpath, fname, contents in data: - basename, ext = os.path.splitext(fname) - static_file = os.path.join(static_dir, fname) - #thumbfile = os.path.join(thumb_dir, '%s.png'%basename) - #print ' static_dir=%s, basename=%s, fullpath=%s, fname=%s, thumb_dir=%s, thumbfile=%s'%(static_dir, basename, fullpath, fname, thumb_dir, thumbfile) - - rstfile = '%s.rst'%basename - outfile = os.path.join(output_dir, rstfile) - - fhsubdirIndex.write(' %s\n'%rstfile) - - if (not out_of_date(fullpath, static_file) and - not out_of_date(fullpath, outfile)): - continue - - print('%s/%s' % (subdir,fname)) - - fhstatic = file(static_file, 'w') - fhstatic.write(contents) - fhstatic.close() - - fh = file(outfile, 'w') - fh.write('.. _%s-%s:\n\n'%(subdir, basename)) - base=fname.partition('.')[0] - title = '%s'%(base.replace('_',' ').title()) - - - #title = ' %s example code: %s'%(thumbfile, subdir, fname) - - - fh.write(title + '\n') - fh.write('='*len(title) + '\n\n') - - pngname=base+".png" - png=os.path.join(static_dir,pngname) - linkname = os.path.join('..', '..', 'static', 'examples') - if os.path.exists(png): - fh.write('.. image:: %s \n\n'%os.path.join(linkname,pngname)) - linkname = os.path.join('..', '..', '_static', 'examples') - fh.write("[`source code <%s>`_]\n\n::\n\n" % os.path.join(linkname,fname)) - - # indent the contents - contents = '\n'.join([' %s'%row.rstrip() for row in contents.split('\n')]) - fh.write(contents) - - # fh.write('\n\nKeywords: python, matplotlib, pylab, example, codex (see :ref:`how-to-search-examples`)') - fh.close() - - fhsubdirIndex.close() - - fhindex.close() - -if __name__ == '__main__': - import sys - try: - arg0,arg1,arg2=sys.argv[:3] - except: - arg0=sys.argv[0] - print(""" -Usage: %s exampledir sourcedir - - exampledir: a directory containing the python code for the examples. - sourcedir: a directory to put the generated documentation source for these examples. - - """ % (arg0)) - else: - main(arg1,arg2) - diff --git a/doc/make_gallery.py b/doc/make_gallery.py deleted file mode 100755 index 26572cf95c0..00000000000 --- a/doc/make_gallery.py +++ /dev/null @@ -1,91 +0,0 @@ -""" -Generate a thumbnail gallery of examples. - -""" -from __future__ import print_function - -import os, glob, re, shutil, sys -import matplotlib -matplotlib.use("Agg") -import matplotlib.pyplot -import matplotlib.image -from matplotlib.figure import Figure -from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas - -examples_source_dir = '../examples/drawing' -examples_dir = 'examples/drawing' -template_dir = 'source/templates' -static_dir = 'source/static/examples' -pwd=os.getcwd() -rows = [] - -template = """ -{%% extends "layout.html" %%} -{%% set title = "Gallery" %%} - - -{%% block body %%} - -

Click on any image to see source code

-
- -%s -{%% endblock %%} -""" - -link_template = """ -%s -""" - -if not os.path.exists(static_dir): - os.makedirs(static_dir) - -os.chdir(examples_source_dir) -all_examples=sorted(glob.glob("*.py")) - -# check for out of date examples -stale_examples=[] -for example in all_examples: - png=example.replace('py','png') - png_static=os.path.join(pwd,static_dir,png) - if (not os.path.exists(png_static) or - os.stat(png_static).st_mtime < os.stat(example).st_mtime): - stale_examples.append(example) - -for example in stale_examples: - print(example, end=" ") - png=example.replace('py','png') - matplotlib.pyplot.figure(figsize=(6,6)) - stdout=sys.stdout - sys.stdout=open('/dev/null','w') - try: - execfile(example) - sys.stdout=stdout - print(" OK") - except ImportError as strerr: - sys.stdout=stdout - sys.stdout.write(" FAIL: %s\n" % strerr) - continue - matplotlib.pyplot.clf() - im=matplotlib.image.imread(png) - fig = Figure(figsize=(2.5, 2.5)) - canvas = FigureCanvas(fig) - ax = fig.add_axes([0,0,1,1], aspect='auto', frameon=False, xticks=[], yticks -=[]) -# basename, ext = os.path.splitext(basename) - ax.imshow(im, aspect='auto', resample=True, interpolation='bilinear') - thumbfile=png.replace(".png","_thumb.png") - fig.savefig(thumbfile) - shutil.copy(thumbfile,os.path.join(pwd,static_dir,thumbfile)) - shutil.copy(png,os.path.join(pwd,static_dir,png)) - - basename, ext = os.path.splitext(example) - link = '%s/%s.html'%(examples_dir, basename) - rows.append(link_template%(link, os.path.join('_static/examples',thumbfile), basename)) - - -os.chdir(pwd) -fh = open(os.path.join(template_dir,'gallery.html'), 'w') -fh.write(template%'\n'.join(rows)) -fh.close() - diff --git a/doc/requirements.txt b/doc/requirements.txt index 65fa2261136..6c14a6c0d7e 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -1,7 +1,9 @@ -ipython[nbconvert] -numpy >= 1.6 -matplotlib -pandas +numpy >= 1.13.1 +matplotlib >= 2.0.2 +pandas >= 0.20.3 pydot >= 1.2.3 -sphinx -sphinx_rtd_theme +pygraphviz >= 1.3.1 +sphinx >= 1.6.2 +sphinx_rtd_theme >= 0.2.4 +sphinx-gallery >= 0.1.11 +pillow >= 4.2.1 diff --git a/doc/rst_templates/autosummary/base.rst b/doc/rst_templates/autosummary/base.rst deleted file mode 100644 index 55741485903..00000000000 --- a/doc/rst_templates/autosummary/base.rst +++ /dev/null @@ -1,6 +0,0 @@ -{{ name }} -{{ underline }} - -.. currentmodule:: {{ module }} - -.. auto{{ objtype }}:: {{ objname }} diff --git a/doc/rst_templates/autosummary/class.rst b/doc/rst_templates/autosummary/class.rst deleted file mode 100644 index 6fa9f3bc930..00000000000 --- a/doc/rst_templates/autosummary/class.rst +++ /dev/null @@ -1,30 +0,0 @@ -{{ name }} -{{ underline }} - -.. currentmodule:: {{ module }} - -.. autoclass:: {{ objname }} - - {% block methods %} - .. automethod:: __init__ - - {% if methods %} - .. rubric:: Methods - - .. autosummary:: - {% for item in methods %} - ~{{ name }}.{{ item }} - {%- endfor %} - {% endif %} - {% endblock %} - - {% block attributes %} - {% if attributes %} - .. rubric:: Attributes - - .. autosummary:: - {% for item in attributes %} - ~{{ name }}.{{ item }} - {%- endfor %} - {% endif %} - {% endblock %} diff --git a/doc/rst_templates/autosummary/function.rst b/doc/rst_templates/autosummary/function.rst deleted file mode 100644 index cb986e86d01..00000000000 --- a/doc/rst_templates/autosummary/function.rst +++ /dev/null @@ -1,7 +0,0 @@ -{{ name }} -{{ underline }} - -.. currentmodule:: {{ module }} - -.. autofunction:: {{ objname }} - diff --git a/doc/rst_templates/autosummary/module.rst b/doc/rst_templates/autosummary/module.rst deleted file mode 100644 index e113e55bb94..00000000000 --- a/doc/rst_templates/autosummary/module.rst +++ /dev/null @@ -1,37 +0,0 @@ -{{ name }} -{{ underline }} - -.. automodule:: {{ name }} - - {% block functions %} - {% if functions %} - .. rubric:: Functions - - .. autosummary:: - {% for item in functions %} - {{ item }} - {%- endfor %} - {% endif %} - {% endblock %} - - {% block classes %} - {% if classes %} - .. rubric:: Classes - - .. autosummary:: - {% for item in classes %} - {{ item }} - {%- endfor %} - {% endif %} - {% endblock %} - - {% block exceptions %} - {% if exceptions %} - .. rubric:: Exceptions - - .. autosummary:: - {% for item in exceptions %} - {{ item }} - {%- endfor %} - {% endif %} - {% endblock %} diff --git a/doc/source/conf.py b/doc/source/conf.py index 1383326fcbc..e97cc4d1930 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -12,26 +12,32 @@ # serve to show the default value. from __future__ import print_function -import sys, os, re -import contextlib - -@contextlib.contextmanager -def cd(newpath): - """ - Change the current working directory to `newpath`, temporarily. - - If the old current working directory no longer exists, do not return back. - """ - oldpath = os.getcwd() - os.chdir(newpath) - try: - yield - finally: - try: - os.chdir(oldpath) - except OSError: - # If oldpath no longer exists, stay where we are. - pass +import sys +import os +import re +#import contextlib +from datetime import date + +#from sphinx_gallery.sorting import ExplicitOrder + +#@contextlib.contextmanager +#def cd(newpath): +# """ +# Change the current working directory to `newpath`, temporarily. +# +# If the old current working directory no longer exists, do not return back. +# """ +# oldpath = os.getcwd() +# os.chdir(newpath) +# try: +# yield +# finally: +# try: +# os.chdir(oldpath) +# except OSError: +# # If oldpath no longer exists, stay where we are. +# pass +# # Check Sphinx version import sphinx @@ -40,22 +46,22 @@ def cd(newpath): # Environment variable to know if the docs are being built on rtd. on_rtd = os.environ.get('READTHEDOCS', None) == 'True' -print -print("Building on ReadTheDocs: {}".format(on_rtd)) -print -print("Current working directory: {}".format(os.path.abspath(os.curdir))) -print("Python: {}".format(sys.executable)) - -if on_rtd: - # Build is not via Makefile (yet). - # So we manually build the examples and gallery. - import subprocess - with cd('..'): - # The Makefile is run from networkx/doc, so we need to move there - # from networkx/doc/source (which holds conf.py). - py = sys.executable - subprocess.call([py, 'make_gallery.py']) - subprocess.call([py, 'make_examples_rst.py', '../examples', 'source']) +#print +#print("Building on ReadTheDocs: {}".format(on_rtd)) +#print +#print("Current working directory: {}".format(os.path.abspath(os.curdir))) +#print("Python: {}".format(sys.executable)) + +#if on_rtd: +# # Build is not via Makefile (yet). +# # So we manually build the examples and gallery. +# import subprocess +# with cd('..'): +# # The Makefile is run from networkx/doc, so we need to move there +# # from networkx/doc/source (which holds conf.py). +# py = sys.executable +# subprocess.call([py, 'make_gallery.py']) +# subprocess.call([py, 'make_examples_rst.py', '../examples', 'source']) # If your extensions are in another directory, add it here. # These locations are relative to conf.py @@ -75,14 +81,33 @@ def cd(newpath): 'sphinx.ext.napoleon', 'sphinx.ext.todo', 'sphinx.ext.viewcode', + 'sphinx_gallery.gen_gallery', ] +# https://github.com/sphinx-gallery/sphinx-gallery +sphinx_gallery_conf = { + # path to your examples scripts + 'examples_dirs': '../../examples', +# 'subsection_order': ExplicitOrder(['../../examples/basic', +# '../../examples/drawing', +# '../../examples/3d_drawing', +# '../../examples/pygraphviz', +# '../../examples/graph', +# '../../examples/algorithms', +# '../../examples/advanced', +# '../../examples/javascript', +# '../../examples/jit', +# '../../examples/subclass']), + # path where to save gallery generated examples + 'gallery_dirs': 'auto_examples', + 'backreferences_dir': 'modules/generated' +} # generate autosummary pages -autosummary_generate=True +autosummary_generate = True # Add any paths that contain templates here, relative to this directory. -templates_path = ['templates','../rst_templates'] +#templates_path = ['templates', '../rst_templates'] # The suffix of source filenames. source_suffix = '.rst' @@ -95,7 +120,7 @@ def cd(newpath): # General substitutions. project = 'NetworkX' -copyright = '2004-2017, NetworkX Developers' +copyright = '2004-{}, NetworkX Developers'.format(date.today().year) # The default replacements for |version| and |release|, also used in various # other places throughout the built documents. @@ -104,7 +129,7 @@ def cd(newpath): import networkx version = networkx.__version__ # The full version, including dev info -release = networkx.__version__.replace('_','') +release = networkx.__version__.replace('_', '') # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: @@ -130,9 +155,9 @@ def cd(newpath): pygments_style = 'sphinx' # A list of prefixs that are ignored when creating the module index. (new in Sphinx 0.6) -modindex_common_prefix=['networkx.'] +modindex_common_prefix = ['networkx.'] -doctest_global_setup="import networkx as nx" +doctest_global_setup = "import networkx as nx" # treat ``x, y : type`` as vars x and y instead of default ``y(x,) : type`` napoleon_use_param = False @@ -145,7 +170,7 @@ def cd(newpath): html_theme = 'sphinx_rtd_theme' html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] -#html_theme_options = { +# html_theme_options = { # "rightsidebar": "true", # "relbarbgcolor: "black" #} @@ -171,7 +196,7 @@ def cd(newpath): # Content template for the index page. #html_index = 'index.html' -html_index = 'contents.html' +#html_index = 'contents.html' # Custom sidebar templates, maps page names to templates. #html_sidebars = {} @@ -179,7 +204,7 @@ def cd(newpath): # Additional templates that should be rendered to pages, maps page names to # templates. #html_additional_pages = {'index': 'index.html','gallery':'gallery.html'} -html_additional_pages = {'gallery':'gallery.html'} +#html_additional_pages = {'gallery': 'gallery.html'} # If true, the reST sources are included in the HTML build as _sources/. html_copy_source = False @@ -203,18 +228,18 @@ def cd(newpath): latex_documents = [('tutorial/index', 'networkx_tutorial.tex', 'NetworkX Tutorial', 'Aric Hagberg, Dan Schult, Pieter Swart', 'howto', 1), - ('reference/pdf_reference', 'networkx_reference.tex', + ('reference/index', 'networkx_reference.tex', 'NetworkX Reference', 'Aric Hagberg, Dan Schult, Pieter Swart', 'manual', 1)] -#latex_appendices = ['installing']#,'legal'],'citing','credits','history'] +# latex_appendices = ['installing']#,'legal'],'citing','credits','history'] #latex_appendices = ['credits'] # Intersphinx mapping intersphinx_mapping = {'http://docs.python.org/': None, 'http://docs.scipy.org/doc/numpy/': None, - } + } # The reST default role (used for this markup: `text`) to use for all # documents. diff --git a/doc/source/developer/gitwash/configure_git.rst b/doc/source/developer/gitwash/configure_git.rst index 0e18b666d0b..3a172d5ba44 100644 --- a/doc/source/developer/gitwash/configure_git.rst +++ b/doc/source/developer/gitwash/configure_git.rst @@ -1,3 +1,5 @@ +.. highlight:: bash + .. _configure-git: =============== @@ -12,7 +14,9 @@ Overview Your personal git configurations are saved in the ``.gitconfig`` file in your home directory. -Here is an example ``.gitconfig`` file:: +Here is an example ``.gitconfig`` file: + +.. code-block:: none [user] name = Your Name @@ -63,7 +67,9 @@ line:: git config --global user.email you@yourdomain.example.com This will write the settings into your git configuration file, which -should now contain a user section with your name and email:: +should now contain a user section with your name and email: + +.. code-block:: none [user] name = Your Name @@ -91,7 +97,9 @@ The following ``git config --global`` commands:: git config --global alias.wdiff "diff --color-words" will create an ``alias`` section in your ``.gitconfig`` file with contents -like this:: +like this: + +.. code-block:: none [alias] ci = commit -a @@ -111,7 +119,9 @@ You may also want to make sure that your editor of choice is used :: Merging ------- -To enforce summaries when doing merges (``~/.gitconfig`` file again):: +To enforce summaries when doing merges (``~/.gitconfig`` file again): + +.. code-block:: none [merge] log = true @@ -126,7 +136,9 @@ Fancy log output ---------------- This is a very nice alias to get a fancy log output; it should go in the -``alias`` section of your ``.gitconfig`` file:: +``alias`` section of your ``.gitconfig`` file: + +.. code-block:: none lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)[%an]%Creset' --abbrev-commit --date=relative @@ -134,7 +146,9 @@ You use the alias with:: git lg -and it gives graph / text output something like this (but with color!):: +and it gives graph / text output something like this (but with color!): + +.. code-block:: none * 6d8e1ee - (HEAD, origin/my-fancy-feature, my-fancy-feature) NF - a fancy file (45 minutes ago) [Matthew Brett] * d304a73 - (origin/placeholder, placeholder) Merge pull request #48 from hhuuggoo/master (2 weeks ago) [Jonathan Terhorst] diff --git a/doc/source/developer/gitwash/development_workflow.rst b/doc/source/developer/gitwash/development_workflow.rst index 2f6f8f33600..957f0e7d030 100644 --- a/doc/source/developer/gitwash/development_workflow.rst +++ b/doc/source/developer/gitwash/development_workflow.rst @@ -1,3 +1,5 @@ +.. highlight:: bash + .. _development-workflow: #################### @@ -5,7 +7,7 @@ Development workflow #################### You already have your own forked copy of the `networkx`_ repository, by -following :ref:`forking`. You have :ref:`set-up-fork`. You have configured +following :ref:`forking`. You have :ref:`set-up-fork`. You have configured git by following :ref:`configure-git`. Now you are ready for some real work. Workflow summary @@ -26,14 +28,14 @@ In what follows we'll refer to the upstream networkx ``master`` branch, as * If you do find yourself merging from trunk, consider :ref:`rebase-on-trunk` * Ask on the `networkx mailing list`_ if you get stuck. * Check that your code meets the requirements as outlined in our - (wiki)[https://github.com/networkx/networkx/wiki]. + `wiki `_. * Ask for code review! This way of working helps to keep work well organized, with readable history. This in turn makes it easier for project maintainers (that might be you) to see what you've done, and why you did it. -See `ipython git workflow`_ for some explanation. +See `linux git workflow`_ and `ipython git workflow`_ for some explanation. Consider deleting your master branch ==================================== @@ -118,7 +120,9 @@ In more detail #. Make some changes #. See which files have changed with ``git status`` (see `git status`_). - You'll see a listing like this one:: + You'll see a listing like this one: + + .. code-block:: none # On branch ny-new-feature # Changed but not updated: @@ -138,10 +142,10 @@ In more detail `git add`_). #. To commit all modified files into the local copy of your repo,, do ``git commit -am 'A commit message'``. Note the ``-am`` options to - ``commit``. The ``m`` flag just signals that you're going to type a + ``commit``. The ``m`` flag just signals that you're going to type a message on the command line. The ``a`` flag |emdash| you can just take on faith |emdash| or see `why the -a flag?`_ |emdash| and the helpful use-case - description in the `tangled working copy problem`_. The `git commit`_ manual + description in the `tangled working copy problem`_. The `git commit`_ manual page might also be useful. #. To push the changes up to your forked repo on github, do a ``git push`` (see `git push`_). @@ -152,7 +156,7 @@ Ask for your changes to be reviewed or merged When you are ready to ask for someone to review your code and consider a merge: #. Go to the URL of your forked repo, say - ``http://github.com/your-user-name/networkx``. + ``https://github.com/your-user-name/networkx``. #. Use the 'Switch Branches' dropdown menu near the top left of the page to select the branch with your changes: @@ -184,8 +188,8 @@ Delete a branch on github # delete branch on github git push origin :my-unwanted-branch -(Note the colon ``:`` before ``test-branch``. See also: -http://github.com/guides/remove-a-remote-branch +Note the colon ``:`` before ``my-unwanted-branch``. See also: +https://help.github.com/articles/pushing-to-a-remote/#deleting-a-remote-branch-or-tag Several people sharing a single repository ------------------------------------------ @@ -197,7 +201,7 @@ share it via github. First fork networkx into your account, as from :ref:`forking`. Then, go to your forked repository github page, say -``http://github.com/your-user-name/networkx`` +``https://github.com/your-user-name/networkx`` Click on the 'Admin' button, and add anyone else to the repo as a collaborator: @@ -242,10 +246,12 @@ Rebasing on trunk Let's say you thought of some work you'd like to do. You :ref:`update-mirror-trunk` and :ref:`make-feature-branch` called -``cool-feature``. At this stage trunk is at some commit, let's call it E. Now +``cool-feature``. At this stage trunk is at some commit, let's call it E. Now you make some new commits on your ``cool-feature`` branch, let's call them A, B, C. Maybe your changes take a while, or you come back to them after a while. In -the meantime, trunk has progressed from commit E to commit (say) G:: +the meantime, trunk has progressed from commit E to commit (say) G: + +.. code-block:: none A---B---C cool-feature / @@ -253,15 +259,17 @@ the meantime, trunk has progressed from commit E to commit (say) G:: At this stage you consider merging trunk into your feature branch, and you remember that this here page sternly advises you not to do that, because the -history will get messy. Most of the time you can just ask for a review, and not +history will get messy. Most of the time you can just ask for a review, and not worry that trunk has got a little ahead. But sometimes, the changes in trunk might affect your changes, and you need to harmonize them. In this situation you may prefer to do a rebase. rebase takes your changes (A, B, C) and replays them as if they had been made to the current state of ``trunk``. In other words, in this case, it takes the -changes represented by A, B, C and replays them on top of G. After the rebase, -your history will look like this:: +changes represented by A, B, C and replays them on top of G. After the rebase, +your history will look like this: + +.. code-block:: none A'--B'--C' cool-feature / @@ -294,7 +302,7 @@ If it doesn't look good you may need to have a look at If you have made changes to files that have also changed in trunk, this may generate merge conflicts that you need to resolve - see the `git rebase`_ man -page for some instructions at the end of the "Description" section. There is +page for some instructions at the end of the "Description" section. There is some related help on merging in the git user manual - see `resolving a merge`_. .. _recovering-from-mess-up: @@ -302,7 +310,7 @@ some related help on merging in the git user manual - see `resolving a merge`_. Recovering from mess-ups ------------------------ -Sometimes, you mess up merges or rebases. Luckily, in git it is +Sometimes, you mess up merges or rebases. Luckily, in git it is relatively straightforward to recover from such mistakes. If you mess up during a rebase:: @@ -336,7 +344,7 @@ Rewriting commit history Do this only for your own feature branches. -There's an embarassing typo in a commit you made? Or perhaps the you +There's an embarrassing typo in a commit you made? Or perhaps the you made several false starts you would like the posterity not to see. This can be done via *interactive rebasing*. @@ -352,7 +360,7 @@ Suppose that the commit history looks like this:: 29001ed Add pre-nep for a copule of structured_array_extensions. ... -and ``6ad92e5`` is the last commit in the ``cool-feature`` branch. Suppose we +and ``6ad92e5`` is the last commit in the ``cool-feature`` branch. Suppose we want to make the following changes: * Rewrite the commit message for ``13d7934`` to something more sensible. @@ -393,11 +401,11 @@ To achieve what we want, we will make the following changes to it:: f eadc391 Fix some remaining bugs This means that (i) we want to edit the commit message for -``13d7934``, and (ii) collapse the last three commits into one. Now we +``13d7934``, and (ii) collapse the last three commits into one. Now we save and quit the editor. Git will then immediately bring up an editor for editing the commit -message. After revising it, we get the output:: +message. After revising it, we get the output:: [detached HEAD 721fc64] FOO: First implementation 2 files changed, 199 insertions(+), 66 deletions(-) diff --git a/doc/source/developer/gitwash/following_latest.rst b/doc/source/developer/gitwash/following_latest.rst index 336d337a16b..78a52ddd69f 100644 --- a/doc/source/developer/gitwash/following_latest.rst +++ b/doc/source/developer/gitwash/following_latest.rst @@ -1,3 +1,5 @@ +.. highlight:: bash + .. _following-latest: ============================= @@ -25,39 +27,12 @@ You now have a copy of the code tree in the new ``networkx`` directory. Updating the code ================= -From time to time you may want to pull down the latest code. It is necessary -to add the networkx repository as a remote to your configuration file. We call it -upstream. - - git remote set-url upstream https://github.com/networkx/networkx.git - -Now git knows where to fetch updates from. +From time to time you may want to pull down the latest code. Do this with:: cd networkx - git fetch upstream + git pull The tree in ``networkx`` will now have the latest changes from the initial -repository, unless you have made local changes in the meantime. In this -case, you have to merge. - - git merge upstream/master - -It is also possible to update your local fork directly from GitHub: - - 1. Open your fork on GitHub. - 2. Click on 'Pull Requests'. - 3. Click on 'New Pull Request'. By default, GitHub will compare the - original with your fork. If you didn’t make any changes, there is - nothing to compare. - 4. Click on 'Switching the base' or click 'Edit' and switch the - base manually. Now GitHub will compare your fork with the original, - and you should see all the latest changes. - 5. Click on 'Click to create a pull request for this comparison' and name - your pull request. - 6. Click on Send pull request. - 7. Scroll down and click 'Merge pull request' and finally 'Confirm merge'. - You will be able to merge it automatically unless you did not change - you local repo. - +repository. .. include:: links.inc diff --git a/doc/source/developer/gitwash/forking_hell.rst b/doc/source/developer/gitwash/forking_hell.rst index 1e29fc8002e..079767a794b 100644 --- a/doc/source/developer/gitwash/forking_hell.rst +++ b/doc/source/developer/gitwash/forking_hell.rst @@ -1,3 +1,5 @@ +.. highlight:: bash + .. _forking: ====================================================== @@ -5,7 +7,7 @@ Making your own copy (fork) of networkx ====================================================== You need to do this only once. The instructions here are very similar -to the instructions at https://help.github.com/articles/fork-a-repo/ |emdash| please see +to the instructions at https://help.github.com/forking/ |emdash| please see that page for more detail. We're repeating some of it here just to give the specifics for the `networkx`_ project, and to suggest some default names. @@ -26,8 +28,7 @@ Create your own forked copy of `networkx`_ .. image:: forking_button.png - Now, after a short pause and some 'Hardcore forking action', you - should find yourself at the home page for your own forked copy of `networkx`_. + Now, after a short pause, you should find yourself at the home page for + your own forked copy of `networkx`_. .. include:: links.inc - diff --git a/doc/source/developer/gitwash/git_install.rst b/doc/source/developer/gitwash/git_install.rst index d39003ec8d9..686f54eac62 100644 --- a/doc/source/developer/gitwash/git_install.rst +++ b/doc/source/developer/gitwash/git_install.rst @@ -1,3 +1,5 @@ +.. highlight:: bash + .. _install-git: ============= @@ -9,7 +11,7 @@ Overview ================ ============= Debian / Ubuntu ``sudo apt-get install git`` -Fedora ``sudo yum install git-core`` +Fedora ``sudo dnf install git`` Windows Download and install msysGit_ OS X Use the git-osx-installer_ ================ ============= @@ -21,6 +23,6 @@ See the git page for the most recent information. Have a look at the github install help pages available from `github help`_ -There are good instructions here: http://book.git-scm.com/2_installing_git.html +There are good instructions here: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git .. include:: links.inc diff --git a/doc/source/developer/gitwash/git_intro.rst b/doc/source/developer/gitwash/git_intro.rst index 686eac844f8..19762ab98df 100644 --- a/doc/source/developer/gitwash/git_intro.rst +++ b/doc/source/developer/gitwash/git_intro.rst @@ -1,3 +1,5 @@ +.. highlight:: bash + ============== Introduction ============== @@ -9,7 +11,7 @@ There are several different workflows here, for different ways of working with *networkx*. This is not a comprehensive git reference, it's just a workflow for our -own project. It's tailored to the github hosting service. You may well +own project. It's tailored to the github hosting service. You may well find better or quicker ways of getting stuff done with git, but these should get you started. diff --git a/doc/source/developer/gitwash/git_links.inc b/doc/source/developer/gitwash/git_links.inc index ba0c91a180f..d01ad7833c3 100644 --- a/doc/source/developer/gitwash/git_links.inc +++ b/doc/source/developer/gitwash/git_links.inc @@ -8,49 +8,51 @@ __not_case_sensitive__, so only one target definition is needed for nipy, NIPY, Nipy, etc... -.. git internals -.. _git: http://git-scm.com/ -.. _github: http://github.com -.. _github help: https://git-scm.com/docs/git -.. _github more help: https://help.github.com/articles/git-and-github-learning-resources/ -.. _git svn crash course: http://git-scm.com/course/svn.html -.. _network graph visualizer: http://github.com/blog/39-say-hello-to-the-network-graph-visualizer -.. _git tutorial: https://git-scm.com/docs/gittutorial -.. _git clone: https://git-scm.com/docs/git-clone -.. _git checkout: https://git-scm.com/docs/git-checkout -.. _git commit: https://git-scm.com/docs/git-commit -.. _git push: https://git-scm.com/docs/git-push -.. _git pull: https://git-scm.com/docs/git-pull -.. _git add: https://git-scm.com/docs/git-add -.. _git status: https://git-scm.com/docs/git-status -.. _git diff: https://git-scm.com/docs/git-diff -.. _git log: https://git-scm.com/docs/git-log -.. _git branch: https://git-scm.com/docs/git-branch -.. _git remote: https://git-scm.com/docs/git-remote -.. _git rebase: https://git-scm.com/docs/git-rebase -.. _git config: https://git-scm.com/docs/git-config - -.. git guides -.. _git concepts: http://www.eecs.harvard.edu/~cduan/technical/git/ -.. _git magic: http://www-cs-students.stanford.edu/~blynn/gitmagic/index.html -.. _msysgit: http://code.google.com/p/msysgit/downloads/list -.. _git-osx-installer: http://code.google.com/p/git-osx-installer/downloads/list +.. git stuff +.. _git: https://git-scm.com/ +.. _github: https://github.com +.. _github help: https://help.github.com +.. _msysgit: https://git-scm.com/download/win +.. _git-osx-installer: https://git-scm.com/download/mac .. _subversion: http://subversion.tigris.org/ -.. _Nick Quaranto: http://www.gitready.com/ -.. _Fernando Perez: http://www.fperez.org/py4science/git.html -.. _why the -a flag?: http://www.gitready.com/beginner/2009/01/18/the-staging-area.html -.. _git staging area: http://www.gitready.com/beginner/2009/01/18/the-staging-area.html -.. _tangled working copy problem: http://tomayko.com/writings/the-thing-about-git -.. _Linus Torvalds: http://www.mail-archive.com/dri-devel@lists.sourceforge.net/msg39091.html +.. _git cheat sheet: https://help.github.com/git-cheat-sheets/ +.. _pro git book: https://progit.org/ +.. _git svn crash course: https://git-scm.com/course/svn.html +.. _network graph visualizer: https://github.com/blog/39-say-hello-to-the-network-graph-visualizer +.. _git user manual: https://schacon.github.io/git/user-manual.html +.. _git tutorial: https://schacon.github.io/git/gittutorial.html +.. _git community book: https://git-scm.com/book/en/v2 +.. _git ready: http://gitready.com/ +.. _Fernando's git page: http://www.fperez.org/py4science/git.html +.. _git magic: http://www-cs-students.stanford.edu/~blynn/gitmagic/index.html +.. _git concepts: https://www.sbf5.com/~cduan/technical/git/ +.. _git clone: https://schacon.github.io/git/git-clone.html +.. _git checkout: https://schacon.github.io/git/git-checkout.html +.. _git commit: https://schacon.github.io/git/git-commit.html +.. _git push: https://schacon.github.io/git/git-push.html +.. _git pull: https://schacon.github.io/git/git-pull.html +.. _git add: https://schacon.github.io/git/git-add.html +.. _git status: https://schacon.github.io/git/git-status.html +.. _git diff: https://schacon.github.io/git/git-diff.html +.. _git log: https://schacon.github.io/git/git-log.html +.. _git branch: https://schacon.github.io/git/git-branch.html +.. _git remote: https://schacon.github.io/git/git-remote.html +.. _git rebase: https://schacon.github.io/git/git-rebase.html +.. _git config: https://schacon.github.io/git/git-config.html +.. _why the -a flag?: http://gitready.com/beginner/2009/01/18/the-staging-area.html +.. _git staging area: http://gitready.com/beginner/2009/01/18/the-staging-area.html +.. _tangled working copy problem: http://2ndscale.com/rtomayko/2008/the-thing-about-git +.. _git management: https://web.archive.org/web/20090224195437/http://kerneltrap.org/Linux/Git_Management +.. _linux git workflow: https://www.mail-archive.com/dri-devel@lists.sourceforge.net/msg39091.html .. _git parable: http://tom.preston-werner.com/2009/05/19/the-git-parable.html -.. _git foundation: http://matthew-brett.github.com/pydagogue/foundation.html -.. _deleting master on github: http://matthew-brett.github.com/pydagogue/gh_delete_master.html -.. _rebase without tears: http://matthew-brett.github.com/pydagogue/rebase_without_tears.html -.. _resolving a merge: http://schacon.github.com/git/user-manual.html#resolving-a-merge -.. _ipython git workflow: http://mail.scipy.org/pipermail/ipython-dev/2010-October/006746.html +.. _git foundation: https://matthew-brett.github.io/pydagogue/foundation.html +.. _deleting master on github: https://matthew-brett.github.io/pydagogue/gh_delete_master.html +.. _rebase without tears: https://matthew-brett.github.io/pydagogue/rebase_without_tears.html +.. _resolving a merge: https://schacon.github.io/git/user-manual.html#resolving-a-merge +.. _ipython git workflow: https://mail.scipy.org/pipermail/ipython-dev/2010-October/006746.html .. other stuff -.. _python: http://www.python.org +.. _python: https://www.python.org .. |emdash| unicode:: U+02014 diff --git a/doc/source/developer/gitwash/git_resources.rst b/doc/source/developer/gitwash/git_resources.rst index 7d93a7fb302..2787a575cc4 100644 --- a/doc/source/developer/gitwash/git_resources.rst +++ b/doc/source/developer/gitwash/git_resources.rst @@ -1,3 +1,5 @@ +.. highlight:: bash + .. _git-resources: ============= @@ -7,21 +9,32 @@ git resources Tutorials and summaries ======================= -`github help`_ is Git's own help and tutorial site. `github more help`_ -lists more resources for learning Git and GitHub, including YouTube -channels. The list is constantly updated. In case you are used to subversion_ -, you can directly consult the `git svn crash course`_. - -To make full use of Git, you need to understand the concept behind Git. -The following pages might help you: - -* `git parable`_ |emdash| an easy read parable -* `git foundation`_ |emdash| more on the git parable -* `git magic`_ |emdash| extended introduction with intermediate detail in many languages -* `git concepts`_ |emdash| a technical page on the concepts - -Other than that, many devlopers list their personal tips and tricks. -Among others there are `Fernando Perez`_, `Nick Quaranto`_ and `Linus Torvalds`_. +* `github help`_ has an excellent series of how-to guides. +* The `pro git book`_ is a good in-depth book on git. +* A `git cheat sheet`_ is a page giving summaries of common commands. +* The `git user manual`_ +* The `git tutorial`_ +* The `git community book`_ +* `git ready`_ |emdash| a nice series of tutorials +* `git magic`_ |emdash| extended introduction with intermediate detail +* The `git parable`_ is an easy read explaining the concepts behind git. +* `git foundation`_ expands on the `git parable`_. +* Fernando Perez' git page |emdash| `Fernando's git page`_ |emdash| many + links and tips +* A good but technical page on `git concepts`_ +* `git svn crash course`_: git for those of us used to subversion_ + +Advanced git workflow +===================== + +There are many ways of working with git; here are some posts on the +rules of thumb that other projects have come up with: + +* Linus Torvalds on `git management`_ +* Linus Torvalds on `linux git workflow`_ . Summary; use the git tools + to make the history of your edits as clean as possible; merge from + upstream edits as little as possible in branches where you are doing + active development. Manual pages online =================== diff --git a/doc/source/developer/gitwash/index.rst b/doc/source/developer/gitwash/index.rst index 628abc6b8b8..01629d1c227 100644 --- a/doc/source/developer/gitwash/index.rst +++ b/doc/source/developer/gitwash/index.rst @@ -11,5 +11,6 @@ Contents: git_intro git_install following_latest + patching git_development git_resources diff --git a/doc/source/developer/gitwash/known_projects.inc b/doc/source/developer/gitwash/known_projects.inc index 29723528779..710abe08e47 100644 --- a/doc/source/developer/gitwash/known_projects.inc +++ b/doc/source/developer/gitwash/known_projects.inc @@ -1,41 +1,41 @@ .. Known projects .. PROJECTNAME placeholders -.. _PROJECTNAME: http://neuroimaging.scipy.org -.. _`PROJECTNAME github`: http://github.com/nipy -.. _`PROJECTNAME mailing list`: http://projects.scipy.org/mailman/listinfo/nipy-devel +.. _PROJECTNAME: http://nipy.org +.. _`PROJECTNAME github`: https://github.com/nipy +.. _`PROJECTNAME mailing list`: https://mail.python.org/mailman/listinfo/neuroimaging .. numpy -.. _numpy: hhttp://numpy.scipy.org -.. _`numpy github`: http://github.com/numpy/numpy -.. _`numpy mailing list`: http://mail.scipy.org/mailman/listinfo/numpy-discussion +.. _numpy: http://www.numpy.org +.. _`numpy github`: https://github.com/numpy/numpy +.. _`numpy mailing list`: https://mail.scipy.org/mailman/listinfo/numpy-discussion .. scipy -.. _scipy: http://www.scipy.org -.. _`scipy github`: http://github.com/scipy/scipy -.. _`scipy mailing list`: http://mail.scipy.org/mailman/listinfo/scipy-dev +.. _scipy: https://www.scipy.org +.. _`scipy github`: https://github.com/scipy/scipy +.. _`scipy mailing list`: https://mail.scipy.org/mailman/listinfo/scipy-dev .. nipy -.. _nipy: http://nipy.org/nipy -.. _`nipy github`: http://github.com/nipy/nipy -.. _`nipy mailing list`: http://mail.scipy.org/mailman/listinfo/nipy-devel +.. _nipy: http://nipy.org/nipy/ +.. _`nipy github`: https://github.com/nipy/nipy +.. _`nipy mailing list`: https://mail.python.org/mailman/listinfo/neuroimaging .. ipython -.. _ipython: http://ipython.scipy.org -.. _`ipython github`: http://github.com/ipython/ipython -.. _`ipython mailing list`: http://mail.scipy.org/mailman/listinfo/IPython-dev +.. _ipython: https://ipython.org +.. _`ipython github`: https://github.com/ipython/ipython +.. _`ipython mailing list`: https://mail.scipy.org/mailman/listinfo/IPython-dev .. dipy -.. _dipy: http://nipy.org/dipy -.. _`dipy github`: http://github.com/Garyfallidis/dipy -.. _`dipy mailing list`: http://mail.scipy.org/mailman/listinfo/nipy-devel +.. _dipy: http://nipy.org/dipy/ +.. _`dipy github`: https://github.com/Garyfallidis/dipy +.. _`dipy mailing list`: https://mail.python.org/mailman/listinfo/neuroimaging .. nibabel -.. _nibabel: http://nipy.org/nibabel -.. _`nibabel github`: http://github.com/nipy/nibabel -.. _`nibabel mailing list`: http://mail.scipy.org/mailman/listinfo/nipy-devel +.. _nibabel: http://nipy.org/nibabel/ +.. _`nibabel github`: https://github.com/nipy/nibabel +.. _`nibabel mailing list`: https://mail.python.org/mailman/listinfo/neuroimaging .. marsbar .. _marsbar: http://marsbar.sourceforge.net -.. _`marsbar github`: http://github.com/matthew-brett/marsbar +.. _`marsbar github`: https://github.com/matthew-brett/marsbar .. _`MarsBaR mailing list`: https://lists.sourceforge.net/lists/listinfo/marsbar-users diff --git a/doc/source/developer/gitwash/maintainer_workflow.rst b/doc/source/developer/gitwash/maintainer_workflow.rst index fbeed301cd9..8c02467d296 100644 --- a/doc/source/developer/gitwash/maintainer_workflow.rst +++ b/doc/source/developer/gitwash/maintainer_workflow.rst @@ -1,3 +1,5 @@ +.. highlight:: bash + .. _maintainer-workflow: ################### diff --git a/doc/source/developer/gitwash/patching.rst b/doc/source/developer/gitwash/patching.rst new file mode 100644 index 00000000000..1c7f41b023d --- /dev/null +++ b/doc/source/developer/gitwash/patching.rst @@ -0,0 +1,138 @@ +.. highlight:: bash + +================ + Making a patch +================ + +You've discovered a bug or something else you want to change +in `networkx`_ .. |emdash| excellent! + +You've worked out a way to fix it |emdash| even better! + +You want to tell us about it |emdash| best of all! + +The easiest way is to make a *patch* or set of patches. Here +we explain how. Making a patch is the simplest and quickest, +but if you're going to be doing anything more than simple +quick things, please consider following the +:ref:`git-development` model instead. + +.. _making-patches: + +Making patches +============== + +Overview +-------- + +:: + + # tell git who you are + git config --global user.email you@yourdomain.example.com + git config --global user.name "Your Name Comes Here" + # get the repository if you don't have it + git clone git://github.com/networkx/networkx.git + # make a branch for your patching + cd networkx + git branch the-fix-im-thinking-of + git checkout the-fix-im-thinking-of + # hack, hack, hack + # Tell git about any new files you've made + git add somewhere/tests/test_my_bug.py + # commit work in progress as you go + git commit -am 'BF - added tests for Funny bug' + # hack hack, hack + git commit -am 'BF - added fix for Funny bug' + # make the patch files + git format-patch -M -C master + +Then, send the generated patch files to the `networkx +mailing list`_ |emdash| where we will thank you warmly. + +In detail +--------- + +#. Tell git who you are so it can label the commits you've + made:: + + git config --global user.email you@yourdomain.example.com + git config --global user.name "Your Name Comes Here" + +#. If you don't already have one, clone a copy of the + `networkx`_ repository:: + + git clone git://github.com/networkx/networkx.git + cd networkx + +#. Make a 'feature branch'. This will be where you work on + your bug fix. It's nice and safe and leaves you with + access to an unmodified copy of the code in the main + branch:: + + git branch the-fix-im-thinking-of + git checkout the-fix-im-thinking-of + +#. Do some edits, and commit them as you go:: + + # hack, hack, hack + # Tell git about any new files you've made + git add somewhere/tests/test_my_bug.py + # commit work in progress as you go + git commit -am 'BF - added tests for Funny bug' + # hack hack, hack + git commit -am 'BF - added fix for Funny bug' + + Note the ``-am`` options to ``commit``. The ``m`` flag just + signals that you're going to type a message on the command + line. The ``a`` flag |emdash| you can just take on faith |emdash| + or see `why the -a flag?`_. + +#. When you have finished, check you have committed all your + changes:: + + git status + +#. Finally, make your commits into patches. You want all the + commits since you branched from the ``master`` branch:: + + git format-patch -M -C master + + You will now have several files named for the commits: + + .. code-block:: none + + 0001-BF-added-tests-for-Funny-bug.patch + 0002-BF-added-fix-for-Funny-bug.patch + + Send these files to the `networkx mailing list`_. + +When you are done, to switch back to the main copy of the +code, just return to the ``master`` branch:: + + git checkout master + +Moving from patching to development +=================================== + +If you find you have done some patches, and you have one or +more feature branches, you will probably want to switch to +development mode. You can do this with the repository you +have. + +Fork the `networkx`_ repository on github |emdash| :ref:`forking`. +Then:: + + # checkout and refresh master branch from main repo + git checkout master + git pull origin master + # rename pointer to main repository to 'upstream' + git remote rename origin upstream + # point your repo to default read / write to your fork on github + git remote add origin git@github.com:your-user-name/networkx.git + # push up any branches you've made and want to keep + git push origin the-fix-im-thinking-of + +Then you can, if you want, follow the +:ref:`development-workflow`. + +.. include:: links.inc diff --git a/doc/source/developer/gitwash/set_up_fork.rst b/doc/source/developer/gitwash/set_up_fork.rst index 20239f70b02..12cf72b7266 100644 --- a/doc/source/developer/gitwash/set_up_fork.rst +++ b/doc/source/developer/gitwash/set_up_fork.rst @@ -1,3 +1,5 @@ +.. highlight:: bash + .. _set-up-fork: ================== @@ -25,7 +27,9 @@ Clone your fork git@github.com:your-user-name/networkx.git`` #. Investigate. Change directory to your new repo: ``cd networkx``. Then ``git branch -a`` to show you all branches. You'll get something - like:: + like: + + .. code-block:: none * master remotes/origin/master @@ -57,7 +61,9 @@ Note that we've used ``git://`` for the URL rather than ``git@``. The use it to merge into our own code. Just for your own satisfaction, show yourself that you now have a new -'remote', with ``git remote -v show``, giving you something like:: +'remote', with ``git remote -v show``, giving you something like: + +.. code-block:: none upstream git://github.com/networkx/networkx.git (fetch) upstream git://github.com/networkx/networkx.git (push) @@ -65,4 +71,3 @@ Just for your own satisfaction, show yourself that you now have a new origin git@github.com:your-user-name/networkx.git (push) .. include:: links.inc - diff --git a/doc/source/developer/gitwash/this_project.inc b/doc/source/developer/gitwash/this_project.inc index 9d369a0183d..b05d15f5dc0 100644 --- a/doc/source/developer/gitwash/this_project.inc +++ b/doc/source/developer/gitwash/this_project.inc @@ -1,5 +1,5 @@ .. networkx .. _`networkx`: http://networkx.github.io -.. _`networkx github`: http://github.com/networkx/networkx +.. _`networkx github`: https://github.com/networkx/networkx .. _`networkx mailing list`: http://groups.google.com/group/networkx-discuss/ diff --git a/doc/source/index.rst b/doc/source/index.rst index c6a5a73a5c4..9d48290a0f2 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -8,8 +8,6 @@ NetworkX documentation :Release: |version| :Date: |today| - - .. toctree:: :maxdepth: 2 @@ -21,12 +19,7 @@ NetworkX documentation developer/index reference/history bibliography - examples/index - -.. only:: html - - - `Gallery `_ - + auto_examples/index Indices and tables ================== diff --git a/doc/source/overview.rst b/doc/source/overview.rst index 3b46c6ea607..4ad600d6545 100644 --- a/doc/source/overview.rst +++ b/doc/source/overview.rst @@ -6,7 +6,10 @@ Overview NetworkX is a Python language software package for the creation, manipulation, and study of the structure, dynamics, and function of complex networks. -With NetworkX you can load and store networks in standard and nonstandard data formats, generate many types of random and classic networks, analyze network structure, build network models, design new network algorithms, draw networks, and much more. +With NetworkX you can load and store networks in standard and nonstandard data +formats, generate many types of random and classic networks, analyze network +structure, build network models, design new network algorithms, draw networks, +and much more. Who uses NetworkX? @@ -44,14 +47,21 @@ NetworkX is intended to provide The Python programming language ------------------------------- -Python is a powerful programming language that allows simple and flexible representations of networks, and clear and concise expressions of network algorithms (and other algorithms too). Python has a vibrant and growing ecosystem of packages that NetworkX uses to provide more features such as numerical linear algebra and drawing. In addition -Python is also an excellent "glue" language for putting together pieces of software from other languages which allows reuse of legacy code and engineering of high-performance algorithms [Langtangen04]_. +Python is a powerful programming language that allows simple and flexible +representations of networks, and clear and concise expressions of network +algorithms (and other algorithms too). Python has a vibrant and growing +ecosystem of packages that NetworkX uses to provide more features such as +numerical linear algebra and drawing. In addition Python is also an excellent +"glue" language for putting together pieces of software from other languages +which allows reuse of legacy code and engineering of high-performance +algorithms [Langtangen04]_. Equally important, Python is free, well-supported, and a joy to use. -In order to make the most out of NetworkX you will want to know how to write basic programs in Python. -Among the many guides to Python, we recommend the documentation at -http://www.python.org and the text by Alex Martelli [Martelli03]_. +In order to make the most out of NetworkX you will want to know how to write +basic programs in Python. Among the many guides to Python, we recommend the +documentation at http://www.python.org and the text by Alex Martelli +[Martelli03]_. Free software ------------- @@ -59,27 +69,16 @@ Free software NetworkX is free software; you can redistribute it and/or modify it under the terms of the :doc:`BSD License `. We welcome contributions from the community. Information on -NetworkX development is found at the NetworkX Developer Zone at Github +NetworkX development is found at the NetworkX Developer Zone at GitHub https://github.com/networkx/networkx History ------- -NetworkX was born in May 2002. The original version was designed and written by Aric Hagberg, Dan Schult, and Pieter Swart in 2002 and 2003. -The first public release was in April 2005. +NetworkX was born in May 2002. The original version was designed and written by +Aric Hagberg, Dan Schult, and Pieter Swart in 2002 and 2003. The first public +release was in April 2005. -Many people have contributed to the success of NetworkX. Some of the contributors are listed in the :doc:`credits. ` - - - -What Next -^^^^^^^^^ - - - :doc:`A Brief Tour ` - - - :doc:`Installing ` - - - :doc:`Reference ` - - - :doc:`Examples ` +Many people have contributed to the success of NetworkX. Some of the +contributors are listed in the :doc:`credits. ` diff --git a/doc/source/reference/algorithms.community.rst b/doc/source/reference/algorithms.community.rst index c9988a0001d..d00d99cc9d5 100644 --- a/doc/source/reference/algorithms.community.rst +++ b/doc/source/reference/algorithms.community.rst @@ -59,7 +59,7 @@ Partitions via centrality measures Validating partitions --------------------- -.. automodule:: networkx.algorithms.community.utils +.. automodule:: networkx.algorithms.community.community_utils .. autosummary:: :toctree: generated/ diff --git a/doc/source/reference/citing.rst b/doc/source/reference/citing.rst index 485251bf295..2561a2c0753 100644 --- a/doc/source/reference/citing.rst +++ b/doc/source/reference/citing.rst @@ -14,14 +14,7 @@ in Varoquaux, Travis Vaught, and Jarrod Millman (Eds), (Pasadena, CA USA), pp. 11--15, Aug 2008 - .. only:: html `PDF `_ `BibTeX `_ - - - - - - diff --git a/doc/source/reference/credits.rst b/doc/source/reference/credits.rst index 611ff8ad6f6..0a386b520c5 100644 --- a/doc/source/reference/credits.rst +++ b/doc/source/reference/credits.rst @@ -113,6 +113,7 @@ is partially historical, and now, mostly arbitrary. - Ryan Nelson, GitHub: `rnelsonchem `_ - Niels van Adrichem, GitHub: `NvanAdrichem `_ - Michael E. Rose, GitHub: `Michael-E-Rose `_ +- Jarrod Millman, GitHub: `jarrodmillman `_ Support ------- @@ -123,7 +124,6 @@ If you have provided support to ``networkx`` and a support acknowledgment does not appear below, please help us remedy the situation, and similarly, please let us know if you'd like something modified or corrected. - Research Groups ^^^^^^^^^^^^^^^ @@ -142,7 +142,6 @@ Research Groups Wisconsin Institute for Discovery, University of Wisconsin-Madison, PIs: Jessica C. Flack and David C. Krakauer - Funding ^^^^^^^ diff --git a/doc/source/reference/generators.rst b/doc/source/reference/generators.rst index 6a9f942ce55..64697c8a49b 100644 --- a/doc/source/reference/generators.rst +++ b/doc/source/reference/generators.rst @@ -55,7 +55,7 @@ Lattice ------- .. automodule:: networkx.generators.lattice .. autosummary:: - :toctree:generated/ + :toctree: generated/ grid_2d_graph grid_graph diff --git a/doc/source/reference/glossary.rst b/doc/source/reference/glossary.rst index 540b8c537bd..8bcb38507d9 100644 --- a/doc/source/reference/glossary.rst +++ b/doc/source/reference/glossary.rst @@ -4,11 +4,15 @@ Glossary ======== .. glossary:: - :sorted: + + dictionary + A Python dictionary maps keys to values. Also known as "hashes", + or "associative arrays" in other programming languages. + See http://docs.python.org/tutorial/datastructures.html#dictionaries edge - Edges are either two-tuples of nodes (u,v) or three tuples - of nodes with an edge attribute dictionary (u,v,dict). + Edges are either two-tuples of nodes ``(u, v)`` or three tuples of nodes + with an edge attribute dictionary ``(u, v, dict)``. ebunch An iteratable container of edge tuples like a list, iterator, @@ -17,13 +21,13 @@ Glossary edge attribute Edges can have arbitrary Python objects assigned as attributes by using keyword/value pairs when adding an edge - assigning to the G.edge[u][v] attribute dictionary for the - specified edge u-v. + assigning to the ``G.edge[u][v]`` attribute dictionary for the + specified edge *u*-*v*. hashable An object is hashable if it has a hash value which never changes - during its lifetime (it needs a __hash__() method), and can be - compared to other objects (it needs an __eq__() or __cmp__() + during its lifetime (it needs a :meth:`__hash__` method), and can be + compared to other objects (it needs an :meth:`__eq__` or :meth:`__cmp__` method). Hashable objects which compare equal must have the same hash value. @@ -34,7 +38,7 @@ Glossary mutable containers (such as lists or dictionaries) are. Objects which are instances of user-defined classes are hashable by default; they all compare unequal, and their hash value is their - id(). + :func:`id`. Definition from http://docs.python.org/glossary.html @@ -42,19 +46,12 @@ Glossary An nbunch is any iterable container of nodes that is not itself a node in the graph. It can be an iterable or an iterator, e.g. a list, set, graph, file, etc.. - - node attribute - Nodes can have arbitrary Python objects assigned as attributes - by using keyword/value pairs when adding a node or - assigning to the G.node[n] attribute dictionary for the - specified node n. node A node can be any hashable Python object except None. - - dictionary - A Python dictionary maps keys to values. Also known as "hashes", - or "associative arrays". - See http://docs.python.org/tutorial/datastructures.html#dictionaries - + node attribute + Nodes can have arbitrary Python objects assigned as attributes + by using keyword/value pairs when adding a node or + assigning to the ``G.node[n]`` attribute dictionary for the + specified node ``n``. diff --git a/doc/source/reference/index.rst b/doc/source/reference/index.rst index 6c60ea9bdcf..9b3a00b4cf4 100644 --- a/doc/source/reference/index.rst +++ b/doc/source/reference/index.rst @@ -6,7 +6,6 @@ Reference :Release: |release| :Date: |today| - .. toctree:: :maxdepth: 2 @@ -26,8 +25,3 @@ Reference citing credits glossary - -.. toctree:: - :hidden: - - pdf_reference diff --git a/doc/source/reference/introduction.rst b/doc/source/reference/introduction.rst index 8c80eab5c79..1e88fd18b2c 100644 --- a/doc/source/reference/introduction.rst +++ b/doc/source/reference/introduction.rst @@ -253,9 +253,7 @@ edges are then lines between those dots. >>> nx.draw(G) # default spring_layout >>> nx.draw(G,pos=nx.spectral_layout(G), nodecolor='r',edge_color='b') -See the -:doc:`examples` -for more ideas. +See the :doc:`examples ` for more ideas. Data Structure ============== diff --git a/doc/source/reference/migration_guide_from_1.x_to_2.0.rst b/doc/source/reference/migration_guide_from_1.x_to_2.0.rst index 036bdcd4903..3794e9afe97 100644 --- a/doc/source/reference/migration_guide_from_1.x_to_2.0.rst +++ b/doc/source/reference/migration_guide_from_1.x_to_2.0.rst @@ -4,7 +4,7 @@ Migration guide from 1.X to 2.0 This is a guide for people moving from NetworkX 1.X to NetworkX 2.0 -Any issues with these can be discussed on the [mailing list](https://groups.google.com/forum/#!forum/networkx-discuss) +Any issues with these can be discussed on the `mailing list `_. As you know we have made some major changes to the methods in the Multi/Di/Graph classes. Methods that used to return containers now return iterators and methods that returned iterators have been removed. diff --git a/doc/source/reference/pdf_reference.rst b/doc/source/reference/pdf_reference.rst deleted file mode 100644 index b21be91b01e..00000000000 --- a/doc/source/reference/pdf_reference.rst +++ /dev/null @@ -1,28 +0,0 @@ -.. _pdf_reference: - -Reference -********* - - :Release: |release| - :Date: |today| - - -.. toctree:: - :maxdepth: 2 - - ../overview - introduction - classes - algorithms - functions - generators - linalg - convert - readwrite - drawing - exceptions - utils - legal - citing - credits - glossary diff --git a/doc/source/reference/release_2.0.rst b/doc/source/reference/release_2.0.rst index e7f1f0929b8..dadba65ccdd 100644 --- a/doc/source/reference/release_2.0.rst +++ b/doc/source/reference/release_2.0.rst @@ -5,9 +5,9 @@ Version 2.0 release notes and API changes This page includes more detailed release information and API changes from NetworkX 1.10 to NetworkX 2.0. -There is a [migration guide for people moving from 1.X to 2.0](http://networkx.readthedocs.org/en/latest/reference/migration_guide_from_1.x_to_2.0.html) +There is a `migration guide for people moving from 1.X to 2.0 `_. -Please send comments and questions to the networkx-discuss [mailing list](http://groups.google.com/group/networkx-discuss). +Please send comments and questions to the networkx-discuss `mailing list `_. API changes ----------- @@ -137,7 +137,8 @@ API changes expanding and pushing each other. The algorithm is completly described in [`https://arxiv.org/pdf/1703.09307.pdf `_]. - * [``_] + * [`#2510 `_ and + `#2508 `_] single_source_dijkstra, multi_source_dijkstra and functions that use these now have new behavior when `target` is specified. Instead of returning dicts for distances and paths a 2-tuple of (distance, path) is returned. diff --git a/doc/source/templates/index.html b/doc/source/templates/index.html deleted file mode 100644 index 90a9e57b1e7..00000000000 --- a/doc/source/templates/index.html +++ /dev/null @@ -1,80 +0,0 @@ -{% extends "layout.html" %} -{% set title = 'Overview' %} -{% set css_files = css_files + ["_static/force/force.css"] %} -{% block body %} - - -

High productivity software for complex networks

- -
-

NetworkX is a Python language software package for the creation, manipulation, and -study of the structure, dynamics, and functions of complex networks.

-
- -

Quick Example

- - - - - - - -
-
>>> import networkx as nx
-
->>> G=nx.Graph()
->>> G.add_node("spam")
->>> G.add_edge(1,2)
->>> print(G.nodes())
-[1, 2, 'spam']
->>> print(G.edges())
-[(1, 2)]
-
-
-
- - -
- - -

Documentation

- - - - -
- - - - - - - - - -
- -

Features

-
    -
  • Python language data structures for graphs, digraphs, and multigraphs. -
  • Nodes can be "anything" (e.g. text, images, XML records)
  • -
  • Edges can hold arbitrary data (e.g. weights, time-series) -
  • Generators for classic graphs, random graphs, and synthetic networks
  • -
  • Standard graph algorithms
  • -
  • Network structure and analysis measures
  • -
  • Basic graph drawing
  • -
  • Open source BSD license
  • -
  • Well tested: more than 1500 unit tests
  • -
  • Additional benefits from Python: fast prototyping, easy to teach, multi-platform
  • -
- -

- - -{% endblock %} diff --git a/doc/source/templates/layout.html b/doc/source/templates/layout.html deleted file mode 100644 index 405a91495e0..00000000000 --- a/doc/source/templates/layout.html +++ /dev/null @@ -1,25 +0,0 @@ -{% extends "!layout.html" %} - -{% block rootrellink %} -
  • NetworkX Home
  • -
  • Documentation
  • -
  • Download
  • -
  • Developer (Github)
  • - - -{% endblock %} - -{% block relbar1 %} -
    -NetworkX -
    -{{ super() }} -{% if version.split('.')[-1].startswith('dev') %} -

    This documentation is for the development version {{ version }}

    -{% endif %} -{% endblock %} - -{# put the sidebar before the body #} -{% block sidebar1 %} -{{ sidebar() }}{% endblock %} -{% block sidebar2 %}{% endblock %} diff --git a/doc/source/tutorial/index.rst b/doc/source/tutorial/index.rst index 87c0b7c247e..ec6c000c132 100644 --- a/doc/source/tutorial/index.rst +++ b/doc/source/tutorial/index.rst @@ -8,14 +8,3 @@ Tutorial :maxdepth: 2 tutorial - -**What Next** - - -Now that you have an idea of what the NetworkX package provides, -you should investigate the parts of the package most useful for -you. - -:doc:`Reference Section` provides details on NetworkX. - -:doc:`/examples/index` provides some example programs written using NetworkX. diff --git a/doc/source/tutorial/tutorial.rst b/doc/source/tutorial/tutorial.rst index dc16ffe590b..c479cb04dec 100644 --- a/doc/source/tutorial/tutorial.rst +++ b/doc/source/tutorial/tutorial.rst @@ -11,73 +11,69 @@ Creating a graph Create an empty graph with no nodes and no edges. >>> import networkx as nx ->>> G=nx.Graph() +>>> G = nx.Graph() -By definition, a :class:`Graph` is a collection of nodes (vertices) -along with identified pairs of nodes (called edges, links, etc). -In NetworkX, nodes can be any hashable object e.g. a text string, an -image, an XML object, another Graph, a customized node object, etc. -(Note: Python's None object should not be used as a node as it -determines whether optional function arguments have been assigned -in many functions.) +By definition, a :class:`Graph` is a collection of nodes (vertices) along with +identified pairs of nodes (called edges, links, etc). In NetworkX, nodes can +be any hashable object e.g., a text string, an image, an XML object, another +Graph, a customized node object, etc. + +.. note:: Python's `None` object should not be used as a node as it determines + whether optional function arguments have been assigned in many functions. Nodes ----- -The graph G can be grown in several ways. -NetworkX includes many graph generator functions -and facilities to read and write graphs in many formats. -To get started though we'll look at simple manipulations. -You can add one node at a time, +The graph `G` can be grown in several ways. NetworkX includes many graph +generator functions and facilities to read and write graphs in many formats. +To get started though we'll look at simple manipulations. You can add one node +at a time, >>> G.add_node(1) add a list of nodes, ->>> G.add_nodes_from([2,3]) +>>> G.add_nodes_from([2, 3]) -or add any :term:`nbunch` of nodes. -An *nbunch* is any iterable container -of nodes that is not itself a node -in the graph. (e.g. a list, set, graph, file, etc..) +or add any :term:`nbunch` of nodes. An *nbunch* is any iterable container of +nodes that is not itself a node in the graph. (e.g. a `list`, `set`, `graph`, +`file`, etc..) ->>> H=nx.path_graph(10) +>>> H = nx.path_graph(10) >>> G.add_nodes_from(H) -Note that G now contains the nodes of H as nodes of G. -In contrast, you could use the graph H as a node in G. +Note that `G` now contains the nodes of `H` as nodes of `G`. +In contrast, you could use the graph `H` as a node in `G`. >>> G.add_node(H) -The graph G now contains H as a node. This flexibility -is very powerful as it allows graphs of graphs, graphs of -files, graphs of functions and much more. It is worth -thinking about how to structure your application so that -the nodes are useful entities. Of course you can always -use a unique identifier in G and have a separate dictionary -keyed by identifier to the node information if you prefer. -(Note: You should not change the node object if the hash -depends on its contents.) +The graph `G` now contains `H` as a node. This flexibility is very powerful as +it allows graphs of graphs, graphs of files, graphs of functions and much more. +It is worth thinking about how to structure your application so that the nodes +are useful entities. Of course you can always use a unique identifier in `G` +and have a separate dictionary keyed by identifier to the node information if +you prefer. + +.. note:: You should not change the node object if the hash depends + on its contents. Edges ----- -G can also be grown by adding one edge at a time, +`G` can also be grown by adding one edge at a time, ->>> G.add_edge(1,2) ->>> e=(2,3) ->>> G.add_edge(*e) # unpack edge tuple* +>>> G.add_edge(1, 2) +>>> e = (2, 3) +>>> G.add_edge(*e) # unpack edge tuple* by adding a list of edges, ->>> G.add_edges_from([(1,2),(1,3)]) +>>> G.add_edges_from([(1, 2), (1, 3)]) -or by adding any :term:`ebunch` of edges. -An *ebunch* is any iterable container -of edge-tuples. An edge-tuple can be a 2-tuple -of nodes or a 3-tuple with 2 nodes followed by -an edge attribute dictionary, e.g. (2,3,{'weight':3.1415}). -Edge attributes are discussed further below +or by adding any :term:`ebunch` of edges. An *ebunch* is any iterable +container of edge-tuples. An edge-tuple can be a 2-tuple of nodes or a 3-tuple +with 2 nodes followed by an edge attribute dictionary, e.g., +`(2, 3, {'weight': 3.1415})`. Edge attributes are discussed further below >>> G.add_edges_from(H.edges()) @@ -98,13 +94,13 @@ after removing all nodes and edges, we add new nodes/edges and NetworkX quietly ignores any that are already present. ->>> G.add_edges_from([(1,2),(1,3)]) +>>> G.add_edges_from([(1, 2), (1, 3)]) >>> G.add_node(1) ->>> G.add_edge(1,2) ->>> G.add_node("spam") # adds node "spam" ->>> G.add_nodes_from("spam") # adds 4 nodes: 's', 'p', 'a', 'm' +>>> G.add_edge(1, 2) +>>> G.add_node("spam") # adds node "spam" +>>> G.add_nodes_from("spam") # adds 4 nodes: 's', 'p', 'a', 'm' -At this stage the graph G consists of 8 nodes and 2 edges, as can be seen by: +At this stage the graph `G` consists of 8 nodes and 2 edges, as can be seen by: >>> G.number_of_nodes() 8 @@ -129,7 +125,7 @@ Removing nodes or edges has similar syntax to adding: >>> G.remove_nodes_from("spam") >>> list(G.nodes()) [1, 2, 3, 'spam'] ->>> G.remove_edge(1,3) +>>> G.remove_edge(1, 3) When creating a graph structure by instantiating one of the graph classes you can specify data in several formats. @@ -137,19 +133,20 @@ classes you can specify data in several formats. >>> H=nx.DiGraph(G) # create a DiGraph using the connections from G >>> list(H.edges()) [(1, 2), (2, 1)] ->>> edgelist=[(0,1),(1,2),(2,3)] +>>> edgelist=[(0, 1), (1, 2), (2, 3)] >>> H=nx.Graph(edgelist) What to use as nodes and edges ------------------------------ + You might notice that nodes and edges are not specified as NetworkX objects. This leaves you free to use meaningful items as nodes and edges. The most common choices are numbers or strings, but a node can -be any hashable object (except None), and an edge can be associated -with any object x using G.add_edge(n1,n2,object=x). +be any hashable object (except `None`), and an edge can be associated +with any object `x` using `G.add_edge(n1, n2, object=x)`. -As an example, n1 and n2 could be protein objects from the RCSB Protein -Data Bank, and x could refer to an XML record of publications detailing +As an example, `n1` and `n2` could be protein objects from the RCSB Protein +Data Bank, and `x` could refer to an XML record of publications detailing experimental observations of their interaction. We have found this power quite useful, but its abuse @@ -157,7 +154,6 @@ can lead to unexpected surprises unless one is familiar with Python. If in doubt, consider using :func:`convert_node_labels_to_integers` to obtain a more traditional graph with integer labels. - Accessing edges --------------- @@ -169,7 +165,7 @@ fast direct access to the graph data structure is also possible using subscript notation. .. Warning:: - Do not change the returned dict--it is part of + Do not change the returned `dict`---it is part of the graph data structure and direct manipulation may leave the graph in an inconsistent state. @@ -181,18 +177,18 @@ using subscript notation. You can safely set the attributes of an edge using subscript notation if the edge already exists. ->>> G.add_edge(1,3) ->>> G[1][3]['color']='blue' +>>> G.add_edge(1, 3) +>>> G[1][3]['color'] = "blue" Fast examination of all edges is achieved using adjacency iterators. Note that for undirected graphs this actually looks at each edge twice. ->>> FG=nx.Graph() ->>> FG.add_weighted_edges_from([(1,2,0.125),(1,3,0.75),(2,4,1.2),(3,4,0.375)]) ->>> for n,nbrs in FG.adjacency(): -... for nbr,eattr in nbrs.items(): -... data=eattr['weight'] -... if data<0.5: print('(%d, %d, %.3f)' % (n,nbr,data)) +>>> FG = nx.Graph() +>>> FG.add_weighted_edges_from([(1, 2, 0.125), (1, 3, 0.75), (2, 4, 1.2), (3, 4, 0.375)]) +>>> for n, nbrs in FG.adjacency(): +... for nbr, eattr in nbrs.items(): +... data = eattr['weight'] +... if data < 0.5: print('(%d, %d, %.3f)' % (n, nbr, data)) (1, 2, 0.125) (2, 1, 0.125) (3, 4, 0.375) @@ -200,25 +196,26 @@ Note that for undirected graphs this actually looks at each edge twice. Convenient access to all edges is achieved with the edges method. ->>> for (u,v,d) in FG.edges(data='weight'): -... if d<0.5: print('(%d, %d, %.3f)'%(u,v,d)) +>>> for (u, v, d) in FG.edges(data='weight'): +... if d < 0.5: print('(%d, %d, %.3f)' % (u, v, d)) (1, 2, 0.125) (3, 4, 0.375) Adding attributes to graphs, nodes, and edges --------------------------------------------- -Attributes such as weights, labels, colors, or whatever -Python object you like, can be attached to graphs, nodes, or edges. -Each graph, node, and edge can hold key/value attribute pairs -in an associated attribute dictionary (the keys must be hashable). -By default these are empty, but attributes can be added or changed using -add_edge, add_node or direct manipulation of the attribute -dictionaries named G.graph, G.node and G.edge for a graph G. +Attributes such as weights, labels, colors, or whatever Python object you like, +can be attached to graphs, nodes, or edges. +Each graph, node, and edge can hold key/value attribute pairs in an associated +attribute dictionary (the keys must be hashable). By default these are empty, +but attributes can be added or changed using `add_edge`, `add_node` or direct +manipulation of the attribute dictionaries named `G.graph`, `G.node`, and +`G.edge` for a graph `G`. Graph attributes ~~~~~~~~~~~~~~~~ + Assign graph attributes when creating a new graph >>> G = nx.Graph(day="Friday") @@ -227,16 +224,14 @@ Assign graph attributes when creating a new graph Or you can modify attributes later ->>> G.graph['day']='Monday' +>>> G.graph['day'] = "Monday" >>> G.graph {'day': 'Monday'} - - Node attributes ~~~~~~~~~~~~~~~ -Add node attributes using add_node(), add_nodes_from() or G.node +Add node attributes using `add_node()`, `add_nodes_from()`, or `G.node` >>> G.add_node(1, time='5pm') >>> G.add_nodes_from([3], time='2pm') @@ -246,46 +241,47 @@ Add node attributes using add_node(), add_nodes_from() or G.node >>> list(G.nodes(data=True)) [(1, {'room': 714, 'time': '5pm'}), (3, {'time': '2pm'})] -Note that adding a node to G.node does not add it to the graph, -use G.add_node() to add new nodes. +Note that adding a node to `G.node` does not add it to the graph, use +`G.add_node()` to add new nodes. Edge Attributes ~~~~~~~~~~~~~~~ -Add edge attributes using add_edge(), add_edges_from(), subscript -notation, or G.edge. + +Add edge attributes using `add_edge()`, `add_edges_from()`, subscript notation, +or `G.edge`. >>> G.add_edge(1, 2, weight=4.7 ) ->>> G.add_edges_from([(3,4),(4,5)], color='red') ->>> G.add_edges_from([(1,2,{'color':'blue'}), (2,3,{'weight':8})]) +>>> G.add_edges_from([(3, 4), (4, 5)], color='red') +>>> G.add_edges_from([(1, 2, {'color': 'blue'}), (2, 3, {'weight': 8})]) >>> G[1][2]['weight'] = 4.7 >>> G.edge[1][2]['weight'] = 4 -The special attribute 'weight' -should be numeric and holds values used by algorithms requiring weighted edges. -Warning: Do not assign anything to `G.edge[u]` or `G.edge[u][v]` as it will -corrupt the graph data structure. Change the edge dict as shown above. +The special attribute `weight` should be numeric and holds values used by +algorithms requiring weighted edges. +.. warning:: Do not assign anything to `G.edge[u]` or `G.edge[u][v]` as it will + corrupt the graph data structure. Change the edge `dict` as shown above. Directed graphs --------------- The :class:`DiGraph` class provides additional methods specific to directed -edges, e.g. +edges, e.g., :meth:`DiGraph.out_edges`, :meth:`DiGraph.in_degree`, :meth:`DiGraph.predecessors`, :meth:`DiGraph.successors` etc. -To allow algorithms to work with both classes easily, the directed -versions of neighbors() and degree() are equivalent to successors() -and the sum of in_degree() and out_degree() respectively even though -that may feel inconsistent at times. - ->>> DG=nx.DiGraph() ->>> DG.add_weighted_edges_from([(1,2,0.5), (3,1,0.75)]) ->>> DG.out_degree(1,weight='weight') +To allow algorithms to work with both classes easily, the directed versions of +`neighbors()` and `degree()` are equivalent to `successors()` and the sum of +`in_degree()` and `out_degree()` respectively even though that may feel +inconsistent at times. + +>>> DG = nx.DiGraph() +>>> DG.add_weighted_edges_from([(1, 2, 0.5), (3, 1, 0.75)]) +>>> DG.out_degree(1, weight='weight') 0.5 ->>> DG.degree(1,weight='weight') +>>> DG.degree(1, weight='weight') 1.25 >>> DG.successors(1) [2] @@ -298,8 +294,7 @@ and undirected graphs together is dangerous. If you want to treat a directed graph as undirected for some measurement you should probably convert it using :meth:`Graph.to_undirected` or with ->>> H = nx.Graph(G) # convert G to undirected graph - +>>> H = nx.Graph(G) # convert G to undirected graph Multigraphs ----------- @@ -311,24 +306,23 @@ classes allow you to add the same edge twice, possibly with different edge data. This can be powerful for some applications, but many algorithms are not well defined on such graphs. Where results are well defined, -e.g. :meth:`MultiGraph.degree` we provide the function. Otherwise you +e.g., :meth:`MultiGraph.degree` we provide the function. Otherwise you should convert to a standard graph in a way that makes the measurement well defined. ->>> MG=nx.MultiGraph() ->>> MG.add_weighted_edges_from([(1,2,.5), (1,2,.75), (2,3,.5)]) +>>> MG = nx.MultiGraph() +>>> MG.add_weighted_edges_from([(1, 2, 0.5), (1, 2, 0.75), (2, 3, 0.5)]) >>> dict(MG.degree(weight='weight')) {1: 1.25, 2: 1.75, 3: 0.5} ->>> GG=nx.Graph() ->>> for n,nbrs in MG.adjacency_iter(): -... for nbr,edict in nbrs.items(): -... minvalue=min([d['weight'] for d in edict.values()]) -... GG.add_edge(n,nbr, weight = minvalue) +>>> GG = nx.Graph() +>>> for n, nbrs in MG.adjacency_iter(): +... for nbr, edict in nbrs.items(): +... minvalue = min([d['weight'] for d in edict.values()]) +... GG.add_edge(n, nbr, weight = minvalue) ... ->>> nx.shortest_path(GG,1,3) +>>> nx.shortest_path(GG, 1, 3) [1, 2, 3] - Graph generators and graph operations ------------------------------------- @@ -348,95 +342,84 @@ can also be generated by convert_to_directed(G) - return a directed representation of G -2. Using a call to one of the classic small graphs, e.g. +2. Using a call to one of the classic small graphs, e.g., ->>> petersen=nx.petersen_graph() ->>> tutte=nx.tutte_graph() ->>> maze=nx.sedgewick_maze_graph() ->>> tet=nx.tetrahedral_graph() +>>> peterseni = nx.petersen_graph() +>>> tutte = nx.tutte_graph() +>>> maze = nx.sedgewick_maze_graph() +>>> tet = nx.tetrahedral_graph() -3. Using a (constructive) generator for a classic graph, e.g. +3. Using a (constructive) generator for a classic graph, e.g., ->>> K_5=nx.complete_graph(5) ->>> K_3_5=nx.complete_bipartite_graph(3,5) ->>> barbell=nx.barbell_graph(10,10) ->>> lollipop=nx.lollipop_graph(10,20) +>>> K_5 = nx.complete_graph(5) +>>> K_3_5 = nx.complete_bipartite_graph(3, 5) +>>> barbell = nx.barbell_graph(10, 10) +>>> lollipop = nx.lollipop_graph(10, 20) -4. Using a stochastic graph generator, e.g. +4. Using a stochastic graph generator, e.g., ->>> er=nx.erdos_renyi_graph(100,0.15) ->>> ws=nx.watts_strogatz_graph(30,3,0.1) ->>> ba=nx.barabasi_albert_graph(100,5) ->>> red=nx.random_lobster(100,0.9,0.9) +>>> er = nx.erdos_renyi_graph(100, 0.15) +>>> ws = nx.watts_strogatz_graph(30, 3, 0.1) +>>> ba = nx.barabasi_albert_graph(100, 5) +>>> red = nx.random_lobster(100, 0.9, 0.9) 5. Reading a graph stored in a file using common graph formats, such as edge lists, adjacency lists, GML, GraphML, pickle, LEDA and others. ->>> nx.write_gml(red,"path.to.file") ->>> mygraph=nx.read_gml("path.to.file") +>>> nx.write_gml(red, "path.to.file") +>>> mygraph = nx.read_gml("path.to.file") Details on graph formats: :doc:`/reference/readwrite` Details on graph generator functions: :doc:`/reference/generators` - Analyzing graphs ---------------- -The structure of G can be analyzed using various graph-theoretic +The structure of `G` can be analyzed using various graph-theoretic functions such as: ->>> G=nx.Graph() ->>> G.add_edges_from([(1,2),(1,3)]) +>>> G = nx.Graph() +>>> G.add_edges_from([(1, 2), (1, 3)]) >>> G.add_node("spam") # adds node "spam" - >>> list(nx.connected_components(G)) [{1, 2, 3}, {'spam'}] - >>> sorted(d for n, d in G.degree()) [0, 1, 1, 2] - >>> nx.clustering(G) {1: 0.0, 2: 0.0, 3: 0.0, 'spam': 0.0} Functions that return node properties return iterators over node, value -2-tuples. These are easily stored in a dict structure if you desire. +2-tuples. These are easily stored in a `dict` structure if you desire. >>> dict(nx.degree(G)) {1: 2, 2: 1, 3: 1, 'spam': 0} -For values of specific nodes, you can provide a single node or an nbunch -of nodes as argument. If a single node is specified, then a single value -is returned. If an nbunch is specified, then the function will -return a dictionary. +For values of specific nodes, you can provide a single node or an nbunch of +nodes as argument. If a single node is specified, then a single value is +returned. If an nbunch is specified, then the function will return a +dictionary. ->>> nx.degree(G,1) +>>> nx.degree(G, 1) 2 >>> G.degree(1) 2 ->>> dict(G.degree([1,2])) +>>> dict(G.degree([1, 2])) {1: 2, 2: 1} ->>> sorted(d for n, d in G.degree([1,2])) +>>> sorted(d for n, d in G.degree([1, 2])) [1, 2] >>> sorted(d for n, d in G.degree()) [0, 1, 1, 2] - Details on graph algorithms supported: :doc:`/reference/algorithms` - Drawing graphs -------------- -NetworkX is not primarily a graph drawing package but -basic drawing with Matplotlib as well as an interface to use the -open source Graphviz software package are included. -These are part of the networkx.drawing package -and will be imported if possible. -See :doc:`/reference/drawing` for details. - -Note that the drawing package in NetworkX is not yet compatible with -Python versions 3.0 and above. +NetworkX is not primarily a graph drawing package but basic drawing with +Matplotlib as well as an interface to use the open source Graphviz software +package are included. These are part of the `networkx.drawing` module and will +be imported if possible. See :doc:`/reference/drawing` for details. First import Matplotlib's plot interface (pylab works too) @@ -446,16 +429,15 @@ You may find it useful to interactively test code using "ipython -pylab", which combines the power of ipython and matplotlib and provides a convenient interactive mode. -To test if the import of networkx.drawing was successful -draw G using one of +To test if the import of networkx.drawing was successful draw `G` using one of >>> nx.draw(G) >>> nx.draw_random(G) >>> nx.draw_circular(G) >>> nx.draw_spectral(G) -when drawing to an interactive display. -Note that you may need to issue a Matplotlib +when drawing to an interactive display. Note that you may need to issue a +Matplotlib >>> plt.show() @@ -468,15 +450,13 @@ To save drawings to a file, use, for example >>> nx.draw(G) >>> plt.savefig("path.png") -writes to the file "path.png" in the local directory. If Graphviz -and PyGraphviz or pydot, are available on your system, you can also use -``nx_agraph.graphviz_layout(G)`` or ``nx_pydot.graphviz_layout(G)`` to -get the node positions, or write the graph in dot format for further -processing. +writes to the file "path.png" in the local directory. If Graphviz and +PyGraphviz or pydot, are available on your system, you can also use +``nx_agraph.graphviz_layout(G)`` or ``nx_pydot.graphviz_layout(G)`` to get the +node positions, or write the graph in dot format for further processing. >>> pos = nx.nx_agraph.graphviz_layout(G) >>> nx.draw(G, pos=pos) >>> nx.write_dot(G,'file.dot') Details on drawing graphs: :doc:`/reference/drawing` - diff --git a/examples/3d_drawing/README.txt b/examples/3d_drawing/README.txt new file mode 100644 index 00000000000..1a7668282d7 --- /dev/null +++ b/examples/3d_drawing/README.txt @@ -0,0 +1,2 @@ +3D Drawing +---------- diff --git a/examples/3d_drawing/mayavi2_spring.py b/examples/3d_drawing/mayavi2_spring.py index 79141c061c0..ea61b076872 100644 --- a/examples/3d_drawing/mayavi2_spring.py +++ b/examples/3d_drawing/mayavi2_spring.py @@ -1,34 +1,43 @@ -# needs mayavi2 +""" +======= +Mayavi2 +======= + +This is +""" + +# needs mayavi2 # run with ipython -wthread import networkx as nx import numpy as np -from enthought.mayavi import mlab +from mayavi import mlab +mlab.options.offscreen = True # some graphs to try -#H=nx.krackhardt_kite_graph() -#H=nx.Graph();H.add_edge('a','b');H.add_edge('a','c');H.add_edge('a','d') -#H=nx.grid_2d_graph(4,5) -H=nx.cycle_graph(20) +# H=nx.krackhardt_kite_graph() +# H=nx.Graph();H.add_edge('a','b');H.add_edge('a','c');H.add_edge('a','d') +# H=nx.grid_2d_graph(4,5) +H = nx.cycle_graph(20) # reorder nodes from 0,len(G)-1 -G=nx.convert_node_labels_to_integers(H) +G = nx.convert_node_labels_to_integers(H) # 3d spring layout -pos=nx.spring_layout(G,dim=3) +pos = nx.spring_layout(G, dim=3) # numpy array of x,y,z positions in sorted node order -xyz=np.array([pos[v] for v in sorted(G)]) +xyz = np.array([pos[v] for v in sorted(G)]) # scalar colors -scalars=np.array(list(G.nodes()))+5 +scalars = np.array(list(G.nodes())) + 5 mlab.figure(1, bgcolor=(0, 0, 0)) mlab.clf() -pts = mlab.points3d(xyz[:,0], xyz[:,1], xyz[:,2], +pts = mlab.points3d(xyz[:, 0], xyz[:, 1], xyz[:, 2], scalars, scale_factor=0.1, scale_mode='none', colormap='Blues', resolution=20) - + pts.mlab_source.dataset.lines = np.array(list(G.edges())) tube = mlab.pipeline.tube(pts, tube_radius=0.01) mlab.pipeline.surface(tube, color=(0.8, 0.8, 0.8)) diff --git a/examples/README.txt b/examples/README.txt new file mode 100644 index 00000000000..77185e48f2e --- /dev/null +++ b/examples/README.txt @@ -0,0 +1,9 @@ +.. _examples_gallery: + +Examples +======== + +General-purpose and introductory examples for NetworkX. + +The `tutorial <../tutorial/index.html>`_ introduces conventions and basic graph +manipulations. diff --git a/examples/advanced/README.txt b/examples/advanced/README.txt new file mode 100644 index 00000000000..4519ce7c669 --- /dev/null +++ b/examples/advanced/README.txt @@ -0,0 +1,2 @@ +Advanced +-------- diff --git a/examples/advanced/heavy_metal_umlaut.py b/examples/advanced/heavy_metal_umlaut.py index 81dd0d490b7..cb7467aea93 100644 --- a/examples/advanced/heavy_metal_umlaut.py +++ b/examples/advanced/heavy_metal_umlaut.py @@ -1,6 +1,10 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- """ +================== +Heavy Metal Umlaut +================== + Example using unicode strings as graph labels. Also shows creative use of the Heavy Metal Umlaut: @@ -23,40 +27,40 @@ pass try: - hd='H' + unichr(252) + 'sker D' + unichr(252) - mh='Mot' + unichr(246) + 'rhead' - mc='M' + unichr(246) + 'tley Cr' + unichr(252) + 'e' - st='Sp' + unichr(305) + 'n' + unichr(776) + 'al Tap' - q='Queensr' + unichr(255) + 'che' - boc='Blue ' + unichr(214) +'yster Cult' - dt='Deatht' + unichr(246) + 'ngue' + hd = 'H' + unichr(252) + 'sker D' + unichr(252) + mh = 'Mot' + unichr(246) + 'rhead' + mc = 'M' + unichr(246) + 'tley Cr' + unichr(252) + 'e' + st = 'Sp' + unichr(305) + 'n' + unichr(776) + 'al Tap' + q = 'Queensr' + unichr(255) + 'che' + boc = 'Blue ' + unichr(214) + 'yster Cult' + dt = 'Deatht' + unichr(246) + 'ngue' except NameError: - hd='H' + chr(252) + 'sker D' + chr(252) - mh='Mot' + chr(246) + 'rhead' - mc='M' + chr(246) + 'tley Cr' + chr(252) + 'e' - st='Sp' + chr(305) + 'n' + chr(776) + 'al Tap' - q='Queensr' + chr(255) + 'che' - boc='Blue ' + chr(214) +'yster Cult' - dt='Deatht' + chr(246) + 'ngue' + hd = 'H' + chr(252) + 'sker D' + chr(252) + mh = 'Mot' + chr(246) + 'rhead' + mc = 'M' + chr(246) + 'tley Cr' + chr(252) + 'e' + st = 'Sp' + chr(305) + 'n' + chr(776) + 'al Tap' + q = 'Queensr' + chr(255) + 'che' + boc = 'Blue ' + chr(214) + 'yster Cult' + dt = 'Deatht' + chr(246) + 'ngue' -G=NX.Graph() -G.add_edge(hd,mh) -G.add_edge(mc,st) -G.add_edge(boc,mc) -G.add_edge(boc,dt) -G.add_edge(st,dt) -G.add_edge(q,st) -G.add_edge(dt,mh) -G.add_edge(st,mh) +G = NX.Graph() +G.add_edge(hd, mh) +G.add_edge(mc, st) +G.add_edge(boc, mc) +G.add_edge(boc, dt) +G.add_edge(st, dt) +G.add_edge(q, st) +G.add_edge(dt, mh) +G.add_edge(st, mh) # write in UTF-8 encoding -fh=open('edgelist.utf-8','wb') -fh.write('# -*- coding: utf-8 -*-\n'.encode('utf-8')) # encoding hint for emacs -NX.write_multiline_adjlist(G,fh,delimiter='\t', encoding = 'utf-8') +fh = open('edgelist.utf-8', 'wb') +fh.write('# -*- coding: utf-8 -*-\n'.encode('utf-8')) # encoding hint for emacs +NX.write_multiline_adjlist(G, fh, delimiter='\t', encoding='utf-8') # read and store in UTF-8 -fh=open('edgelist.utf-8','rb') -H=NX.read_multiline_adjlist(fh,delimiter='\t', encoding = 'utf-8') +fh = open('edgelist.utf-8', 'rb') +H = NX.read_multiline_adjlist(fh, delimiter='\t', encoding='utf-8') for n in G.nodes(): if n not in H: @@ -65,13 +69,11 @@ print(list(G.nodes())) try: - pos=NX.spring_layout(G) - NX.draw(G,pos,font_size=16,with_labels=False) - for p in pos: # raise text positions - pos[p][1]+=0.07 - NX.draw_networkx_labels(G,pos) + pos = NX.spring_layout(G) + NX.draw(G, pos, font_size=16, with_labels=False) + for p in pos: # raise text positions + pos[p][1] += 0.07 + NX.draw_networkx_labels(G, pos) P.show() except: pass - - diff --git a/examples/advanced/iterated_dynamical_systems.py b/examples/advanced/iterated_dynamical_systems.py index 900601a6d3f..e339d6887f5 100644 --- a/examples/advanced/iterated_dynamical_systems.py +++ b/examples/advanced/iterated_dynamical_systems.py @@ -1,6 +1,9 @@ """ +========================== +Iterated Dynamical Systems +========================== + Digraphs from Integer-valued Iterated Functions -=============================================== Sums of cubes on 3N @@ -85,8 +88,9 @@ from math import * -nmax=10000 -p=3 +nmax = 10000 +p = 3 + def digitsrep(n, b=10): """Return list of digits comprising n represented in base b. @@ -96,101 +100,110 @@ def digitsrep(n, b=10): return [0] dlist = [] - while (n > 0) : + while (n > 0): # Prepend next least-significant digit dlist = [n % b] + dlist # Floor-division n = n // b return dlist -def powersum(n,p,b=10): + +def powersum(n, p, b=10): """Return sum of digits of n (in base b) raised to the power p.""" - dlist=digitsrep(n,b) - sum=0 + dlist = digitsrep(n, b) + sum = 0 for k in dlist: - sum+=k**p + sum += k**p return sum -def attractor153_graph(n,p,multiple=3,b=10): + +def attractor153_graph(n, p, multiple=3, b=10): """Return digraph of iterations of powersum(n,3,10).""" - G=DiGraph() - for k in range(1,n+1): - if k%multiple==0 and k not in G: - k1=k - knext=powersum(k1,p,b) - while k1!=knext: - G.add_edge(k1,knext) - k1=knext - knext=powersum(k1,p,b) + G = DiGraph() + for k in range(1, n + 1): + if k % multiple == 0 and k not in G: + k1 = k + knext = powersum(k1, p, b) + while k1 != knext: + G.add_edge(k1, knext) + k1 = knext + knext = powersum(k1, p, b) return G -def squaring_cycle_graph_old(n,b=10): + +def squaring_cycle_graph_old(n, b=10): """Return digraph of iterations of powersum(n,2,10).""" - G=DiGraph() - for k in range(1,n+1): - k1=k - G.add_node(k1) # case k1==knext, at least add node - knext=powersum(k1,2,b) - G.add_edge(k1,knext) - while k1!=knext: # stop if fixed point - k1=knext - knext=powersum(k1,2,b) - G.add_edge(k1,knext) - if G.out_degree(knext) >=1: - # knext has already been iterated in and out - break + G = DiGraph() + for k in range(1, n + 1): + k1 = k + G.add_node(k1) # case k1==knext, at least add node + knext = powersum(k1, 2, b) + G.add_edge(k1, knext) + while k1 != knext: # stop if fixed point + k1 = knext + knext = powersum(k1, 2, b) + G.add_edge(k1, knext) + if G.out_degree(knext) >= 1: + # knext has already been iterated in and out + break return G -def sum_of_digits_graph(nmax,b=10): - def f(n): return powersum(n,1,b) - return discrete_dynamics_digraph(nmax,f) -def squaring_cycle_digraph(nmax,b=10): - def f(n): return powersum(n,2,b) - return discrete_dynamics_digraph(nmax,f) +def sum_of_digits_graph(nmax, b=10): + def f(n): return powersum(n, 1, b) + return discrete_dynamics_digraph(nmax, f) + + +def squaring_cycle_digraph(nmax, b=10): + def f(n): return powersum(n, 2, b) + return discrete_dynamics_digraph(nmax, f) + def cubing_153_digraph(nmax): - def f(n): return powersum(n,3,10) - return discrete_dynamics_digraph(nmax,f) + def f(n): return powersum(n, 3, 10) + return discrete_dynamics_digraph(nmax, f) + -def discrete_dynamics_digraph(nmax,f,itermax=50000): - G=DiGraph() - for k in range(1,nmax+1): - kold=k +def discrete_dynamics_digraph(nmax, f, itermax=50000): + G = DiGraph() + for k in range(1, nmax + 1): + kold = k G.add_node(kold) - knew=f(kold) - G.add_edge(kold,knew) - while kold!=knew and kold<=1: - # knew has already been iterated in and out - break + knew = f(kold) + G.add_edge(kold, knew) + while kold != knew and kold << itermax: + # iterate until fixed point reached or itermax is exceeded + kold = knew + knew = f(kold) + G.add_edge(kold, knew) + if G.out_degree(knew) >= 1: + # knew has already been iterated in and out + break return G + def collatz_problem_digraph(nmax): def f(n): - if n%2==0: + if n % 2 == 0: return n // 2 else: - return 3*n+1 - return discrete_dynamics_digraph(nmax,f) + return 3 * n + 1 + return discrete_dynamics_digraph(nmax, f) + def fixed_points(G): """Return a list of fixed points for the discrete dynamical system represented by the digraph G. """ - return [n for n in G if G.out_degree(n)==0] + return [n for n in G if G.out_degree(n) == 0] + - if __name__ == "__main__": - nmax=10000 - print("Building cubing_153_digraph(%d)"% nmax) - G=cubing_153_digraph(nmax) + nmax = 10000 + print("Building cubing_153_digraph(%d)" % nmax) + G = cubing_153_digraph(nmax) print("Resulting digraph has", len(G), "nodes and", - G.size()," edges") + G.size(), " edges") print("Shortest path from 177 to 153 is:") - print(shortest_path(G,177,153)) + print(shortest_path(G, 177, 153)) print("fixed points are %s" % fixed_points(G)) diff --git a/examples/advanced/parallel_betweenness.py b/examples/advanced/parallel_betweenness.py index 45cafd582e1..eab1d89de2e 100644 --- a/examples/advanced/parallel_betweenness.py +++ b/examples/advanced/parallel_betweenness.py @@ -1,4 +1,8 @@ """ +==================== +Parallel Betweenness +==================== + Example of parallel implementation of betweenness centrality using the multiprocessing module from Python Standard Library. @@ -36,13 +40,13 @@ def _betmap(G_normalized_weight_sources_tuple): def betweenness_centrality_parallel(G, processes=None): """Parallel betweenness centrality function""" p = Pool(processes=processes) - node_divisor = len(p._pool)*4 - node_chunks = list(chunks(G.nodes(), int(G.order()/node_divisor))) + node_divisor = len(p._pool) * 4 + node_chunks = list(chunks(G.nodes(), int(G.order() / node_divisor))) num_chunks = len(node_chunks) bt_sc = p.map(_betmap, - zip([G]*num_chunks, - [True]*num_chunks, - [None]*num_chunks, + zip([G] * num_chunks, + [True] * num_chunks, + [None] * num_chunks, node_chunks)) # Reduce the partial solutions @@ -52,6 +56,7 @@ def betweenness_centrality_parallel(G, processes=None): bt_c[n] += bt[n] return bt_c + if __name__ == "__main__": G_ba = nx.barabasi_albert_graph(1000, 3) G_er = nx.gnp_random_graph(1000, 0.01) @@ -63,11 +68,11 @@ def betweenness_centrality_parallel(G, processes=None): print("\tParallel version") start = time.time() bt = betweenness_centrality_parallel(G) - print("\t\tTime: %.4F" % (time.time()-start)) + print("\t\tTime: %.4F" % (time.time() - start)) print("\t\tBetweenness centrality for node 0: %.5f" % (bt[0])) print("\tNon-Parallel version") start = time.time() bt = nx.betweenness_centrality(G) - print("\t\tTime: %.4F seconds" % (time.time()-start)) + print("\t\tTime: %.4F seconds" % (time.time() - start)) print("\t\tBetweenness centrality for node 0: %.5f" % (bt[0])) print("") diff --git a/examples/advanced/eigenvalues.py b/examples/advanced/plot_eigenvalues.py similarity index 61% rename from examples/advanced/eigenvalues.py rename to examples/advanced/plot_eigenvalues.py index dffa429ac6a..24fc8ab52e2 100644 --- a/examples/advanced/eigenvalues.py +++ b/examples/advanced/plot_eigenvalues.py @@ -1,5 +1,8 @@ -#!/usr/bin/env python """ +=========== +Eigenvalues +=========== + Create an G{n,m} random graph and compute the eigenvalues. Requires numpy and matplotlib. """ @@ -7,14 +10,14 @@ import numpy.linalg import matplotlib.pyplot as plt -n = 1000 # 1000 nodes -m = 5000 # 5000 edges -G = nx.gnm_random_graph(n,m) +n = 1000 # 1000 nodes +m = 5000 # 5000 edges +G = nx.gnm_random_graph(n, m) L = nx.normalized_laplacian_matrix(G) e = numpy.linalg.eigvals(L.A) print("Largest eigenvalue:", max(e)) print("Smallest eigenvalue:", min(e)) -plt.hist(e,bins=100) # histogram with 100 bins -plt.xlim(0,2) # eigenvalues between 0 and 2 +plt.hist(e, bins=100) # histogram with 100 bins +plt.xlim(0, 2) # eigenvalues between 0 and 2 plt.show() diff --git a/examples/algorithms/README.txt b/examples/algorithms/README.txt new file mode 100644 index 00000000000..a78a4d7d032 --- /dev/null +++ b/examples/algorithms/README.txt @@ -0,0 +1,2 @@ +Algorithms +---------- diff --git a/examples/algorithms/beam_search.py b/examples/algorithms/beam_search.py index 64f7de5370a..8cac6c4be59 100644 --- a/examples/algorithms/beam_search.py +++ b/examples/algorithms/beam_search.py @@ -6,11 +6,15 @@ # # NetworkX is distributed under a BSD license; see LICENSE.txt for more # information. -"""Beam search with dynamic beam width. +""" +=========== +Beam Search +=========== + +Beam search with dynamic beam width. The progressive widening beam search repeatedly executes a beam search with increasing beam width until the target node is found. - """ import math diff --git a/examples/algorithms/davis_club.py b/examples/algorithms/davis_club.py index 68fab4bf298..eaf368e0994 100644 --- a/examples/algorithms/davis_club.py +++ b/examples/algorithms/davis_club.py @@ -1,5 +1,9 @@ #!/usr/bin/env python """ +========== +Davis Club +========== + Davis Southern Club Women Shows how to make unipartite projections of the graph and compute the @@ -17,20 +21,19 @@ clubs = G.graph['bottom'] print("Biadjacency matrix") -print(bipartite.biadjacency_matrix(G,women,clubs)) +print(bipartite.biadjacency_matrix(G, women, clubs)) # project bipartite graph onto women nodes W = bipartite.projected_graph(G, women) -print('') +print('') print("#Friends, Member") for w in women: - print('%d %s' % (W.degree(w),w)) + print('%d %s' % (W.degree(w), w)) # project bipartite graph onto women nodes keeping number of co-occurence # the degree computed is weighted and counts the total number of shared contacts W = bipartite.weighted_projected_graph(G, women) -print('') +print('') print("#Friend meetings, Member") for w in women: - print('%d %s' % (W.degree(w,weight='weight'),w)) - + print('%d %s' % (W.degree(w, weight='weight'), w)) diff --git a/examples/algorithms/krackhardt_centrality.py b/examples/algorithms/krackhardt_centrality.py index 71dee8f18af..46925f85ca9 100644 --- a/examples/algorithms/krackhardt_centrality.py +++ b/examples/algorithms/krackhardt_centrality.py @@ -1,5 +1,9 @@ #!/usr/bin/env python """ +===================== +Krackhardt Centrality +===================== + Centrality measures of Krackhardt social network. """ # Author: Aric Hagberg (hagberg@lanl.gov) @@ -15,19 +19,19 @@ from networkx import * -G=krackhardt_kite_graph() +G = krackhardt_kite_graph() print("Betweenness") -b=betweenness_centrality(G) +b = betweenness_centrality(G) for v in G.nodes(): - print("%0.2d %5.3f"%(v,b[v])) + print("%0.2d %5.3f" % (v, b[v])) print("Degree centrality") -d=degree_centrality(G) +d = degree_centrality(G) for v in G.nodes(): - print("%0.2d %5.3f"%(v,d[v])) + print("%0.2d %5.3f" % (v, d[v])) print("Closeness centrality") -c=closeness_centrality(G) +c = closeness_centrality(G) for v in G.nodes(): - print("%0.2d %5.3f"%(v,c[v])) + print("%0.2d %5.3f" % (v, c[v])) diff --git a/examples/algorithms/blockmodel.py b/examples/algorithms/plot_blockmodel.py similarity index 57% rename from examples/algorithms/blockmodel.py rename to examples/algorithms/plot_blockmodel.py index bf165e59a1e..c6cdd5f0d0c 100644 --- a/examples/algorithms/blockmodel.py +++ b/examples/algorithms/plot_blockmodel.py @@ -1,6 +1,10 @@ #!/usr/bin/env python # encoding: utf-8 """ +========== +Blockmodel +========== + Example of creating a block model using the blockmodel function in NX. Data used is the Hartford, CT drug users network: @article{, @@ -30,54 +34,54 @@ def create_hc(G): """Creates hierarchical cluster of graph G from distance matrix""" - path_length=nx.all_pairs_shortest_path_length(G) - distances=numpy.zeros((len(G),len(G))) - for u,p in path_length.items(): - for v,d in p.items(): - distances[u][v]=d + path_length = nx.all_pairs_shortest_path_length(G) + distances = numpy.zeros((len(G), len(G))) + for u, p in path_length: + for v, d in p.items(): + distances[u][v] = d # Create hierarchical cluster - Y=distance.squareform(distances) - Z=hierarchy.complete(Y) # Creates HC using farthest point linkage + Y = distance.squareform(distances) + Z = hierarchy.complete(Y) # Creates HC using farthest point linkage # This partition selection is arbitrary, for illustrive purposes - membership=list(hierarchy.fcluster(Z,t=1.15)) + membership = list(hierarchy.fcluster(Z, t=1.15)) # Create collection of lists for blockmodel - partition=defaultdict(list) - for n,p in zip(list(range(len(G))),membership): + partition = defaultdict(list) + for n, p in zip(list(range(len(G))), membership): partition[p].append(n) return list(partition.values()) + if __name__ == '__main__': - G=nx.read_edgelist("hartford_drug.edgelist") + G = nx.read_edgelist("hartford_drug.edgelist") # Extract largest connected component into graph H H = next(nx.connected_component_subgraphs(G)) # Makes life easier to have consecutively labeled integer nodes - H=nx.convert_node_labels_to_integers(H) + H = nx.convert_node_labels_to_integers(H) # Create parititions with hierarchical clustering - partitions=create_hc(H) + partitions = create_hc(H) # Build blockmodel graph - BM=nx.blockmodel(H,partitions) - + BM = nx.blockmodel(H, partitions) # Draw original graph - pos=nx.spring_layout(H,iterations=100) - fig=plt.figure(1,figsize=(6,10)) - ax=fig.add_subplot(211) - nx.draw(H,pos,with_labels=False,node_size=10) - plt.xlim(0,1) - plt.ylim(0,1) + pos = nx.spring_layout(H, iterations=100) + fig = plt.figure(1, figsize=(6, 10)) + ax = fig.add_subplot(211) + nx.draw(H, pos, with_labels=False, node_size=10) + plt.xlim(0, 1) + plt.ylim(0, 1) # Draw block model with weighted edges and nodes sized by number of internal nodes - node_size=[BM.node[x]['nnodes']*10 for x in BM.nodes()] - edge_width=[(2*d['weight']) for (u,v,d) in BM.edges(data=True)] + node_size = [BM.node[x]['nnodes'] * 10 for x in BM.nodes()] + edge_width = [(2 * d['weight']) for (u, v, d) in BM.edges(data=True)] # Set positions to mean of positions of internal nodes from original graph - posBM={} + posBM = {} for n in BM: - xy=numpy.array([pos[u] for u in BM.node[n]['graph']]) - posBM[n]=xy.mean(axis=0) - ax=fig.add_subplot(212) - nx.draw(BM,posBM,node_size=node_size,width=edge_width,with_labels=False) - plt.xlim(0,1) - plt.ylim(0,1) + xy = numpy.array([pos[u] for u in BM.node[n]['graph']]) + posBM[n] = xy.mean(axis=0) + ax = fig.add_subplot(212) + nx.draw(BM, posBM, node_size=node_size, width=edge_width, with_labels=False) + plt.xlim(0, 1) + plt.ylim(0, 1) plt.axis('off') - plt.savefig('hartford_drug_block_model.png') + plt.show() diff --git a/examples/algorithms/rcm.py b/examples/algorithms/rcm.py index 43fa56f6cf9..f67e7fec506 100644 --- a/examples/algorithms/rcm.py +++ b/examples/algorithms/rcm.py @@ -1,7 +1,15 @@ -# Cuthill-McKee ordering of matrices -# The reverse Cuthill-McKee algorithm gives a sparse matrix ordering that -# reduces the matrix bandwidth. -# Requires NumPy +""" +=== +Rcm +=== + +Cuthill-McKee ordering of matrices + +The reverse Cuthill-McKee algorithm gives a sparse matrix ordering that +reduces the matrix bandwidth. +Requires NumPy +""" + # Copyright (C) 2011-2016 by # Author: Aric Hagberg # BSD License @@ -10,23 +18,22 @@ import numpy as np # build low-bandwidth numpy matrix -G=nx.grid_2d_graph(3,3) +G = nx.grid_2d_graph(3, 3) rcm = list(reverse_cuthill_mckee_ordering(G)) -print("ordering",rcm) +print("ordering", rcm) print("unordered Laplacian matrix") A = nx.laplacian_matrix(G) -x,y = np.nonzero(A) +x, y = np.nonzero(A) #print("lower bandwidth:",(y-x).max()) #print("upper bandwidth:",(x-y).max()) -print("bandwidth: %d"%((y-x).max()+(x-y).max()+1)) +print("bandwidth: %d" % ((y - x).max() + (x - y).max() + 1)) print(A) -B = nx.laplacian_matrix(G,nodelist=rcm) +B = nx.laplacian_matrix(G, nodelist=rcm) print("low-bandwidth Laplacian matrix") -x,y = np.nonzero(B) +x, y = np.nonzero(B) #print("lower bandwidth:",(y-x).max()) #print("upper bandwidth:",(x-y).max()) -print("bandwidth: %d"%((y-x).max()+(x-y).max()+1)) +print("bandwidth: %d" % ((y - x).max() + (x - y).max() + 1)) print(B) - diff --git a/examples/basic/README.txt b/examples/basic/README.txt new file mode 100644 index 00000000000..c1cc18b1fad --- /dev/null +++ b/examples/basic/README.txt @@ -0,0 +1,2 @@ +Basic +----- diff --git a/examples/basic/properties.py b/examples/basic/properties.py index 9ac87f86ef9..2bea7daaf5c 100644 --- a/examples/basic/properties.py +++ b/examples/basic/properties.py @@ -1,5 +1,9 @@ #!/usr/bin/env python """ +========== +Properties +========== + Compute some network properties for the lollipop graph. """ # Copyright (C) 2004-2016 by @@ -11,33 +15,33 @@ from networkx import * -G = lollipop_graph(4,6) +G = lollipop_graph(4, 6) -pathlengths=[] +pathlengths = [] print("source vertex {target:length, }") for v in G.nodes(): - spl=single_source_shortest_path_length(G,v) - print('%s %s' % (v,spl)) + spl = single_source_shortest_path_length(G, v) + print('%s %s' % (v, spl)) for p in spl.values(): pathlengths.append(p) print('') -print("average shortest path length %s" % (sum(pathlengths)/len(pathlengths))) +print("average shortest path length %s" % (sum(pathlengths) / len(pathlengths))) # histogram of path lengths -dist={} +dist = {} for p in pathlengths: if p in dist: - dist[p]+=1 + dist[p] += 1 else: - dist[p]=1 + dist[p] = 1 print('') print("length #paths") -verts=dist.keys() +verts = dist.keys() for d in sorted(verts): - print('%s %d' % (d,dist[d])) + print('%s %d' % (d, dist[d])) print("radius: %d" % radius(G)) print("diameter: %d" % diameter(G)) @@ -45,4 +49,3 @@ print("center: %s" % center(G)) print("periphery: %s" % periphery(G)) print("density: %s" % density(G)) - diff --git a/examples/basic/read_write.py b/examples/basic/read_write.py index 37db0cd7a3b..bbd55305199 100644 --- a/examples/basic/read_write.py +++ b/examples/basic/read_write.py @@ -1,5 +1,9 @@ #!/usr/bin/env python """ +====================== +Read and write graphs. +====================== + Read and write graphs. """ # Author: Aric Hagberg (hagberg@lanl.gov) @@ -13,13 +17,12 @@ from networkx import * import sys -G=grid_2d_graph(5,5) # 5x5 grid -try: # Python 2.6+ - write_adjlist(G,sys.stdout) # write adjacency list to screen -except TypeError: # Python 3.x - write_adjlist(G,sys.stdout.buffer) # write adjacency list to screen +G = grid_2d_graph(5, 5) # 5x5 grid +try: # Python 2.6+ + write_adjlist(G, sys.stdout) # write adjacency list to screen +except TypeError: # Python 3.x + write_adjlist(G, sys.stdout.buffer) # write adjacency list to screen # write edgelist to grid.edgelist -write_edgelist(G,path="grid.edgelist",delimiter=":") +write_edgelist(G, path="grid.edgelist", delimiter=":") # read edgelist from grid.edgelist -H=read_edgelist(path="grid.edgelist",delimiter=":") - +H = read_edgelist(path="grid.edgelist", delimiter=":") diff --git a/examples/drawing/README.txt b/examples/drawing/README.txt new file mode 100644 index 00000000000..c25993decee --- /dev/null +++ b/examples/drawing/README.txt @@ -0,0 +1,2 @@ +Drawing +------- diff --git a/examples/drawing/house_with_colors.py b/examples/drawing/house_with_colors.py deleted file mode 100644 index 78aa1521989..00000000000 --- a/examples/drawing/house_with_colors.py +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env python -""" -Draw a graph with matplotlib. -You must have matplotlib for this to work. -""" -# Author: Aric Hagberg (hagberg@lanl.gov) -try: - import matplotlib.pyplot as plt -except: - raise - -import networkx as nx - -G=nx.house_graph() -# explicitly set positions -pos={0:(0,0), - 1:(1,0), - 2:(0,1), - 3:(1,1), - 4:(0.5,2.0)} - -nx.draw_networkx_nodes(G,pos,node_size=2000,nodelist=[4]) -nx.draw_networkx_nodes(G,pos,node_size=3000,nodelist=[0,1,2,3],node_color='b') -nx.draw_networkx_edges(G,pos,alpha=0.5,width=6) -plt.axis('off') -plt.savefig("house_with_colors.png") # save as png -plt.show() # display diff --git a/examples/drawing/labels_and_colors.py b/examples/drawing/labels_and_colors.py deleted file mode 100644 index cf06a95a769..00000000000 --- a/examples/drawing/labels_and_colors.py +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env python -""" -Draw a graph with matplotlib, color by degree. - -You must have matplotlib for this to work. -""" -# Author: Aric Hagberg (hagberg@lanl.gov) -import matplotlib.pyplot as plt - -import networkx as nx - -G=nx.cubical_graph() -pos=nx.spring_layout(G) # positions for all nodes - -# nodes -nx.draw_networkx_nodes(G,pos, - nodelist=[0,1,2,3], - node_color='r', - node_size=500, - alpha=0.8) -nx.draw_networkx_nodes(G,pos, - nodelist=[4,5,6,7], - node_color='b', - node_size=500, - alpha=0.8) - -# edges -nx.draw_networkx_edges(G,pos,width=1.0,alpha=0.5) -nx.draw_networkx_edges(G,pos, - edgelist=[(0,1),(1,2),(2,3),(3,0)], - width=8,alpha=0.5,edge_color='r') -nx.draw_networkx_edges(G,pos, - edgelist=[(4,5),(5,6),(6,7),(7,4)], - width=8,alpha=0.5,edge_color='b') - - -# some math labels -labels={} -labels[0]=r'$a$' -labels[1]=r'$b$' -labels[2]=r'$c$' -labels[3]=r'$d$' -labels[4]=r'$\alpha$' -labels[5]=r'$\beta$' -labels[6]=r'$\gamma$' -labels[7]=r'$\delta$' -nx.draw_networkx_labels(G,pos,labels,font_size=16) - -plt.axis('off') -plt.savefig("labels_and_colors.png") # save as png -plt.show() # display diff --git a/examples/drawing/atlas.py b/examples/drawing/plot_atlas.py similarity index 74% rename from examples/drawing/atlas.py rename to examples/drawing/plot_atlas.py index 53d181a45a7..2107830b503 100644 --- a/examples/drawing/atlas.py +++ b/examples/drawing/plot_atlas.py @@ -1,5 +1,9 @@ #!/usr/bin/env python """ +===== +Atlas +===== + Atlas of all graphs of 6 nodes or less. """ @@ -17,16 +21,17 @@ from networkx.algorithms.isomorphism.isomorph import graph_could_be_isomorphic as isomorphic import random + def atlas6(): """ Return the atlas of all connected graphs of 6 nodes or less. Attempt to check for isomorphisms and remove. """ - Atlas = graph_atlas_g()[0:208] # 208 + Atlas = graph_atlas_g()[0:208] # 208 # remove isolated nodes, only connected graphs are left - U = nx.Graph() # graph for union of all graphs in atlas + U = nx.Graph() # graph for union of all graphs in atlas for G in Atlas: - zerodegree = [n for n in G if G.degree(n)==0] + zerodegree = [n for n in G if G.degree(n) == 0] for n in zerodegree: G.remove_node(n) U = nx.disjoint_union(U, G) @@ -36,14 +41,15 @@ def atlas6(): UU = nx.Graph() # do quick isomorphic-like check, not a true isomorphism checker - nlist = [] # list of nonisomorphic graphs + nlist = [] # list of nonisomorphic graphs for G in C: # check against all nonisomorphic graphs so far if not iso(G, nlist): nlist.append(G) - UU = nx.disjoint_union(UU, G) # union the nonisomorphic graphs + UU = nx.disjoint_union(UU, G) # union the nonisomorphic graphs return UU + def iso(G1, glist): """Quick and dirty nonisomorphism checker used to check isomorphisms.""" for G2 in glist: @@ -53,10 +59,10 @@ def iso(G1, glist): if __name__ == '__main__': - G=atlas6() + G = atlas6() - print("graph has %d nodes with %d edges"\ - %(nx.number_of_nodes(G), nx.number_of_edges(G))) + print("graph has %d nodes with %d edges" + % (nx.number_of_nodes(G), nx.number_of_edges(G))) print(nx.number_connected_components(G), "connected components") try: @@ -77,13 +83,13 @@ def iso(G1, glist): # color nodes the same in each connected subgraph C = nx.connected_component_subgraphs(G) for g in C: - c = [random.random()] * nx.number_of_nodes(g) # random color... + c = [random.random()] * nx.number_of_nodes(g) # random color... nx.draw(g, - pos, - node_size=40, - node_color=c, - vmin=0.0, - vmax=1.0, - with_labels=False - ) - plt.savefig("atlas.png", dpi=75) + pos, + node_size=40, + node_color=c, + vmin=0.0, + vmax=1.0, + with_labels=False + ) + plt.show() diff --git a/examples/drawing/chess_masters.py b/examples/drawing/plot_chess_masters.py similarity index 54% rename from examples/drawing/chess_masters.py rename to examples/drawing/plot_chess_masters.py index 76e8ae6f74f..63c886b6513 100644 --- a/examples/drawing/chess_masters.py +++ b/examples/drawing/plot_chess_masters.py @@ -1,6 +1,10 @@ #!/usr/bin/env python """ +============= +Chess Masters +============= + An example of the MultiDiGraph clas The function chess_pgn_graph reads a collection of chess @@ -33,11 +37,12 @@ # tag names specifying what game info should be # stored in the dict on each digraph edge -game_details=["Event", - "Date", - "Result", - "ECO", - "Site"] +game_details = ["Event", + "Date", + "Result", + "ECO", + "Site"] + def chess_pgn_graph(pgn_file="chess_masters_WCC.pgn.bz2"): """Read chess games in pgn format in pgn_file. @@ -49,55 +54,54 @@ def chess_pgn_graph(pgn_file="chess_masters_WCC.pgn.bz2"): """ import bz2 - G=nx.MultiDiGraph() - game={} + G = nx.MultiDiGraph() + game = {} datafile = bz2.BZ2File(pgn_file) lines = (line.decode().rstrip('\r\n') for line in datafile) for line in lines: if line.startswith('['): - tag,value=line[1:-1].split(' ',1) - game[str(tag)]=value.strip('"') + tag, value = line[1:-1].split(' ', 1) + game[str(tag)] = value.strip('"') else: - # empty line after tag set indicates - # we finished reading game info + # empty line after tag set indicates + # we finished reading game info if game: - white=game.pop('White') - black=game.pop('Black') + white = game.pop('White') + black = game.pop('Black') G.add_edge(white, black, **game) - game={} + game = {} return G if __name__ == '__main__': - G=chess_pgn_graph() + G = chess_pgn_graph() - ngames=G.number_of_edges() - nplayers=G.number_of_nodes() + ngames = G.number_of_edges() + nplayers = G.number_of_nodes() - print("Loaded %d chess games between %d players\n"\ - % (ngames,nplayers)) + print("Loaded %d chess games between %d players\n" + % (ngames, nplayers)) # identify connected components # of the undirected version - Gcc=list(nx.connected_component_subgraphs(G.to_undirected())) - if len(Gcc)>1: + Gcc = list(nx.connected_component_subgraphs(G.to_undirected())) + if len(Gcc) > 1: print("Note the disconnected component consisting of:") print(Gcc[1].nodes()) # find all games with B97 opening (as described in ECO) - openings=set([game_info['ECO'] - for (white,black,game_info) in G.edges(data=True)]) - print("\nFrom a total of %d different openings,"%len(openings)) + openings = set([game_info['ECO'] + for (white, black, game_info) in G.edges(data=True)]) + print("\nFrom a total of %d different openings," % len(openings)) print('the following games used the Sicilian opening') print('with the Najdorff 7...Qb6 "Poisoned Pawn" variation.\n') - for (white,black,game_info) in G.edges(data=True): - if game_info['ECO']=='B97': - print(white,"vs",black) - for k,v in game_info.items(): - print(" ",k,": ",v) - print("\n") - + for (white, black, game_info) in G.edges(data=True): + if game_info['ECO'] == 'B97': + print(white, "vs", black) + for k, v in game_info.items(): + print(" ", k, ": ", v) + print("\n") try: import matplotlib.pyplot as plt @@ -107,47 +111,47 @@ def chess_pgn_graph(pgn_file="chess_masters_WCC.pgn.bz2"): sys.exit(0) # make new undirected graph H without multi-edges - H=nx.Graph(G) + H = nx.Graph(G) # edge width is proportional number of games played - edgewidth=[] - for (u,v,d) in H.edges(data=True): - edgewidth.append(len(G.get_edge_data(u,v))) + edgewidth = [] + for (u, v, d) in H.edges(data=True): + edgewidth.append(len(G.get_edge_data(u, v))) # node size is proportional to number of games won - wins=dict.fromkeys(G.nodes(),0.0) - for (u,v,d) in G.edges(data=True): - r=d['Result'].split('-') - if r[0]=='1': - wins[u]+=1.0 - elif r[0]=='1/2': - wins[u]+=0.5 - wins[v]+=0.5 + wins = dict.fromkeys(G.nodes(), 0.0) + for (u, v, d) in G.edges(data=True): + r = d['Result'].split('-') + if r[0] == '1': + wins[u] += 1.0 + elif r[0] == '1/2': + wins[u] += 0.5 + wins[v] += 0.5 else: - wins[v]+=1.0 + wins[v] += 1.0 try: - pos=nx.nx_agraph.graphviz_layout(H) + pos = nx.nx_agraph.graphviz_layout(H) except: - pos=nx.spring_layout(H,iterations=20) + pos = nx.spring_layout(H, iterations=20) plt.rcParams['text.usetex'] = False - plt.figure(figsize=(8,8)) - nx.draw_networkx_edges(H,pos,alpha=0.3,width=edgewidth, edge_color='m') - nodesize=[wins[v]*50 for v in H] - nx.draw_networkx_nodes(H,pos,node_size=nodesize,node_color='w',alpha=0.4) - nx.draw_networkx_edges(H,pos,alpha=0.4,node_size=0,width=1,edge_color='k') - nx.draw_networkx_labels(H,pos,fontsize=14) - font = {'fontname' : 'Helvetica', - 'color' : 'k', - 'fontweight' : 'bold', - 'fontsize' : 14} + plt.figure(figsize=(8, 8)) + nx.draw_networkx_edges(H, pos, alpha=0.3, width=edgewidth, edge_color='m') + nodesize = [wins[v] * 50 for v in H] + nx.draw_networkx_nodes(H, pos, node_size=nodesize, node_color='w', alpha=0.4) + nx.draw_networkx_edges(H, pos, alpha=0.4, node_size=0, width=1, edge_color='k') + nx.draw_networkx_labels(H, pos, fontsize=14) + font = {'fontname': 'Helvetica', + 'color': 'k', + 'fontweight': 'bold', + 'fontsize': 14} plt.title("World Chess Championship Games: 1886 - 1985", font) # change font and write text (using data coordinates) - font = {'fontname' : 'Helvetica', - 'color' : 'r', - 'fontweight' : 'bold', - 'fontsize' : 14} + font = {'fontname': 'Helvetica', + 'color': 'r', + 'fontweight': 'bold', + 'fontsize': 14} plt.text(0.5, 0.97, "edge width = # games played", horizontalalignment='center', @@ -157,6 +161,4 @@ def chess_pgn_graph(pgn_file="chess_masters_WCC.pgn.bz2"): transform=plt.gca().transAxes) plt.axis('off') - plt.savefig("chess_masters.png",dpi=75) - print("Wrote chess_masters.png") - plt.show() # display + plt.show() diff --git a/examples/drawing/circular_tree.py b/examples/drawing/plot_circular_tree.py similarity index 91% rename from examples/drawing/circular_tree.py rename to examples/drawing/plot_circular_tree.py index 01906de7a6e..5777a147a52 100644 --- a/examples/drawing/circular_tree.py +++ b/examples/drawing/plot_circular_tree.py @@ -1,3 +1,10 @@ +""" +============= +Circular Tree +============= + +This +""" import networkx as nx import matplotlib.pyplot as plt @@ -17,6 +24,4 @@ plt.figure(figsize=(8, 8)) nx.draw(G, pos, node_size=20, alpha=0.5, node_color="blue", with_labels=False) plt.axis('equal') -plt.savefig('circular_tree.png') plt.show() - diff --git a/examples/drawing/degree_histogram.py b/examples/drawing/plot_degree_histogram.py similarity index 62% rename from examples/drawing/degree_histogram.py rename to examples/drawing/plot_degree_histogram.py index 4c05b08cc94..1095533eb87 100644 --- a/examples/drawing/degree_histogram.py +++ b/examples/drawing/plot_degree_histogram.py @@ -1,5 +1,9 @@ #!/usr/bin/env python """ +================ +Degree histogram +================ + Draw degree histogram with matplotlib. Random graph shown as inset """ @@ -9,9 +13,9 @@ G = nx.gnp_random_graph(100, 0.02) -degree_sequence=sorted([d for n,d in G.degree()], reverse=True) # degree sequence -#print "Degree sequence", degree_sequence -degreeCount=collections.Counter(degree_sequence) +degree_sequence = sorted([d for n, d in G.degree()], reverse=True) # degree sequence +# print "Degree sequence", degree_sequence +degreeCount = collections.Counter(degree_sequence) deg, cnt = zip(*degreeCount.items()) fig, ax = plt.subplots() @@ -20,17 +24,15 @@ plt.title("Degree Histogram") plt.ylabel("Count") plt.xlabel("Degree") -ax.set_xticks([d+0.4 for d in deg]) +ax.set_xticks([d + 0.4 for d in deg]) ax.set_xticklabels(deg) # draw graph in inset plt.axes([0.4, 0.4, 0.5, 0.5]) -Gcc=sorted(nx.connected_component_subgraphs(G), key = len, reverse=True)[0] -pos=nx.spring_layout(G) +Gcc = sorted(nx.connected_component_subgraphs(G), key=len, reverse=True)[0] +pos = nx.spring_layout(G) plt.axis('off') nx.draw_networkx_nodes(G, pos, node_size=20) nx.draw_networkx_edges(G, pos, alpha=0.4) -plt.savefig("degree_histogram.png") plt.show() - diff --git a/examples/drawing/degree_rank.py b/examples/drawing/plot_degree_rank.py similarity index 68% rename from examples/drawing/degree_rank.py rename to examples/drawing/plot_degree_rank.py index aaa1aa43c95..950a7d28243 100644 --- a/examples/drawing/degree_rank.py +++ b/examples/drawing/plot_degree_rank.py @@ -1,5 +1,9 @@ #!/usr/bin/env python """ +=========== +Degree Rank +=========== + Random graph from given degree sequence. Draw degree rank plot and graph with matplotlib. """ @@ -9,9 +13,9 @@ G = nx.gnp_random_graph(100, 0.02) -degree_sequence=sorted([d for n, d in G.degree()], reverse=True) -#print "Degree sequence", degree_sequence -dmax=max(degree_sequence) +degree_sequence = sorted([d for n, d in G.degree()], reverse=True) +# print "Degree sequence", degree_sequence +dmax = max(degree_sequence) plt.loglog(degree_sequence, 'b-', marker='o') plt.title("Degree rank plot") @@ -20,11 +24,10 @@ # draw graph in inset plt.axes([0.45, 0.45, 0.45, 0.45]) -Gcc=sorted(nx.connected_component_subgraphs(G), key = len, reverse=True)[0] -pos=nx.spring_layout(Gcc) +Gcc = sorted(nx.connected_component_subgraphs(G), key=len, reverse=True)[0] +pos = nx.spring_layout(Gcc) plt.axis('off') nx.draw_networkx_nodes(Gcc, pos, node_size=20) nx.draw_networkx_edges(Gcc, pos, alpha=0.4) -plt.savefig("degree_rank.png") plt.show() diff --git a/examples/drawing/edge_colormap.py b/examples/drawing/plot_edge_colormap.py similarity index 50% rename from examples/drawing/edge_colormap.py rename to examples/drawing/plot_edge_colormap.py index a2aa7a3a4f6..d4856f852e7 100644 --- a/examples/drawing/edge_colormap.py +++ b/examples/drawing/plot_edge_colormap.py @@ -1,5 +1,9 @@ #!/usr/bin/env python """ +============= +Edge Colormap +============= + Draw a graph with matplotlib, color edges. You must have matplotlib>=87.7 for this to work. """ @@ -11,9 +15,9 @@ import networkx as nx -G=nx.star_graph(20) -pos=nx.spring_layout(G) -colors=range(20) -nx.draw(G,pos,node_color='#A0CBE2',edge_color=colors,width=4,edge_cmap=plt.cm.Blues,with_labels=False) -plt.savefig("edge_colormap.png") # save as png -plt.show() # display +G = nx.star_graph(20) +pos = nx.spring_layout(G) +colors = range(20) +nx.draw(G, pos, node_color='#A0CBE2', edge_color=colors, + width=4, edge_cmap=plt.cm.Blues, with_labels=False) +plt.show() diff --git a/examples/drawing/ego_graph.py b/examples/drawing/plot_ego_graph.py similarity index 50% rename from examples/drawing/ego_graph.py rename to examples/drawing/plot_ego_graph.py index 888150514c6..d80b2566b99 100644 --- a/examples/drawing/ego_graph.py +++ b/examples/drawing/plot_ego_graph.py @@ -1,7 +1,11 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- """ -Example using the NetworkX ego_graph() function to return the main egonet of +========= +Ego Graph +========= + +Example using the NetworkX ego_graph() function to return the main egonet of the largest hub in a Barabási-Albert network. """ # Author: Drew Conway (drew.conway@nyu.edu) @@ -13,18 +17,17 @@ if __name__ == '__main__': # Create a BA model graph - n=1000 - m=2 - G=nx.generators.barabasi_albert_graph(n,m) + n = 1000 + m = 2 + G = nx.generators.barabasi_albert_graph(n, m) # find node with largest degree - node_and_degree=G.degree() - (largest_hub,degree)=sorted(node_and_degree,key=itemgetter(1))[-1] + node_and_degree = G.degree() + (largest_hub, degree) = sorted(node_and_degree, key=itemgetter(1))[-1] # Create ego graph of main hub - hub_ego=nx.ego_graph(G,largest_hub) + hub_ego = nx.ego_graph(G, largest_hub) # Draw graph - pos=nx.spring_layout(hub_ego) - nx.draw(hub_ego,pos,node_color='b',node_size=50,with_labels=False) + pos = nx.spring_layout(hub_ego) + nx.draw(hub_ego, pos, node_color='b', node_size=50, with_labels=False) # Draw ego as large and red - nx.draw_networkx_nodes(hub_ego,pos,nodelist=[largest_hub],node_size=300,node_color='r') - plt.savefig('ego_graph.png') + nx.draw_networkx_nodes(hub_ego, pos, nodelist=[largest_hub], node_size=300, node_color='r') plt.show() diff --git a/examples/drawing/four_grids.py b/examples/drawing/plot_four_grids.py similarity index 57% rename from examples/drawing/four_grids.py rename to examples/drawing/plot_four_grids.py index 112019170cc..15719438d45 100644 --- a/examples/drawing/four_grids.py +++ b/examples/drawing/plot_four_grids.py @@ -1,5 +1,9 @@ #!/usr/bin/env python """ +========== +Four Grids +========== + Draw a graph with matplotlib. You must have matplotlib for this to work. """ @@ -19,22 +23,21 @@ import networkx as nx -G=nx.grid_2d_graph(4,4) #4x4 grid +G = nx.grid_2d_graph(4, 4) # 4x4 grid -pos=nx.spring_layout(G,iterations=100) +pos = nx.spring_layout(G, iterations=100) plt.subplot(221) -nx.draw(G,pos,font_size=8) +nx.draw(G, pos, font_size=8) plt.subplot(222) -nx.draw(G,pos,node_color='k',node_size=0,with_labels=False) +nx.draw(G, pos, node_color='k', node_size=0, with_labels=False) plt.subplot(223) -nx.draw(G,pos,node_color='g',node_size=250,with_labels=False,width=6) +nx.draw(G, pos, node_color='g', node_size=250, with_labels=False, width=6) plt.subplot(224) -H=G.to_directed() -nx.draw(H,pos,node_color='b',node_size=20,with_labels=False) +H = G.to_directed() +nx.draw(H, pos, node_color='b', node_size=20, with_labels=False) -plt.savefig("four_grids.png") plt.show() diff --git a/examples/drawing/giant_component.py b/examples/drawing/plot_giant_component.py similarity index 62% rename from examples/drawing/giant_component.py rename to examples/drawing/plot_giant_component.py index 82d4830c534..0d3daf96611 100644 --- a/examples/drawing/giant_component.py +++ b/examples/drawing/plot_giant_component.py @@ -1,5 +1,9 @@ #!/usr/bin/env python """ +=============== +Giant Component +=============== + This example illustrates the sudden appearance of a giant connected component in a binomial random graph. @@ -37,43 +41,42 @@ layout = nx.spring_layout -n=150 # 150 nodes +n = 150 # 150 nodes # p value at which giant component (of size log(n) nodes) is expected -p_giant=1.0/(n-1) +p_giant = 1.0 / (n - 1) # p value at which graph is expected to become completely connected -p_conn=math.log(n)/float(n) +p_conn = math.log(n) / float(n) # the following range of p values should be close to the threshold -pvals=[0.003, 0.006, 0.008, 0.015] +pvals = [0.003, 0.006, 0.008, 0.015] -region=220 # for pylab 2x2 subplot layout -plt.subplots_adjust(left=0,right=1,bottom=0,top=0.95,wspace=0.01,hspace=0.01) +region = 220 # for pylab 2x2 subplot layout +plt.subplots_adjust(left=0, right=1, bottom=0, top=0.95, wspace=0.01, hspace=0.01) for p in pvals: - G=nx.binomial_graph(n,p) - pos=layout(G) - region+=1 + G = nx.binomial_graph(n, p) + pos = layout(G) + region += 1 plt.subplot(region) - plt.title("p = %6.3f"%(p)) - nx.draw(G,pos, + plt.title("p = %6.3f" % (p)) + nx.draw(G, pos, with_labels=False, node_size=10 ) # identify largest connected component - Gcc=sorted(nx.connected_component_subgraphs(G), key = len, reverse=True) - G0=Gcc[0] - nx.draw_networkx_edges(G0,pos, + Gcc = sorted(nx.connected_component_subgraphs(G), key=len, reverse=True) + G0 = Gcc[0] + nx.draw_networkx_edges(G0, pos, with_labels=False, edge_color='r', width=6.0 - ) + ) # show other connected components for Gi in Gcc[1:]: - if len(Gi)>1: - nx.draw_networkx_edges(Gi,pos, - with_labels=False, - edge_color='r', - alpha=0.3, - width=5.0 - ) -plt.savefig("giant_component.png") -plt.show() # display + if len(Gi) > 1: + nx.draw_networkx_edges(Gi, pos, + with_labels=False, + edge_color='r', + alpha=0.3, + width=5.0 + ) +plt.show() diff --git a/examples/drawing/plot_house_with_colors.py b/examples/drawing/plot_house_with_colors.py new file mode 100644 index 00000000000..54041d4be01 --- /dev/null +++ b/examples/drawing/plot_house_with_colors.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python +""" +================= +House With Colors +================= + +Draw a graph with matplotlib. +You must have matplotlib for this to work. +""" +# Author: Aric Hagberg (hagberg@lanl.gov) +try: + import matplotlib.pyplot as plt +except: + raise + +import networkx as nx + +G = nx.house_graph() +# explicitly set positions +pos = {0: (0, 0), + 1: (1, 0), + 2: (0, 1), + 3: (1, 1), + 4: (0.5, 2.0)} + +nx.draw_networkx_nodes(G, pos, node_size=2000, nodelist=[4]) +nx.draw_networkx_nodes(G, pos, node_size=3000, nodelist=[0, 1, 2, 3], node_color='b') +nx.draw_networkx_edges(G, pos, alpha=0.5, width=6) +plt.axis('off') +plt.show() diff --git a/examples/drawing/knuth_miles.py b/examples/drawing/plot_knuth_miles.py similarity index 56% rename from examples/drawing/knuth_miles.py rename to examples/drawing/plot_knuth_miles.py index 0ba9fd767e8..03f1579638f 100644 --- a/examples/drawing/knuth_miles.py +++ b/examples/drawing/plot_knuth_miles.py @@ -1,5 +1,9 @@ #!/usr/bin/env python """ +=========== +Knuth Miles +=========== + An example using networkx.Graph(). miles_graph() returns an undirected graph over the 128 US cities from @@ -36,77 +40,74 @@ def miles_graph(): """ # open file miles_dat.txt.gz (or miles_dat.txt) import gzip - fh = gzip.open('knuth_miles.txt.gz','r') + fh = gzip.open('knuth_miles.txt.gz', 'r') - G=nx.Graph() - G.position={} - G.population={} + G = nx.Graph() + G.position = {} + G.population = {} - cities=[] + cities = [] for line in fh.readlines(): line = line.decode() - if line.startswith("*"): # skip comments + if line.startswith("*"): # skip comments continue - numfind=re.compile("^\d+") + numfind = re.compile("^\d+") - if numfind.match(line): # this line is distances - dist=line.split() + if numfind.match(line): # this line is distances + dist = line.split() for d in dist: - G.add_edge(city,cities[i],weight=int(d)) - i=i+1 - else: # this line is a city, position, population - i=1 - (city,coordpop)=line.split("[") - cities.insert(0,city) - (coord,pop)=coordpop.split("]") - (y,x)=coord.split(",") + G.add_edge(city, cities[i], weight=int(d)) + i = i + 1 + else: # this line is a city, position, population + i = 1 + (city, coordpop) = line.split("[") + cities.insert(0, city) + (coord, pop) = coordpop.split("]") + (y, x) = coord.split(",") G.add_node(city) # assign position - flip x axis for matplotlib, shift origin - G.position[city]=(-int(x)+7500,int(y)-3000) - G.population[city]=float(pop)/1000.0 + G.position[city] = (-int(x) + 7500, int(y) - 3000) + G.population[city] = float(pop) / 1000.0 return G + if __name__ == '__main__': import networkx as nx import re import sys - G=miles_graph() + G = miles_graph() print("Loaded miles_dat.txt containing 128 cities.") - print("digraph has %d nodes with %d edges"\ - %(nx.number_of_nodes(G),nx.number_of_edges(G))) - + print("digraph has %d nodes with %d edges" + % (nx.number_of_nodes(G), nx.number_of_edges(G))) # make new graph of cites, edge if less then 300 miles between them - H=nx.Graph() + H = nx.Graph() for v in G: H.add_node(v) - for (u,v,d) in G.edges(data=True): + for (u, v, d) in G.edges(data=True): if d['weight'] < 300: - H.add_edge(u,v) + H.add_edge(u, v) # draw with matplotlib/pylab try: import matplotlib.pyplot as plt - plt.figure(figsize=(8,8)) + plt.figure(figsize=(8, 8)) # with nodes colored by degree sized by population - node_color=[float(H.degree(v)) for v in H] - nx.draw(H,G.position, - node_size=[G.population[v] for v in H], - node_color=node_color, - with_labels=False) + node_color = [float(H.degree(v)) for v in H] + nx.draw(H, G.position, + node_size=[G.population[v] for v in H], + node_color=node_color, + with_labels=False) # scale the axes equally - plt.xlim(-5000,500) - plt.ylim(-2000,3500) + plt.xlim(-5000, 500) + plt.ylim(-2000, 3500) - plt.savefig("knuth_miles.png") + plt.show() except: pass - - - diff --git a/examples/drawing/plot_labels_and_colors.py b/examples/drawing/plot_labels_and_colors.py new file mode 100644 index 00000000000..81a30321ba6 --- /dev/null +++ b/examples/drawing/plot_labels_and_colors.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python +""" +================= +Labels And Colors +================= + +Draw a graph with matplotlib, color by degree. + +You must have matplotlib for this to work. +""" +# Author: Aric Hagberg (hagberg@lanl.gov) +import matplotlib.pyplot as plt + +import networkx as nx + +G = nx.cubical_graph() +pos = nx.spring_layout(G) # positions for all nodes + +# nodes +nx.draw_networkx_nodes(G, pos, + nodelist=[0, 1, 2, 3], + node_color='r', + node_size=500, + alpha=0.8) +nx.draw_networkx_nodes(G, pos, + nodelist=[4, 5, 6, 7], + node_color='b', + node_size=500, + alpha=0.8) + +# edges +nx.draw_networkx_edges(G, pos, width=1.0, alpha=0.5) +nx.draw_networkx_edges(G, pos, + edgelist=[(0, 1), (1, 2), (2, 3), (3, 0)], + width=8, alpha=0.5, edge_color='r') +nx.draw_networkx_edges(G, pos, + edgelist=[(4, 5), (5, 6), (6, 7), (7, 4)], + width=8, alpha=0.5, edge_color='b') + + +# some math labels +labels = {} +labels[0] = r'$a$' +labels[1] = r'$b$' +labels[2] = r'$c$' +labels[3] = r'$d$' +labels[4] = r'$\alpha$' +labels[5] = r'$\beta$' +labels[6] = r'$\gamma$' +labels[7] = r'$\delta$' +nx.draw_networkx_labels(G, pos, labels, font_size=16) + +plt.axis('off') +plt.show() diff --git a/examples/drawing/lanl_routes.py b/examples/drawing/plot_lanl_routes.py similarity index 80% rename from examples/drawing/lanl_routes.py rename to examples/drawing/plot_lanl_routes.py index ae6f08d1ca3..21267893fa3 100644 --- a/examples/drawing/lanl_routes.py +++ b/examples/drawing/plot_lanl_routes.py @@ -1,5 +1,9 @@ #!/usr/bin/env python """ +=========== +Lanl Routes +=========== + Routes to LANL from 186 sites on the Internet. This uses Graphviz for layout so you need PyGraphviz or pydot. @@ -20,7 +24,7 @@ def lanl_graph(): """ import networkx as nx try: - fh = open('lanl_routes.edgelist' , 'r') + fh = open('lanl_routes.edgelist', 'r') except IOError: print("lanl.edges not found") raise @@ -28,20 +32,21 @@ def lanl_graph(): G = nx.Graph() time = {} - time[0] = 0 # assign 0 to center node + time[0] = 0 # assign 0 to center node for line in fh.readlines(): (head, tail, rtt) = line.split() G.add_edge(int(head), int(tail)) time[int(head)] = float(rtt) # get largest component and assign ping times to G0time dictionary - G0 = sorted(nx.connected_component_subgraphs(G), key = len, reverse=True)[0] + G0 = sorted(nx.connected_component_subgraphs(G), key=len, reverse=True)[0] G0.rtt = {} for n in G0: G0.rtt[n] = time[n] return G0 + if __name__ == '__main__': import networkx as nx import math @@ -56,10 +61,10 @@ def lanl_graph(): raise ImportError("This example needs Graphviz and either " "PyGraphviz or pydot") - G=lanl_graph() + G = lanl_graph() - print("graph has %d nodes with %d edges"\ - %(nx.number_of_nodes(G), nx.number_of_edges(G))) + print("graph has %d nodes with %d edges" + % (nx.number_of_nodes(G), nx.number_of_edges(G))) print(nx.number_connected_components(G), "connected components") import matplotlib.pyplot as plt @@ -73,8 +78,8 @@ def lanl_graph(): alpha=0.5, node_size=15) # adjust the plot limits - xmax = 1.02 * max(xx for xx,yy in pos.values()) - ymax = 1.02 * max(yy for xx,yy in pos.values()) + xmax = 1.02 * max(xx for xx, yy in pos.values()) + ymax = 1.02 * max(yy for xx, yy in pos.values()) plt.xlim(0, xmax) plt.ylim(0, ymax) - plt.savefig("lanl_routes.png") + plt.show() diff --git a/examples/drawing/node_colormap.py b/examples/drawing/plot_node_colormap.py similarity index 55% rename from examples/drawing/node_colormap.py rename to examples/drawing/plot_node_colormap.py index 6a2d28d4bd0..f7b4700a801 100644 --- a/examples/drawing/node_colormap.py +++ b/examples/drawing/plot_node_colormap.py @@ -1,5 +1,9 @@ #!/usr/bin/env python """ +============= +Node Colormap +============= + Draw a graph with matplotlib, color by degree. You must have matplotlib for this to work. """ @@ -12,8 +16,7 @@ import networkx as nx -G=nx.cycle_graph(24) -pos=nx.spring_layout(G,iterations=200) -nx.draw(G,pos,node_color=range(24),node_size=800,cmap=plt.cm.Blues) -plt.savefig("node_colormap.png") # save as png -plt.show() # display +G = nx.cycle_graph(24) +pos = nx.spring_layout(G, iterations=200) +nx.draw(G, pos, node_color=range(24), node_size=800, cmap=plt.cm.Blues) +plt.show() diff --git a/examples/drawing/plot_random_geometric_graph.py b/examples/drawing/plot_random_geometric_graph.py new file mode 100644 index 00000000000..b234d103b55 --- /dev/null +++ b/examples/drawing/plot_random_geometric_graph.py @@ -0,0 +1,39 @@ +""" +====================== +Random Geometric Graph +====================== + +Example +""" + +import networkx as nx +import matplotlib.pyplot as plt + +G = nx.random_geometric_graph(200, 0.125) +# position is stored as node attribute data for random_geometric_graph +pos = nx.get_node_attributes(G, 'pos') + +# find node near center (0.5,0.5) +dmin = 1 +ncenter = 0 +for n in pos: + x, y = pos[n] + d = (x - 0.5)**2 + (y - 0.5)**2 + if d < dmin: + ncenter = n + dmin = d + +# color by path length from node near center +p = dict(nx.single_source_shortest_path_length(G, ncenter)) + +plt.figure(figsize=(8, 8)) +nx.draw_networkx_edges(G, pos, nodelist=[ncenter], alpha=0.4) +nx.draw_networkx_nodes(G, pos, nodelist=p.keys(), + node_size=80, + node_color=p.values(), + cmap=plt.cm.Reds_r) + +plt.xlim(-0.05, 1.05) +plt.ylim(-0.05, 1.05) +plt.axis('off') +plt.show() diff --git a/examples/drawing/plot_sampson.py b/examples/drawing/plot_sampson.py new file mode 100644 index 00000000000..fa8ce147ee5 --- /dev/null +++ b/examples/drawing/plot_sampson.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python +""" +======= +Sampson +======= + +Sampson's monastery data. + +Shows how to read data from a zip file and plot multiple frames. + +""" +# Author: Aric Hagberg (hagberg@lanl.gov) + +# Copyright (C) 2010-2016 by +# Aric Hagberg +# Dan Schult +# Pieter Swart +# All rights reserved. +# BSD license. + +import zipfile +import cStringIO +import networkx as nx +import matplotlib.pyplot as plt + +zf = zipfile.ZipFile('sampson_data.zip') # zipfile object +e1 = cStringIO.StringIO(zf.read('samplike1.txt')) # read info file +e2 = cStringIO.StringIO(zf.read('samplike2.txt')) # read info file +e3 = cStringIO.StringIO(zf.read('samplike3.txt')) # read info file +G1 = nx.read_edgelist(e1, delimiter='\t') +G2 = nx.read_edgelist(e2, delimiter='\t') +G3 = nx.read_edgelist(e3, delimiter='\t') +pos = nx.spring_layout(G3, iterations=100) +plt.clf() + +plt.subplot(221) +plt.title('samplike1') +nx.draw(G1, pos, node_size=50, with_labels=False) +plt.subplot(222) +plt.title('samplike2') +nx.draw(G2, pos, node_size=50, with_labels=False) +plt.subplot(223) +plt.title('samplike3') +nx.draw(G3, pos, node_size=50, with_labels=False) +plt.subplot(224) +plt.title('samplike1,2,3') +nx.draw(G3, pos, edgelist=list(G3.edges()), node_size=50, with_labels=False) +nx.draw_networkx_edges(G1, pos, alpha=0.25) +nx.draw_networkx_edges(G2, pos, alpha=0.25) +plt.show() diff --git a/examples/drawing/simple_path.py b/examples/drawing/plot_simple_path.py similarity index 64% rename from examples/drawing/simple_path.py rename to examples/drawing/plot_simple_path.py index b7f70b9fcf4..1726c62b087 100644 --- a/examples/drawing/simple_path.py +++ b/examples/drawing/plot_simple_path.py @@ -1,16 +1,19 @@ #!/usr/bin/env python """ +=========== +Simple Path +=========== + Draw a graph with matplotlib. You must have matplotlib for this to work. """ try: import matplotlib.pyplot as plt except: - raise - + raise + import networkx as nx -G=nx.path_graph(8) +G = nx.path_graph(8) nx.draw(G) -plt.savefig("simple_path.png") # save as png -plt.show() # display +plt.show() diff --git a/examples/drawing/unix_email.py b/examples/drawing/plot_unix_email.py old mode 100755 new mode 100644 similarity index 70% rename from examples/drawing/unix_email.py rename to examples/drawing/plot_unix_email.py index e0a52d1ad18..16bf2ed80f4 --- a/examples/drawing/unix_email.py +++ b/examples/drawing/plot_unix_email.py @@ -1,5 +1,9 @@ #!/usr/bin/env python """ +========== +Unix Email +========== + Create a directed graph, allowing multiple edges and self loops, from a unix mailbox. The nodes are email addresses with links that point from the sender to the recievers. The edge data @@ -25,12 +29,14 @@ # BSD license. import email -from email.utils import getaddresses,parseaddr +from email.utils import getaddresses, parseaddr import mailbox import sys # unix mailbox recipe # see http://www.python.org/doc/current/lib/module-mailbox.html + + def msgfactory(fp): try: return email.message_from_file(fp) @@ -39,7 +45,6 @@ def msgfactory(fp): return '' - if __name__ == '__main__': import networkx as nx @@ -48,18 +53,18 @@ def msgfactory(fp): except: pass - if len(sys.argv)==1: + if len(sys.argv) == 1: filePath = "unix_email.mbox" else: filePath = sys.argv[1] - mbox = mailbox.mbox(filePath, msgfactory) # parse unix mailbox + mbox = mailbox.mbox(filePath, msgfactory) # parse unix mailbox - G=nx.MultiDiGraph() # create empty graph + G = nx.MultiDiGraph() # create empty graph # parse each messages and build graph - for msg in mbox: # msg is python email.Message.Message object - (source_name,source_addr) = parseaddr(msg['From']) # sender + for msg in mbox: # msg is python email.Message.Message object + (source_name, source_addr) = parseaddr(msg['From']) # sender # get all recipients # see http://www.python.org/doc/current/lib/module-email.Utils.html tos = msg.get_all('to', []) @@ -68,18 +73,16 @@ def msgfactory(fp): resent_ccs = msg.get_all('resent-cc', []) all_recipients = getaddresses(tos + ccs + resent_tos + resent_ccs) # now add the edges for this mail message - for (target_name,target_addr) in all_recipients: - G.add_edge(source_addr,target_addr,message=msg) + for (target_name, target_addr) in all_recipients: + G.add_edge(source_addr, target_addr, message=msg) # print edges with message subject - for (u,v,d) in G.edges(data=True): - print("From: %s To: %s Subject: %s"%(u,v,d['message']["Subject"])) - + for (u, v, d) in G.edges(data=True): + print("From: %s To: %s Subject: %s" % (u, v, d['message']["Subject"])) - try: # draw - pos=nx.spring_layout(G,iterations=10) - nx.draw(G,pos,node_size=0,alpha=0.4,edge_color='r',font_size=16) - plt.savefig("unix_email.png") + try: # draw + pos = nx.spring_layout(G, iterations=10) + nx.draw(G, pos, node_size=0, alpha=0.4, edge_color='r', font_size=16) plt.show() - except: # matplotlib not available + except: # matplotlib not available pass diff --git a/examples/drawing/plot_weighted_graph.py b/examples/drawing/plot_weighted_graph.py new file mode 100644 index 00000000000..8b511d6440f --- /dev/null +++ b/examples/drawing/plot_weighted_graph.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python +""" +============== +Weighted Graph +============== + +An example using Graph as a weighted network. +""" +# Author: Aric Hagberg (hagberg@lanl.gov) +try: + import matplotlib.pyplot as plt +except: + raise + +import networkx as nx + +G = nx.Graph() + +G.add_edge('a', 'b', weight=0.6) +G.add_edge('a', 'c', weight=0.2) +G.add_edge('c', 'd', weight=0.1) +G.add_edge('c', 'e', weight=0.7) +G.add_edge('c', 'f', weight=0.9) +G.add_edge('a', 'd', weight=0.3) + +elarge = [(u, v) for (u, v, d) in G.edges(data=True) if d['weight'] > 0.5] +esmall = [(u, v) for (u, v, d) in G.edges(data=True) if d['weight'] <= 0.5] + +pos = nx.spring_layout(G) # positions for all nodes + +# nodes +nx.draw_networkx_nodes(G, pos, node_size=700) + +# edges +nx.draw_networkx_edges(G, pos, edgelist=elarge, + width=6) +nx.draw_networkx_edges(G, pos, edgelist=esmall, + width=6, alpha=0.5, edge_color='b', style='dashed') + +# labels +nx.draw_networkx_labels(G, pos, font_size=20, font_family='sans-serif') + +plt.axis('off') +plt.show() diff --git a/examples/drawing/random_geometric_graph.py b/examples/drawing/random_geometric_graph.py deleted file mode 100644 index 78c480e0fb3..00000000000 --- a/examples/drawing/random_geometric_graph.py +++ /dev/null @@ -1,33 +0,0 @@ -import networkx as nx -import matplotlib.pyplot as plt - -G=nx.random_geometric_graph(200,0.125) -# position is stored as node attribute data for random_geometric_graph -pos=nx.get_node_attributes(G,'pos') - -# find node near center (0.5,0.5) -dmin=1 -ncenter=0 -for n in pos: - x,y=pos[n] - d=(x-0.5)**2+(y-0.5)**2 - if d -# Dan Schult -# Pieter Swart -# All rights reserved. -# BSD license. - -import zipfile, cStringIO -import networkx as nx -import matplotlib.pyplot as plt - -zf = zipfile.ZipFile('sampson_data.zip') # zipfile object -e1=cStringIO.StringIO(zf.read('samplike1.txt')) # read info file -e2=cStringIO.StringIO(zf.read('samplike2.txt')) # read info file -e3=cStringIO.StringIO(zf.read('samplike3.txt')) # read info file -G1=nx.read_edgelist(e1,delimiter='\t') -G2=nx.read_edgelist(e2,delimiter='\t') -G3=nx.read_edgelist(e3,delimiter='\t') -pos=nx.spring_layout(G3,iterations=100) -plt.clf() - -plt.subplot(221) -plt.title('samplike1') -nx.draw(G1,pos,node_size=50,with_labels=False) -plt.subplot(222) -plt.title('samplike2') -nx.draw(G2,pos,node_size=50,with_labels=False) -plt.subplot(223) -plt.title('samplike3') -nx.draw(G3,pos,node_size=50,with_labels=False) -plt.subplot(224) -plt.title('samplike1,2,3') -nx.draw(G3, pos, edgelist=list(G3.edges()), node_size=50, with_labels=False) -nx.draw_networkx_edges(G1,pos,alpha=0.25) -nx.draw_networkx_edges(G2,pos,alpha=0.25) -plt.savefig("sampson.png") # save as png -plt.show() # display diff --git a/examples/drawing/weighted_graph.py b/examples/drawing/weighted_graph.py deleted file mode 100644 index 74e26514477..00000000000 --- a/examples/drawing/weighted_graph.py +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env python -""" -An example using Graph as a weighted network. -""" -# Author: Aric Hagberg (hagberg@lanl.gov) -try: - import matplotlib.pyplot as plt -except: - raise - -import networkx as nx - -G=nx.Graph() - -G.add_edge('a','b',weight=0.6) -G.add_edge('a','c',weight=0.2) -G.add_edge('c','d',weight=0.1) -G.add_edge('c','e',weight=0.7) -G.add_edge('c','f',weight=0.9) -G.add_edge('a','d',weight=0.3) - -elarge=[(u,v) for (u,v,d) in G.edges(data=True) if d['weight'] >0.5] -esmall=[(u,v) for (u,v,d) in G.edges(data=True) if d['weight'] <=0.5] - -pos=nx.spring_layout(G) # positions for all nodes - -# nodes -nx.draw_networkx_nodes(G,pos,node_size=700) - -# edges -nx.draw_networkx_edges(G,pos,edgelist=elarge, - width=6) -nx.draw_networkx_edges(G,pos,edgelist=esmall, - width=6,alpha=0.5,edge_color='b',style='dashed') - -# labels -nx.draw_networkx_labels(G,pos,font_size=20,font_family='sans-serif') - -plt.axis('off') -plt.savefig("weighted_graph.png") # save as png -plt.show() # display diff --git a/examples/graph/README.txt b/examples/graph/README.txt new file mode 100644 index 00000000000..9b0e3b2123b --- /dev/null +++ b/examples/graph/README.txt @@ -0,0 +1,2 @@ +Graph +----- diff --git a/examples/graph/atlas2.py b/examples/graph/atlas2.py index 268f5d3a610..76e4be56bd0 100644 --- a/examples/graph/atlas2.py +++ b/examples/graph/atlas2.py @@ -1,5 +1,9 @@ #!/usr/bin/env python """ +====== +Atlas2 +====== + Write first 20 graphs from the graph atlas as graphviz dot files Gn.dot where n=0,19. Requires pygraphviz and graphviz. @@ -23,7 +27,7 @@ for G in atlas: print("graph %s has %d nodes with %d edges" - %(G.name,NX.number_of_nodes(G),NX.number_of_edges(G))) + % (G.name, NX.number_of_nodes(G), NX.number_of_edges(G))) A = nx.nx_agraph.to_agraph(G) A.graph_attr['label'] = G.name # set default node attributes diff --git a/examples/graph/degree_sequence.py b/examples/graph/degree_sequence.py index 15c452505b6..d9f034e43b6 100644 --- a/examples/graph/degree_sequence.py +++ b/examples/graph/degree_sequence.py @@ -1,5 +1,9 @@ #!/usr/bin/env python """ +=============== +Degree Sequence +=============== + Random graph from given degree sequence. """ # Author: Aric Hagberg (hagberg@lanl.gov) @@ -15,20 +19,20 @@ from networkx import * -z=[5,3,3,3,3,2,2,2,1,1,1] +z = [5, 3, 3, 3, 3, 2, 2, 2, 1, 1, 1] print(is_valid_degree_sequence(z)) print("Configuration model") -G=configuration_model(z) # configuration model -degree_sequence = [d for n,d in G.degree()] # degree sequence +G = configuration_model(z) # configuration model +degree_sequence = [d for n, d in G.degree()] # degree sequence print("Degree sequence %s" % degree_sequence) print("Degree histogram") -hist={} +hist = {} for d in degree_sequence: if d in hist: - hist[d]+=1 + hist[d] += 1 else: - hist[d]=1 + hist[d] = 1 print("degree #nodes") for d in hist: - print('%d %d' % (d,hist[d])) + print('%d %d' % (d, hist[d])) diff --git a/examples/graph/erdos_renyi.py b/examples/graph/erdos_renyi.py index 63ffb1891d8..0ffc07da156 100644 --- a/examples/graph/erdos_renyi.py +++ b/examples/graph/erdos_renyi.py @@ -1,6 +1,10 @@ # -*- coding: utf-8 -*- #!/usr/bin/env python """ +=========== +Erdos Renyi +=========== + Create an G{n,m} random graph with n nodes and m edges and report some properties. @@ -20,19 +24,18 @@ from networkx import * import sys -n=10 # 10 nodes -m=20 # 20 edges +n = 10 # 10 nodes +m = 20 # 20 edges -G=gnm_random_graph(n,m) +G = gnm_random_graph(n, m) # some properties print("node degree clustering") for v in nodes(G): - print('%s %d %f' % (v,degree(G,v),clustering(G,v))) + print('%s %d %f' % (v, degree(G, v), clustering(G, v))) -# print the adjacency list to terminal +# print the adjacency list to terminal try: - write_adjlist(G,sys.stdout) -except TypeError: # Python 3.x - write_adjlist(G,sys.stdout.buffer) - + write_adjlist(G, sys.stdout) +except TypeError: # Python 3.x + write_adjlist(G, sys.stdout.buffer) diff --git a/examples/graph/expected_degree_sequence.py b/examples/graph/expected_degree_sequence.py index 0a00851cd26..c48cac0090c 100644 --- a/examples/graph/expected_degree_sequence.py +++ b/examples/graph/expected_degree_sequence.py @@ -1,5 +1,9 @@ #!/usr/bin/env python """ +======================== +Expected Degree Sequence +======================== + Random graph from given degree sequence. """ # Author: Aric Hagberg (hagberg@lanl.gov) @@ -15,15 +19,14 @@ from networkx.generators.degree_seq import * # make a random graph of 500 nodes with expected degrees of 50 -n=500 # n nodes -p=0.1 -w=[p*n for i in range(n)] # w = p*n for all nodes -G=expected_degree_graph(w) # configuration model +n = 500 # n nodes +p = 0.1 +w = [p * n for i in range(n)] # w = p*n for all nodes +G = expected_degree_graph(w) # configuration model print("Degree histogram") print("degree (#nodes) ****") -dh=degree_histogram(G) -low=min(degree(G)) -for i in range(low,len(dh)): - bar=''.join(dh[i]*['*']) - print("%2s (%2s) %s"%(i,dh[i],bar)) - +dh = degree_histogram(G) +low = min(degree(G)) +for i in range(low, len(dh)): + bar = ''.join(dh[i] * ['*']) + print("%2s (%2s) %s" % (i, dh[i], bar)) diff --git a/examples/graph/football.py b/examples/graph/football.py index 7c4114e3fdb..4977322816b 100644 --- a/examples/graph/football.py +++ b/examples/graph/football.py @@ -1,5 +1,9 @@ #!/usr/bin/env python """ +======== +Football +======== + Load football network in GML format and compute some network statistcs. Shows how to download GML graph in a zipped file, unpack it, and load @@ -20,27 +24,27 @@ from networkx import * -url="http://www-personal.umich.edu/~mejn/netdata/football.zip" +url = "http://www-personal.umich.edu/~mejn/netdata/football.zip" -try: # Python 3.x +try: # Python 3.x import urllib.request as urllib -except ImportError: # Python 2.x +except ImportError: # Python 2.x import urllib import io import zipfile sock = urllib.urlopen(url) # open URL -s=io.BytesIO(sock.read()) # read into BytesIO "file" +s = io.BytesIO(sock.read()) # read into BytesIO "file" sock.close() -zf = zipfile.ZipFile(s) # zipfile object -txt=zf.read('football.txt').decode() # read info file -gml=zf.read('football.gml').decode() # read gml data +zf = zipfile.ZipFile(s) # zipfile object +txt = zf.read('football.txt').decode() # read info file +gml = zf.read('football.gml').decode() # read gml data # throw away bogus first line with # from mejn files -gml=gml.split('\n')[1:] -G=parse_gml(gml) # parse gml data +gml = gml.split('\n')[1:] +G = parse_gml(gml) # parse gml data print(txt) # print degree for each team - number of games -for n,d in G.degree(): +for n, d in G.degree(): print('%s %d' % (n, d)) diff --git a/examples/graph/karate_club.py b/examples/graph/karate_club.py index 58121f3c749..bb7892b0bc0 100644 --- a/examples/graph/karate_club.py +++ b/examples/graph/karate_club.py @@ -1,5 +1,9 @@ #!/usr/bin/env python """ +=========== +Karate Club +=========== + Zachary's Karate Club graph Data file from: @@ -11,7 +15,7 @@ Journal of Anthropological Research, 33, 452-473. """ import networkx as nx -G=nx.karate_club_graph() +G = nx.karate_club_graph() print("Node Degree") for v in G: - print('%s %s' % (v,G.degree(v))) + print('%s %s' % (v, G.degree(v))) diff --git a/examples/graph/napoleon_russian_campaign.py b/examples/graph/plot_napoleon_russian_campaign.py similarity index 64% rename from examples/graph/napoleon_russian_campaign.py rename to examples/graph/plot_napoleon_russian_campaign.py index b7a354dc120..30d5ff5e0d2 100644 --- a/examples/graph/napoleon_russian_campaign.py +++ b/examples/graph/plot_napoleon_russian_campaign.py @@ -1,5 +1,9 @@ #!/usr/bin/env python """ +========================= +Napoleon Russian Campaign +========================= + Minard's data from Napoleon's 1812-1813 Russian Campaign. http://www.math.yorku.ca/SCS/Gallery/minard/minard.txt @@ -18,7 +22,7 @@ def minard_graph(): - data1="""\ + data1 = """\ 24.0,54.9,340000,A,1 24.5,55.0,340000,A,1 25.5,54.5,340000,A,1 @@ -54,7 +58,7 @@ def minard_graph(): 24.4,54.4,4000,R,1 24.2,54.4,4000,R,1 24.1,54.4,4000,R,1""" - data2="""\ + data2 = """\ 24.0,55.1,60000,A,2 24.5,55.2,60000,A,2 25.5,54.7,60000,A,2 @@ -64,14 +68,14 @@ def minard_graph(): 29.2,54.2,30000,R,2 28.5,54.1,30000,R,2 28.3,54.2,28000,R,2""" - data3="""\ + data3 = """\ 24.0,55.2,22000,A,3 24.5,55.3,22000,A,3 24.6,55.8,6000,A,3 24.6,55.8,6000,R,3 24.2,54.4,6000,R,3 24.1,54.4,6000,R,3""" - cities="""\ + cities = """\ 24.0,55.0,Kowno 25.3,54.7,Wilna 26.4,54.4,Smorgoni @@ -93,53 +97,53 @@ def minard_graph(): 36.6,55.3,Tarantino 36.5,55.0,Malo-Jarosewii""" - c={} + c = {} for line in cities.split('\n'): - x,y,name=line.split(',') - c[name]=(float(x),float(y)) + x, y, name = line.split(',') + c[name] = (float(x), float(y)) - g=[] + g = [] - for data in [data1,data2,data3]: - G=nx.Graph() - i=0 - G.pos={} # location - G.pop={} # size - last=None + for data in [data1, data2, data3]: + G = nx.Graph() + i = 0 + G.pos = {} # location + G.pop = {} # size + last = None for line in data.split('\n'): - x,y,p,r,n=line.split(',') - G.pos[i]=(float(x),float(y)) - G.pop[i]=int(p) + x, y, p, r, n = line.split(',') + G.pos[i] = (float(x), float(y)) + G.pop[i] = int(p) if last is None: - last=i + last = i else: - G.add_edge(i,last,**{r:int(n)}) - last=i - i=i+1 + G.add_edge(i, last, **{r: int(n)}) + last = i + i = i + 1 g.append(G) - return g,c + return g, c + if __name__ == "__main__": - (g,city)=minard_graph() + (g, city) = minard_graph() try: import matplotlib.pyplot as plt - plt.figure(1,figsize=(11,5)) + plt.figure(1, figsize=(11, 5)) plt.clf() - colors=['b','g','r'] + colors = ['b', 'g', 'r'] for G in g: - c=colors.pop(0) - node_size=[int(G.pop[n]/300.0) for n in G] - nx.draw_networkx_edges(G,G.pos,edge_color=c,width=4,alpha=0.5) - nx.draw_networkx_nodes(G,G.pos,node_size=node_size,node_color=c,alpha=0.5) - nx.draw_networkx_nodes(G,G.pos,node_size=5,node_color='k') + c = colors.pop(0) + node_size = [int(G.pop[n] / 300.0) for n in G] + nx.draw_networkx_edges(G, G.pos, edge_color=c, width=4, alpha=0.5) + nx.draw_networkx_nodes(G, G.pos, node_size=node_size, node_color=c, alpha=0.5) + nx.draw_networkx_nodes(G, G.pos, node_size=5, node_color='k') for c in city: - x,y=city[c] - plt.text(x,y+0.1,c) - plt.savefig("napoleon_russian_campaign.png") + x, y = city[c] + plt.text(x, y + 0.1, c) + plt.show() except ImportError: pass - diff --git a/examples/graph/roget.py b/examples/graph/roget.py index b31baa322c7..b2814351865 100644 --- a/examples/graph/roget.py +++ b/examples/graph/roget.py @@ -1,5 +1,9 @@ #!/usr/bin/env python """ +===== +Roget +===== + Build a directed graph of 1022 categories and 5075 cross-references as defined in the 1879 version of Roget's Thesaurus contained in the datafile roget_dat.txt. This example is described in @@ -35,47 +39,48 @@ import re import sys + def roget_graph(): """ Return the thesaurus graph from the roget.dat example in the Stanford Graph Base. """ # open file roget_dat.txt.gz (or roget_dat.txt) import gzip - fh=gzip.open('roget_dat.txt.gz','r') + fh = gzip.open('roget_dat.txt.gz', 'r') - G=DiGraph() + G = DiGraph() for line in fh.readlines(): line = line.decode() - if line.startswith("*"): # skip comments + if line.startswith("*"): # skip comments continue - if line.startswith(" "): # this is a continuation line, append - line=oldline+line - if line.endswith("\\\n"): # continuation line, buffer, goto next - oldline=line.strip("\\\n") + if line.startswith(" "): # this is a continuation line, append + line = oldline + line + if line.endswith("\\\n"): # continuation line, buffer, goto next + oldline = line.strip("\\\n") continue - (headname,tails)=line.split(":") + (headname, tails) = line.split(":") # head - numfind=re.compile("^\d+") # re to find the number of this word - head=numfind.findall(headname)[0] # get the number + numfind = re.compile("^\d+") # re to find the number of this word + head = numfind.findall(headname)[0] # get the number G.add_node(head) for tail in tails.split(): - if head==tail: - print("skipping self loop",head,tail, file=sys.stderr) - G.add_edge(head,tail) + if head == tail: + print("skipping self loop", head, tail, file=sys.stderr) + G.add_edge(head, tail) return G + if __name__ == '__main__': from networkx import * - G=roget_graph() + G = roget_graph() print("Loaded roget_dat.txt containing 1022 categories.") - print("digraph has %d nodes with %d edges"\ - %(number_of_nodes(G),number_of_edges(G))) - UG=G.to_undirected() - print(number_connected_components(UG),"connected components") - + print("digraph has %d nodes with %d edges" + % (number_of_nodes(G), number_of_edges(G))) + UG = G.to_undirected() + print(number_connected_components(UG), "connected components") diff --git a/examples/graph/words.py b/examples/graph/words.py index 9b5b9dfcfcb..dfde263be1c 100644 --- a/examples/graph/words.py +++ b/examples/graph/words.py @@ -1,4 +1,8 @@ """ +===== +Words +===== + Words/Ladder Graph ------------------ Generate an undirected graph over the 5757 5-letter words in the @@ -29,15 +33,18 @@ #------------------------------------------------------------------- # The Words/Ladder graph of Section 1.1 #------------------------------------------------------------------- + + def generate_graph(words): from string import ascii_lowercase as lowercase G = nx.Graph(name="words") - lookup = dict((c,lowercase.index(c)) for c in lowercase) + lookup = dict((c, lowercase.index(c)) for c in lowercase) + def edit_distance_one(word): for i in range(len(word)): - left, c, right = word[0:i], word[i], word[i+1:] - j = lookup[c] # lowercase.index(c) - for cc in lowercase[j+1:]: + left, c, right = word[0:i], word[i], word[i + 1:] + j = lookup[c] # lowercase.index(c) + for cc in lowercase[j + 1:]: yield left + cc + right candgen = ((word, cand) for word in sorted(words) for cand in edit_distance_one(word) if cand in words) @@ -46,39 +53,37 @@ def edit_distance_one(word): G.add_edge(word, cand) return G + def words_graph(): """Return the words example graph from the Stanford GraphBase""" import gzip - fh=gzip.open('words_dat.txt.gz','r') - words=set() + fh = gzip.open('words_dat.txt.gz', 'r') + words = set() for line in fh.readlines(): line = line.decode() if line.startswith('*'): continue - w=str(line[0:5]) + w = str(line[0:5]) words.add(w) return generate_graph(words) + if __name__ == '__main__': from networkx import * - G=words_graph() + G = words_graph() print("Loaded words_dat.txt containing 5757 five-letter English words.") print("Two words are connected if they differ in one letter.") print("Graph has %d nodes with %d edges" - %(number_of_nodes(G),number_of_edges(G))) + % (number_of_nodes(G), number_of_edges(G))) print("%d connected components" % number_connected_components(G)) - for (source,target) in [('chaos','order'), - ('nodes','graph'), - ('pound','marks')]: - print("Shortest path between %s and %s is"%(source,target)) + for (source, target) in [('chaos', 'order'), + ('nodes', 'graph'), + ('pound', 'marks')]: + print("Shortest path between %s and %s is" % (source, target)) try: - sp=shortest_path(G, source, target) + sp = shortest_path(G, source, target) for n in sp: print(n) except nx.NetworkXNoPath: print("None") - - - - diff --git a/examples/javascript/README.txt b/examples/javascript/README.txt new file mode 100644 index 00000000000..bcf45a3eac5 --- /dev/null +++ b/examples/javascript/README.txt @@ -0,0 +1,2 @@ +Javascript +---------- diff --git a/examples/javascript/force.py b/examples/javascript/force.py index 4834da11b5f..fb6275fedd2 100644 --- a/examples/javascript/force.py +++ b/examples/javascript/force.py @@ -1,4 +1,9 @@ -"""Example of writing JSON format graph data and using the D3 Javascript library to produce an HTML/Javascript drawing. +""" +========== +Javascript +========== + +Example of writing JSON format graph data and using the D3 Javascript library to produce an HTML/Javascript drawing. """ # Author: Aric Hagberg @@ -13,22 +18,25 @@ from networkx.readwrite import json_graph import flask -G = nx.barbell_graph(6,3) +G = nx.barbell_graph(6, 3) # this d3 example uses the name attribute for the mouse-hover value, # so add a name to each node for n in G: G.node[n]['name'] = n # write json formatted data -d = json_graph.node_link_data(G) # node-link format to serialize +d = json_graph.node_link_data(G) # node-link format to serialize # write json -json.dump(d, open('force/force.json','w')) +json.dump(d, open('force/force.json', 'w')) print('Wrote node-link JSON data to force/force.json') # Serve the file over http to allow for cross origin requests app = flask.Flask(__name__, static_folder="force") + @app.route('/') def static_proxy(path): - return app.send_static_file(path) + return app.send_static_file(path) + + print('\nGo to http://localhost:8000/force.html to see the example\n') -app.run(port=8000) \ No newline at end of file +app.run(port=8000) diff --git a/examples/jit/README.txt b/examples/jit/README.txt new file mode 100644 index 00000000000..d9c41bf859e --- /dev/null +++ b/examples/jit/README.txt @@ -0,0 +1,2 @@ +JIT +--- diff --git a/examples/jit/rgraph.py b/examples/jit/rgraph.py index 15607ed2401..d70c1ce4ab5 100644 --- a/examples/jit/rgraph.py +++ b/examples/jit/rgraph.py @@ -1,5 +1,9 @@ #!/usr/bin/env python """ +====== +Rgraph +====== + An example showing how to use the JavaScript InfoVis Toolkit (JIT) JSON export diff --git a/examples/pygraphviz/README.txt b/examples/pygraphviz/README.txt new file mode 100644 index 00000000000..b493e07c4bd --- /dev/null +++ b/examples/pygraphviz/README.txt @@ -0,0 +1,2 @@ +Pygraphviz +---------- diff --git a/examples/pygraphviz/pygraphviz_attributes.py b/examples/pygraphviz/pygraphviz_attributes.py index 247dbbc3f3b..50a36cdc375 100644 --- a/examples/pygraphviz/pygraphviz_attributes.py +++ b/examples/pygraphviz/pygraphviz_attributes.py @@ -1,11 +1,14 @@ #!/usr/bin/env python """ +===================== +Pygraphviz Attributes +===================== + An example showing how to use the interface to the pygraphviz AGraph class to convert to and from graphviz. Also see the pygraphviz documentation and examples at http://pygraphviz.github.io/ - """ # Author: Aric Hagberg (hagberg@lanl.gov) diff --git a/examples/pygraphviz/pygraphviz_draw.py b/examples/pygraphviz/pygraphviz_draw.py index 8f361eb22d8..d638eb742e1 100644 --- a/examples/pygraphviz/pygraphviz_draw.py +++ b/examples/pygraphviz/pygraphviz_draw.py @@ -1,12 +1,14 @@ #!/usr/bin/env python """ +=============== +Pygraphviz Draw +=============== + An example showing how to use the interface to the pygraphviz AGraph class to draw a graph. Also see the pygraphviz documentation and examples at http://pygraphviz.github.io/ - - """ # Author: Aric Hagberg (hagberg@lanl.gov) @@ -25,4 +27,3 @@ A = nx.nx_agraph.to_agraph(G) # convert to a graphviz graph A.layout() # neato layout A.draw("k5.ps") # write postscript in k5.ps with neato layout - diff --git a/examples/pygraphviz/pygraphviz_simple.py b/examples/pygraphviz/pygraphviz_simple.py index 7fb4ad42195..71850488384 100644 --- a/examples/pygraphviz/pygraphviz_simple.py +++ b/examples/pygraphviz/pygraphviz_simple.py @@ -1,12 +1,14 @@ #!/usr/bin/env python """ +================= +Pygraphviz Simple +================= + An example showing how to use the interface to the pygraphviz AGraph class to convert to and from graphviz. Also see the pygraphviz documentation and examples at http://pygraphviz.github.io/ - - """ # Author: Aric Hagberg (hagberg@lanl.gov) @@ -28,5 +30,4 @@ G1 = nx.Graph(X1) # now make it a Graph A.write('k5.dot') # write to dot file -X3 = nx.nx_agraph.read_dot('k5.dot') # read from dotfile - +X3 = nx.nx_agraph.read_dot('k5.dot') # read from dotfile diff --git a/examples/pygraphviz/write_dotfile.py b/examples/pygraphviz/write_dotfile.py index a9043f06d3a..a683efef3ea 100644 --- a/examples/pygraphviz/write_dotfile.py +++ b/examples/pygraphviz/write_dotfile.py @@ -1,5 +1,10 @@ #!/usr/bin/env python """ +============= +Write Dotfile +============= + + Write a dot file from a networkx graph for further processing with graphviz. You need to have either pygraphviz or pydot for this example. @@ -39,6 +44,6 @@ print() raise -G=nx.grid_2d_graph(5,5) # 5x5 grid -write_dot(G,"grid.dot") +G = nx.grid_2d_graph(5, 5) # 5x5 grid +write_dot(G, "grid.dot") print("Now run: neato -Tps grid.dot >grid.ps") diff --git a/examples/subclass/README.txt b/examples/subclass/README.txt new file mode 100644 index 00000000000..e3650b1bacc --- /dev/null +++ b/examples/subclass/README.txt @@ -0,0 +1,2 @@ +Subclass +-------- diff --git a/examples/subclass/antigraph.py b/examples/subclass/antigraph.py index cf0649aba31..1c2b4d13d9a 100644 --- a/examples/subclass/antigraph.py +++ b/examples/subclass/antigraph.py @@ -1,4 +1,9 @@ -""" Complement graph class for small footprint when working on dense graphs. +""" +========= +Antigraph +========= + +Complement graph class for small footprint when working on dense graphs. This class allows you to add the edges that *do not exist* in the dense graph. However, when applying algorithms to this complement graph data @@ -21,6 +26,7 @@ __all__ = ['AntiGraph'] + class AntiGraph(nx.Graph): """ Class for complement graphs. @@ -35,6 +41,7 @@ class AntiGraph(nx.Graph): """ all_edge_dict = {'weight': 1} + def single_edge_dict(self): return self.all_edge_dict edge_attr_dict_factory = single_edge_dict @@ -56,7 +63,6 @@ def __getitem__(self, n): return dict((node, self.all_edge_dict) for node in set(self.adj) - set(self.adj[n]) - set([n])) - def neighbors(self, n): """Return an iterator over all neighbors of node n in the dense graph. @@ -65,7 +71,7 @@ def neighbors(self, n): try: return iter(set(self.adj) - set(self.adj[n]) - set([n])) except KeyError: - raise NetworkXError("The node %s is not in the graph."%(n,)) + raise NetworkXError("The node %s is not in the graph." % (n,)) def degree(self, nbunch=None, weight=None): """Return an iterator for (node, degree) in the dense graph. @@ -103,21 +109,21 @@ def degree(self, nbunch=None, weight=None): """ if nbunch is None: nodes_nbrs = ((n, {v: self.all_edge_dict for v in - set(self.adj) - set(self.adj[n]) - set([n])}) - for n in self.nodes()) + set(self.adj) - set(self.adj[n]) - set([n])}) + for n in self.nodes()) else: - nodes_nbrs= ((n, {v: self.all_edge_dict for v in - set(self.nodes()) - set(self.adj[n]) - set([n])}) - for n in self.nbunch_iter(nbunch)) + nodes_nbrs = ((n, {v: self.all_edge_dict for v in + set(self.nodes()) - set(self.adj[n]) - set([n])}) + for n in self.nbunch_iter(nbunch)) if weight is None: - for n,nbrs in nodes_nbrs: - yield (n,len(nbrs)+(n in nbrs)) # return tuple (n,degree) + for n, nbrs in nodes_nbrs: + yield (n, len(nbrs) + (n in nbrs)) # return tuple (n,degree) else: # AntiGraph is a ThinGraph so all edges have weight 1 - for n,nbrs in nodes_nbrs: + for n, nbrs in nodes_nbrs: yield (n, sum((nbrs[nbr].get(weight, 1) for nbr in nbrs)) + - (n in nbrs and nbrs[n].get(weight, 1))) + (n in nbrs and nbrs[n].get(weight, 1))) def adjacency_iter(self): """Return an iterator of (node, adjacency set) tuples for all nodes @@ -141,7 +147,7 @@ def adjacency_iter(self): # Build several pairs of graphs, a regular graph # and the AntiGraph of it's complement, which behaves # as if it were the original graph. - Gnp = nx.gnp_random_graph(20,0.8) + Gnp = nx.gnp_random_graph(20, 0.8) Anp = AntiGraph(nx.complement(Gnp)) Gd = nx.davis_southern_women_graph() Ad = AntiGraph(nx.complement(Gd)) @@ -165,7 +171,7 @@ def adjacency_iter(self): node = list(G.nodes())[0] nodes = list(G.nodes())[1:4] assert G.degree(node) == A.degree(node) - assert sum(d for n,d in G.degree()) == sum(d for n,d in A.degree()) + assert sum(d for n, d in G.degree()) == sum(d for n, d in A.degree()) # AntiGraph is a ThinGraph, so all the weights are 1 - assert sum(d for n,d in A.degree()) == sum(d for n,d in A.degree(weight='weight')) - assert sum(d for n,d in G.degree(nodes)) == sum(d for n,d in A.degree(nodes)) + assert sum(d for n, d in A.degree()) == sum(d for n, d in A.degree(weight='weight')) + assert sum(d for n, d in G.degree(nodes)) == sum(d for n, d in A.degree(nodes)) diff --git a/examples/subclass/printgraph.py b/examples/subclass/printgraph.py index b2d53ea33a3..31004d201a5 100644 --- a/examples/subclass/printgraph.py +++ b/examples/subclass/printgraph.py @@ -1,4 +1,8 @@ """ +=========== +Print Graph +=========== + Example subclass of the Graph class. """ # Author: Aric Hagberg (hagberg@lanl.gov) @@ -18,53 +22,55 @@ import networkx.convert as convert from copy import deepcopy + class PrintGraph(Graph): """ Example subclass of the Graph class. Prints activity log to file or standard output. """ + def __init__(self, data=None, name='', file=None, **attr): - Graph.__init__(self, data=data,name=name,**attr) + Graph.__init__(self, data=data, name=name, **attr) if file is None: import sys - self.fh=sys.stdout + self.fh = sys.stdout else: - self.fh=open(file,'w') + self.fh = open(file, 'w') def add_node(self, n, attr_dict=None, **attr): - Graph.add_node(self,n,attr_dict=attr_dict,**attr) - self.fh.write("Add node: %s\n"%n) + Graph.add_node(self, n, attr_dict=attr_dict, **attr) + self.fh.write("Add node: %s\n" % n) def add_nodes_from(self, nodes, **attr): for n in nodes: self.add_node(n, **attr) - def remove_node(self,n): - Graph.remove_node(self,n) - self.fh.write("Remove node: %s\n"%n) + def remove_node(self, n): + Graph.remove_node(self, n) + self.fh.write("Remove node: %s\n" % n) def remove_nodes_from(self, nodes): for n in nodes: self.remove_node(n) def add_edge(self, u, v, attr_dict=None, **attr): - Graph.add_edge(self,u,v,attr_dict=attr_dict,**attr) - self.fh.write("Add edge: %s-%s\n"%(u,v)) + Graph.add_edge(self, u, v, attr_dict=attr_dict, **attr) + self.fh.write("Add edge: %s-%s\n" % (u, v)) def add_edges_from(self, ebunch, attr_dict=None, **attr): for e in ebunch: - u,v=e[0:2] - self.add_edge(u,v,attr_dict=attr_dict,**attr) + u, v = e[0:2] + self.add_edge(u, v, attr_dict=attr_dict, **attr) def remove_edge(self, u, v): - Graph.remove_edge(self,u,v) - self.fh.write("Remove edge: %s-%s\n"%(u,v)) + Graph.remove_edge(self, u, v) + self.fh.write("Remove edge: %s-%s\n" % (u, v)) def remove_edges_from(self, ebunch): for e in ebunch: - u,v=e[0:2] - self.remove_edge(u,v) + u, v = e[0:2] + self.remove_edge(u, v) def clear(self): Graph.clear(self) @@ -76,56 +82,54 @@ def subgraph(self, nbunch, copy=True): # # Also for copy=True Graph() uses dictionary assignment for speed # Here we use H.add_edge() - bunch =set(self.nbunch_iter(nbunch)) + bunch = set(self.nbunch_iter(nbunch)) if not copy: # remove all nodes (and attached edges) not in nbunch self.remove_nodes_from([n for n in self if n not in bunch]) - self.name = "Subgraph of (%s)"%(self.name) + self.name = "Subgraph of (%s)" % (self.name) return self else: # create new graph and copy subgraph into it H = self.__class__() - H.name = "Subgraph of (%s)"%(self.name) + H.name = "Subgraph of (%s)" % (self.name) # add nodes H.add_nodes_from(bunch) # add edges - seen=set() - for u,nbrs in self.adjacency_iter(): + seen = set() + for u, nbrs in self.adjacency_iter(): if u in bunch: - for v,datadict in nbrs.items(): + for v, datadict in nbrs.items(): if v in bunch and v not in seen: - dd=deepcopy(datadict) - H.add_edge(u,v,dd) + dd = deepcopy(datadict) + H.add_edge(u, v, dd) seen.add(u) # copy node and graph attr dicts - H.node=dict( (n,deepcopy(d)) - for (n,d) in self.node.items() if n in H) - H.graph=deepcopy(self.graph) + H.node = dict((n, deepcopy(d)) + for (n, d) in self.node.items() if n in H) + H.graph = deepcopy(self.graph) return H - -if __name__=='__main__': - G=PrintGraph() +if __name__ == '__main__': + G = PrintGraph() G.add_node('foo') - G.add_nodes_from('bar',weight=8) + G.add_nodes_from('bar', weight=8) G.remove_node('b') G.remove_nodes_from('ar') print(G.nodes(data=True)) - G.add_edge(0,1,weight=10) + G.add_edge(0, 1, weight=10) print(list(G.edges(data=True))) - G.remove_edge(0,1) - G.add_edges_from(list(zip(list(range(0o3)),list(range(1,4)))),weight=10) + G.remove_edge(0, 1) + G.add_edges_from(list(zip(list(range(0o3)), list(range(1, 4)))), weight=10) print(list(G.edges(data=True))) - G.remove_edges_from(list(zip(list(range(0o3)),list(range(1,4))))) + G.remove_edges_from(list(zip(list(range(0o3)), list(range(1, 4))))) print(list(G.edges(data=True))) - - G=PrintGraph() + G = PrintGraph() nx.add_path(G, range(10)) print("subgraph") - H1=G.subgraph(range(4), copy=False) - H2=G.subgraph(range(4), copy=False) + H1 = G.subgraph(range(4), copy=False) + H2 = G.subgraph(range(4), copy=False) print(list(H1.edges())) print(list(H2.edges())) diff --git a/networkx/__init__.py b/networkx/__init__.py index aad83ca9e8d..e8ee0f88fa6 100644 --- a/networkx/__init__.py +++ b/networkx/__init__.py @@ -2,26 +2,57 @@ NetworkX ======== - NetworkX (NX) is a Python package for the creation, manipulation, and - study of the structure, dynamics, and functions of complex networks. +NetworkX is a Python package for the creation, manipulation, +and study of the structure, dynamics, and functions +of complex networks. - https://networkx.lanl.gov/ +Website (including documentation):: -Using ------ + http://networkx.github.io - Just write in Python +Mailing list:: + + https://groups.google.com/forum/#!forum/networkx-discuss + +Source:: + + https://github.com/networkx/networkx + +Bug reports:: + + https://github.com/networkx/networkx/issues + +Simple example +-------------- + +Find the shortest path between two nodes in an undirected graph:: >>> import networkx as nx - >>> G=nx.Graph() - >>> G.add_edge(1,2) - >>> G.add_node(42) - >>> print(sorted(G.nodes())) - [1, 2, 42] - >>> print(sorted(G.edges())) - [(1, 2)] + >>> G = nx.Graph() + >>> G.add_edge('A', 'B', weight=4) + >>> G.add_edge('B', 'D', weight=2) + >>> G.add_edge('A', 'C', weight=3) + >>> G.add_edge('C', 'D', weight=4) + >>> nx.shortest_path(G, 'A', 'D', weight='weight') + ['A', 'B', 'D'] + +Bugs +---- + +Please report any bugs that you find `here `_. +Or, even better, fork the repository on GitHub and create a pull request (PR). + +License +------- + +Released under the 3-Clause BSD license:: + + Copyright (C) 2004-2017 NetworkX Developers + Aric Hagberg + Dan Schult + Pieter Swart """ -# Copyright (C) 2004-2016 by +# Copyright (C) 2004-2017 by # Aric Hagberg # Dan Schult # Pieter Swart diff --git a/doc/gitwash_dumper.py b/tools/gitwash_dumper.py similarity index 92% rename from doc/gitwash_dumper.py rename to tools/gitwash_dumper.py index 47c6f4267ae..b4d782fd321 100644 --- a/doc/gitwash_dumper.py +++ b/tools/gitwash_dumper.py @@ -1,7 +1,8 @@ #!/usr/bin/env python ''' Checkout gitwash repo into directory and do search replace on name ''' -from __future__ import print_function +from __future__ import (absolute_import, division, print_function) + import os from os.path import join as pjoin import shutil @@ -55,16 +56,19 @@ def filename_search_replace(sr_pairs, filename, backup=False): ''' Search and replace for expressions in files ''' - in_txt = open(filename, 'rt').read(-1) + with open(filename, 'rt') as in_fh: + in_txt = in_fh.read(-1) out_txt = in_txt[:] for in_exp, out_exp in sr_pairs: in_exp = re.compile(in_exp) out_txt = in_exp.sub(out_exp, out_txt) if in_txt == out_txt: return False - open(filename, 'wt').write(out_txt) + with open(filename, 'wt') as out_fh: + out_fh.write(out_txt) if backup: - open(filename + '.bak', 'wt').write(in_txt) + with open(filename + '.bak', 'wt') as bak_fh: + bak_fh.write(in_txt) return True @@ -115,7 +119,8 @@ def make_link_targets(proj_name, .. _`proj_name`: url .. _`proj_name` mailing list: url """ - link_contents = open(known_link_fname, 'rt').readlines() + with open(known_link_fname, 'rt') as link_fh: + link_contents = link_fh.readlines() have_url = not url is None have_ml_url = not ml_url is None have_gh_url = None @@ -139,7 +144,7 @@ def make_link_targets(proj_name, if not url is None: lines.append('.. _`%s`: %s\n' % (proj_name, url)) if not have_gh_url: - gh_url = 'http://github.com/%s/%s\n' % (user_name, repo_name) + gh_url = 'https://github.com/%s/%s\n' % (user_name, repo_name) lines.append('.. _`%s github`: %s\n' % (proj_name, gh_url)) if not ml_url is None: lines.append('.. _`%s mailing list`: %s\n' % (proj_name, ml_url)) @@ -148,9 +153,8 @@ def make_link_targets(proj_name, return # A neat little header line lines = ['.. %s\n' % proj_name] + lines - out_links = open(out_link_fname, 'wt') - out_links.writelines(lines) - out_links.close() + with open(out_link_fname, 'wt') as out_links: + out_links.writelines(lines) USAGE = ''' @@ -177,7 +181,7 @@ def main(): metavar="MAIN_GH_USER") parser.add_option("--gitwash-url", dest="gitwash_url", help="URL to gitwash repository - default %s" - % GITWASH_CENTRAL, + % GITWASH_CENTRAL, default=GITWASH_CENTRAL, metavar="GITWASH_URL") parser.add_option("--gitwash-branch", dest="gitwash_branch",