diff --git a/.gitignore b/.gitignore index af835ecb6..f0a852ea0 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ vendor/install/ .DS_Store doc/source/gallery.rst +doc/linkcheck doc/api/ doc/dash/ doc/html/ diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 000000000..7af56aadb --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,49 @@ +# .readthedocs.yaml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +submodules: + include: + - vendor/source/igraph + recursive: true + +# Set the version of Python and other tools you might need +build: + os: ubuntu-22.04 + apt_packages: + - cmake + - flex + - bison + - libxml2-dev + - zlib1g-dev + + tools: + python: "3.9" + # You can also specify other tool versions: + # nodejs: "16" + # rust: "1.55" + # golang: "1.17" + + jobs: + pre_build: + - bash ./scripts/rtd_prebuild.sh + # One website complains about legacy SSL renegotiation (?), skip for now + #- python -m sphinx -b linkcheck doc/source/ _build/linkcheck + + +# Build documentation in the docs/ directory with Sphinx +sphinx: + configuration: doc/source/conf.py + +# If using Sphinx, optionally build your docs in additional formats such as PDF +# formats: +# - pdf + +# Optionally declare the Python requirements required to build your docs +python: + install: + - requirements: doc/source/requirements.txt + diff --git a/doc/source/analysis.rst b/doc/source/analysis.rst index d9e23869e..1be2277df 100644 --- a/doc/source/analysis.rst +++ b/doc/source/analysis.rst @@ -6,7 +6,7 @@ Graph analysis ============== -|igraph| enables analysis of graphs/networks from simple operations such as adding and removing nodes to complex theoretical constructs such as community detection. Read the `API documentation`_ for details on each function and class. +|igraph| enables analysis of graphs/networks from simple operations such as adding and removing nodes to complex theoretical constructs such as community detection. Read the :doc:`api/index` for details on each function and class. The context for the following examples will be to import |igraph| (commonly as `ig`), have the :class:`Graph` class and to have one or more graphs available:: @@ -51,7 +51,7 @@ You can index and slice vertices and edges like indexing and slicing a list:: >>> g.vs[0, 2, 4] >>> g.es[3] -.. note:: The `vs` and `es` attributes are special sequences with their own useful methods. See `API documentation`_ for a full list. +.. note:: The `vs` and `es` attributes are special sequences with their own useful methods. See the :doc:`api/index` for a full list. If you prefer a vanilla edge list, you can use :meth:`Graph.get_edge_list`. @@ -442,5 +442,3 @@ Flow and cuts are closely related, therefore you might find the following functi - :meth:`Graph.all_st_mincuts` - :meth:`Graph.edge_connectivity` or :meth:`Graph.edge_disjoint_paths` or :meth:`Graph.adhesion` - :meth:`Graph.vertex_connectivity` or :meth:`Graph.cohesion` - -.. _API documentation: https://igraph.org/python/api/latest/ diff --git a/doc/source/conf.py b/doc/source/conf.py index 28fb072c1..2e2356231 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -15,58 +15,52 @@ import sys import os -import os.path as op +import importlib +from pathlib import Path import sphinxbootstrap4theme +# Check if we are inside readthedocs, the conf is quite different there +is_inside_rtd = os.getenv("READTHEDOCS", "") == "True" +rtd_version = os.getenv("READTHEDOCS_VERSION", "") + + # Utility functions # NOTE: these could be improved, esp by importing igraph, but that -# currently generates a conflict with pydoctor +# currently generates a conflict with pydoctor. It is funny because pydoctor's +# docs indeed import itself... perhaps there's a decent way to solve this. def get_root_dir(): '''Get project root folder''' - root_folder = op.abspath('../..') - return root_folder + return str(Path('.').absolute().parent.parent) def get_igraphdir(): '''Get igraph folder''' - vmaj, vmin = sys.version_info[:2] - root_folder = get_root_dir() - ig_folder = op.join( - root_folder, - '.venv', - 'lib', - f'python{vmaj}.{vmin}', - 'site-packages', - 'igraph', - ) - return ig_folder + return Path(importlib.util.find_spec('igraph').origin).parent def get_igraph_version(): '''Get igraph version''' - version_file = op.join( - get_igraphdir(), - 'version.py', - ) + if is_inside_rtd: + return rtd_version + + version_file = get_igraphdir() / 'version.py' with open(version_file, 'rt') as f: version_info = (f.readline() .rstrip('\n') .split('=')[1] .strip()[1:-1] .split(', ')) - version = '.'.join(version_info) - + version = '.'.join(version_info) + return version -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.append(os.path.abspath('.')) - # -- General configuration ----------------------------------------------------- +_igraph_dir = str(get_igraphdir()) +_igraph_version = get_igraph_version() + # If your documentation needs a minimal Sphinx version, state it here. #needs_sphinx = '1.0' @@ -78,32 +72,14 @@ def get_igraph_version(): 'sphinx.ext.mathjax', 'sphinx.ext.intersphinx', 'gallery_generator', - 'pydoctor.sphinx_ext.build_apidocs', - 'postprocess_api', #'sphinx_panels', + 'pydoctor.sphinx_ext.build_apidocs', ] -# Using --no-sidebar option to skip the sidebar whole together not to generate noise in the HTML. -# Because the pydoctor output is integrated in a smaller div with a custom CSS it's not optimal to include the sidebar. -pydoctor_args = [ - '--project-name="igraph"', - '--project-version=' + get_igraph_version(), - '--project-url=https://igraph.org/python', - '--introspect-c-modules', - '--no-sidebar', - '--docformat=epytext', - #'--intersphinx='+get_root_dir()+'/doc/tutorial/objects.inv', - '--html-output=' + op.join(get_root_dir(), 'doc', 'html', 'api'), - #'--html-viewsource-base=https://github.com/igraph/python-igraph/tree/default', - '--project-base-dir=' + get_igraphdir(), - get_igraphdir(), -] - -# API docs relative to the rest of the docs -# NOTE: there is a bug in pydoctor that requires this to be a subfolder -# of the main docs. Although we patch pydoctor to work anyway, links might -# be broken if that constraint is not satisfied -pydoctor_url_path = 'api/' +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.append(os.path.abspath('.')) # The suffix of source filenames. source_suffix = '.rst' @@ -123,7 +99,7 @@ def get_igraph_version(): # built documents. # # The short X.Y version. -version = get_igraph_version() +version = _igraph_version # The full version, including alpha/beta/rc tags. release = version @@ -164,26 +140,50 @@ def get_igraph_version(): # -- Options for HTML output --------------------------------------------------- -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = 'sphinxbootstrap4theme' -#html_theme = 'alabaster' +# The theme to use for HTML and HTML Help pages. RTD overloads this with their +# standard theme if the variable 'html_theme' is not set +if not is_inside_rtd: + html_theme = 'sphinxbootstrap4theme' -# Add any paths that contain templates here, relative to this directory. -templates_path = [ - '_templates', -] + # Add any paths that contain templates here, relative to this directory. + templates_path = [ + '_templates', + ] -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -html_theme_options = { - "navbar_style": "full", - "navbar_color_class": "dark", -} + # Theme options are theme-specific and customize the look and feel of a theme + # further. For a list of options available for each theme, see the + # documentation. + html_theme_options = { + "navbar_style": "full", + "navbar_color_class": "dark", + } + + # Add any paths that contain custom themes here, relative to this directory. + html_theme_path = [sphinxbootstrap4theme.get_path()] + + # Add any paths that contain custom static files (such as style sheets) here, + # relative to this directory. They are copied after the builtin static files, + # so a file named "default.css" will overwrite the builtin "default.css". + html_static_path = ['_static'] + + # If false, no module index is generated. + html_domain_indices = False + + # If false, no index is generated. + html_use_index = False + + # If true, the index is split into individual pages for each letter. + #html_split_index = False + + # If true, links to the reST sources are added to the pages. + html_show_sourcelink = False -# Add any paths that contain custom themes here, relative to this directory. -html_theme_path = [sphinxbootstrap4theme.get_path()] +else: + + # Inspired by pydoctor's RTD page itself + # https://github.com/twisted/pydoctor/blob/master/docs/source/conf.py + html_theme = "sphinx_rtd_theme" + html_static_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". @@ -201,11 +201,6 @@ def get_igraph_version(): # pixels large. #html_favicon = None -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' @@ -221,18 +216,6 @@ def get_igraph_version(): # template names. #html_additional_pages = {} -# If false, no module index is generated. -html_domain_indices = False - -# If false, no index is generated. -html_use_index = False - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -html_show_sourcelink = False - # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. #html_show_sphinx = True @@ -251,6 +234,49 @@ def get_igraph_version(): htmlhelp_basename = 'igraphdoc' +# -- Options for pydoctor ------------------------------------------------------ + +def get_pydoctor_html_outputdir(pydoctor_url_path): + '''Get HTML output dir for pydoctor''' + # NOTE: obviously this is a little tricky, but it does work for both + # the sphinx-build script and the python -m sphinx module calls. It works + # locally, on github pages, and on RTD. + return str(Path(sys.argv[-1]) / pydoctor_url_path.strip('/')) + + +# API docs relative to the rest of the docs, needed for pydoctor to play nicely +# with intersphinx (https://pypi.org/project/pydoctor/#pydoctor-21-2-0) +# NOTE: As of 2022 AD, pydoctor requires this to be a subfolder of the docs. +pydoctor_url_path = 'api/' + +pydoctor_args = [ + '--project-name="igraph"', + '--project-version=' + version, + '--project-url=https://igraph.readthedocs.io', + '--introspect-c-modules', + '--docformat=epytext', + #'--intersphinx='+get_root_dir()+'/doc/tutorial/objects.inv', + '--html-output=' + get_pydoctor_html_outputdir(pydoctor_url_path), + #'--html-viewsource-base=https://github.com/igraph/python-igraph/tree/default', + '--project-base-dir=' + _igraph_dir, + ] + +# Using --no-sidebar option to skip the sidebar because the pydoctor output is +# integrated in a smaller div with a custom CSS. +if not is_inside_rtd: + pydoctor_args.extend([ + '--no-sidebar', + ]) +else: + pydoctor_args.extend([ + '--theme=readthedocs', + ]) +pydoctor_args.append(_igraph_dir) + +# RTD needs no postprocessing for pydoctor, while Jekyll does +if not is_inside_rtd: + extensions.append('postprocess_api') + # -- Options for LaTeX output -------------------------------------------------- # The paper size ('letter' or 'a4'). diff --git a/doc/source/generation.rst b/doc/source/generation.rst index 34cb8d64e..674d971c3 100644 --- a/doc/source/generation.rst +++ b/doc/source/generation.rst @@ -7,7 +7,7 @@ Graph generation ================ -The first step of most |igraph| applications is to generate a graph. This section will explain a number of ways to do that. Read the `API documentation`_ for details on each function and class. +The first step of most |igraph| applications is to generate a graph. This section will explain a number of ways to do that. Read the :doc:`api/index` for details on each function and class. The :class:`Graph` class is the main object used to generate graphs:: @@ -55,7 +55,7 @@ a representation that uses Python builtin data structures: - :meth:`Graph.to_list_dict` - :meth:`Graph.to_dict_dict` -See the `API documentation`_ of each function for details and examples. +See the :doc:`api/index` of each function for details and examples. From matrices +++++++++++++ @@ -208,5 +208,3 @@ Finally, there are some ways of generating graphs that are not covered by the pr - graphs from LCF notation :meth:`Graph.LCF` - small graphs of any "isomorphism class" :meth:`Graph.Isoclass` - graphs with a specified degree sequence :meth:`Graph.Realize_Degree_Sequence` - -.. _API documentation: https://igraph.org/python/api/latest/ diff --git a/doc/source/index.rst b/doc/source/index.rst index 0b1226cb1..60b1d987c 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -25,9 +25,11 @@ python-igraph |release| ======================= -|igraph| is a fast open source tool to manipulate and analyze graphs or networks. It is primarily written in C. `python-igraph` is |igraph|'s interface for the Python programming language. +Python interface of `igraph`_, a fast and open source C library to manipulate and analyze graphs (aka networks). It can be used to: -`python-graph` includes functionality for graph plotting and conversion from/to `networkx`_. + - Create, manipulate, and analyze networks. + - Convert graphs from/to `networkx`_, `graph-tool`_ and many file formats. + - Plot networks using `Cairo`_, `matplotlib`_, and `plotly`_. Installation @@ -63,9 +65,9 @@ Documentation **Tutorials** - - :doc:`tutorials/quickstart/quickstart` - - :doc:`Gallery ` - - :doc:`tutorial` + - :doc:`Quick Start ` + - :doc:`Example Gallery ` + - :doc:`Extended tutorial ` .. container:: @@ -74,7 +76,7 @@ Documentation - :doc:`Generation ` - :doc:`Analysis ` - :doc:`Visualization ` - - :doc:`configuration` + - :doc:`Configuration ` .. container:: twocol @@ -82,7 +84,7 @@ Documentation **Reference** - - :doc:`../../api/latest/index` + - :doc:`api/index` - `Source code `_ .. container:: @@ -92,6 +94,7 @@ Documentation - :doc:`FAQs ` - `Forum `_ +Documentation for `python-igraph <= 0.10.1` is available on our `old website `_. .. toctree:: :maxdepth: 1 @@ -115,4 +118,9 @@ Indices and tables * :ref:`modindex` +.. _igraph: https://igraph.org .. _networkx: https://networkx.org/documentation/stable/ +.. _graph-tool: https://graph-tool.skewed.de/ +.. _Cairo: https://www.cairographics.org +.. _matplotlib: https://matplotlib.org +.. _plotly: https://plotly.com/python/ diff --git a/doc/source/install.rst b/doc/source/install.rst index f6caa73d8..899d930b7 100644 --- a/doc/source/install.rst +++ b/doc/source/install.rst @@ -10,7 +10,7 @@ Installing |igraph| Binary package (recommended) ============================ -It is recommended to install a binary package that includes both C core and Python interface. You can choose either of `PyPI `_ or `Conda `_. Linux users can also use their package manager. +It is recommended to install a binary package that includes both C core and Python interface. You can choose either of `PyPI `_ or `Conda `_. Linux users can also use their package manager. PyPI ---- @@ -22,7 +22,7 @@ To install the Python interface of |igraph| globally, use the following command $ pip install igraph If you prefer to install |igraph| in a user folder using a `virtual environment -`_, use the following commands instead:: +`_, use the following commands instead:: $ python -m venv my_environment $ source my_environment/bin/activate @@ -145,11 +145,11 @@ Q: I am trying to install |igraph| on Windows but am getting DLL import errors A: The most common reason for this error is that you do not have the Visual C++ Redistributable library installed on your machine. Python's own installer is supposed to install it, but in case it was not installed on your system, you can -`download it from Microsoft `_. +`download it from Microsoft `_. Q: I am trying to use |igraph| but get errors about something called Cairo ---------------------------------------------------------------------------------- -A: |igraph| by default uses a third-party called `Cairo `_ for plotting. +A: |igraph| by default uses a third-party called `Cairo `_ for plotting. If Cairo is not installed on your computer, you might get an import error. This error is most commonly encountered on Windows machines. @@ -165,7 +165,7 @@ you need to install Cairo headers using your package manager (Linux) or `homebre The Cairo project does not provide pre-compiled binaries for Windows, but Christoph Gohlke maintains a site containing unofficial Windows binaries for several Python extension packages, including Cairo. Therefore, the easiest way to install Cairo on Windows along with its Python bindings -is simply to download it from `Christoph's site `_. +is simply to download it from `Christoph's site `_. Make sure you use an installer that is suitable for your Windows platform (32-bit or 64-bit) and the version of Python you are using. diff --git a/doc/source/requirements.txt b/doc/source/requirements.txt new file mode 100644 index 000000000..342477ba6 --- /dev/null +++ b/doc/source/requirements.txt @@ -0,0 +1,10 @@ +pip +wheel +requests>=2.28.1 + +sphinxbootstrap4theme +pydoctor + +numpy +pandas +matplotlib diff --git a/doc/source/sphinxext/postprocess_api.py b/doc/source/sphinxext/postprocess_api.py index 7af0d35fb..8a059d84f 100644 --- a/doc/source/sphinxext/postprocess_api.py +++ b/doc/source/sphinxext/postprocess_api.py @@ -1,9 +1,9 @@ """ -Sphinx plugin to run example scripts and create a gallery page. - -Lightly modified from the seaborn project (Michael Waskom). -Originally, lightly modified from the mpld3 project. +Sphinx extension to postprocess pydoctor API output. +- If this is released via Jekyll (e.g. GitHub pages), we need to ensure Jekyll + headers are present everywhere and consistent. +- If this is released via readthedocs (RTD), we can skip this step, see conf.py """ from pathlib import Path @@ -18,8 +18,8 @@ def on_build_finished(app: Sphinx, exception: Exception) -> None: # Check if the index has Jekyll template marks. If it does, extract the # YAML frontmatter into a separate variable index_html = html_dir / 'index.html' - with open(index_html, 'rt') as f: - lines = f.readlines() + with open(index_html, 'rt') as handle: + lines = handle.readlines() # The Jekyll template starts with a --- line # Nontemplated HTML starts with some kind of XML tag if lines[0] != '---\n': @@ -78,14 +78,13 @@ def on_build_finished(app: Sphinx, exception: Exception) -> None: footer = footer.replace('"container"', '"container-fluid text-muted credit"').strip() # Patch-up content for Jekyll - content = (''.join(lines_mark[:-1]) + - indent(head, " ") + "\n" + - 'extrafoot: |\n' + - indent(footer, " ") + - indent(rest, " ") + - '\n' + - lines_mark[-1] + - body) + content = (''.join(lines_mark[:-1]) + + indent(head, " ") + "\n" + + 'extrafoot: |\n' + + indent(footer, " ") + + indent(rest, " ") + '\n' + + lines_mark[-1] + + body) # Write the patched content back to the file path.write_text(content) diff --git a/doc/source/tutorial.rst b/doc/source/tutorial.rst index c3089a033..0844d2156 100644 --- a/doc/source/tutorial.rst +++ b/doc/source/tutorial.rst @@ -573,6 +573,8 @@ The adjacency matrix for the example graph is For example, Claire (``[1, 0, 0, 1, 1, 1, 0]``) is directly connected to Alice (who has vertex index 0), Dennis (index 3), Esther (index 4), and Frank (index 5), but not to Bob (index 1) nor George (index 6). +.. _tutorial-layouts-plotting: + Layouts and plotting ==================== @@ -582,7 +584,7 @@ mapping from vertices to coordinates in two- or three-dimensional space first, preferably in a way that is pleasing for the eye. A separate branch of graph theory, namely graph drawing, tries to solve this problem via several graph layout algorithms. |igraph| implements quite a few layout algorithms and is also able to draw them onto -the screen or to a PDF, PNG or SVG file using the `Cairo library `_. +the screen or to a PDF, PNG or SVG file using the `Cairo library `_. .. important:: To follow the examples of this subsection, you need the Python bindings of the @@ -636,7 +638,7 @@ Method name Short name Algorithm description ==================================== =============== ============================================= .. _Distributed Recursive Layout: https://www.osti.gov/doecode/biblio/54626 -.. _Large Graph Layout: http://sourceforge.net/projects/lgl/ +.. _Large Graph Layout: https://sourceforge.net/projects/lgl/ Layout algorithms can either be called directly or using the common layout method called :meth:`~Graph.layout`:: @@ -874,7 +876,7 @@ Specifying colors in plots color (e.g., edge, vertex or label colors in the respective attributes): X11 color names - See the `list of X11 color names `_ + See the `list of X11 color names `_ in Wikipedia for the complete list. Alternatively you can see the keys of the igraph.drawing.colors.known_colors dictionary. Color names are case insensitive in igraph so "DarkBlue" can be written as @@ -962,13 +964,13 @@ Labeled edgelist ``ncol`` :meth:`Graph.Read_Ncol` :meth:`Graph.write_n Pickled graph ``pickle`` :meth:`Graph.Read_Pickle` :meth:`Graph.write_pickle` ================ ============= ============================ ============================= -.. _GraphViz: http://www.graphviz.org -.. _LGL: http://lgl.sourceforge.net/#FileFormat -.. _NCOL: http://lgl.sourceforge.net/#FileFormat -.. _Pajek: http://pajek.imfm.si/doku.php +.. _GraphViz: https://www.graphviz.org +.. _LGL: https://lgl.sourceforge.net/#FileFormat +.. _NCOL: https://lgl.sourceforge.net/#FileFormat +.. _Pajek: http://mrvar.fdv.uni-lj.si/pajek/ As an exercise, download the graph representation of the well-known -`Zachary karate club study `_ +`Zachary karate club study `_ from :download:`this file `, unzip it and try to load it into |igraph|. Since it is a GraphML file, you must use the GraphML reader method from the table above (make sure you use the appropriate path to the downloaded file):: diff --git a/doc/source/tutorials/articulation_points/articulation_points.rst b/doc/source/tutorials/articulation_points/articulation_points.rst index 5c05a7c6a..85ea30810 100644 --- a/doc/source/tutorials/articulation_points/articulation_points.rst +++ b/doc/source/tutorials/articulation_points/articulation_points.rst @@ -6,10 +6,7 @@ Articulation Points =================== -.. _articulation_points: https://igraph.org/python/doc/api/igraph._igraph.GraphBase.html#articulation_points -.. |articulation_points| replace:: :meth:`articulation_points` - -This example shows how to compute and visualize the `articulation points `_ in a graph using |articulation_points|_. For an example on bridges instead, see :ref:`tutorials-bridges`. +This example shows how to compute and visualize the `articulation points `_ in a graph using :meth:`igraph.GraphBase.articulation_points`. For an example on bridges instead, see :ref:`tutorials-bridges`. .. code-block:: python diff --git a/doc/source/tutorials/betweenness/betweenness.rst b/doc/source/tutorials/betweenness/betweenness.rst index 9f76e8dc9..1fc476f1d 100644 --- a/doc/source/tutorials/betweenness/betweenness.rst +++ b/doc/source/tutorials/betweenness/betweenness.rst @@ -6,12 +6,7 @@ Betweenness ======================= -.. _betweenness: https://igraph.org/python/doc/api/igraph._igraph.GraphBase.html#betweenness -.. |betweenness| replace:: :meth:`betweenness` -.. _edge_betweenness: https://igraph.org/python/doc/api/igraph._igraph.GraphBase.html#edge_betweenness -.. |edge_betweenness| replace:: :meth:`edge_betweenness` - -This example demonstrates how to visualize both vertex and edge betweenness with a custom defined color palette. We use the methods |betweenness|_ and |edge_betweenness|_ respectively, and demonstrate the effects on a standard `Krackhardt Kite `_ graph, as well as a `Watts-Strogatz `_ random graph. +This example demonstrates how to visualize both vertex and edge betweenness with a custom defined color palette. We use the methods :meth:`igraph.GraphBase.betweenness` and :meth:`igraph.GraphBase.edge_betweenness` respectively, and demonstrate the effects on a standard `Krackhardt Kite `_ graph, as well as a `Watts-Strogatz `_ random graph. First we import |igraph| and some libraries for plotting et al: @@ -23,10 +18,7 @@ First we import |igraph| and some libraries for plotting et al: from matplotlib.colors import LinearSegmentedColormap, Normalize import igraph as ig -.. _rescale: https://igraph.org/python/doc/api/igraph.utils.html#rescale -.. |rescale| replace:: :meth:`rescale` - -Next we define a function for drawing a graph on an Matplotlib axis. We set the color and size of each vertex and edge based on the betweenness value, and also generate some color bars on the sides to see how they translate to each other. We use `Matplotlib's Normalize class `_ to ensure that our color bar ranges are correct, as well as *igraph*'s |rescale|_ to rescale the betweennesses in the interval ``[0, 1]``: +Next we define a function for drawing a graph on an Matplotlib axis. We set the color and size of each vertex and edge based on the betweenness value, and also generate some color bars on the sides to see how they translate to each other. We use `Matplotlib's Normalize class `_ to ensure that our color bar ranges are correct, as well as *igraph*'s :meth:`igraph.utils.rescale` to rescale the betweennesses in the interval ``[0, 1]``: .. code-block:: python @@ -85,7 +77,6 @@ Finally, we call our function with the two graphs: figsize=(7, 6), gridspec_kw=dict(height_ratios=(15, 1, 1)), ) - #plt.subplots_adjust(bottom=0.3) plot_betweenness(g1, fig, *axs[:, 0]) plot_betweenness(g2, fig, *axs[:, 1]) fig.tight_layout(h_pad=1) diff --git a/doc/source/tutorials/bipartite_matching/bipartite_matching.rst b/doc/source/tutorials/bipartite_matching/bipartite_matching.rst index 8334f77c7..0464a7e48 100644 --- a/doc/source/tutorials/bipartite_matching/bipartite_matching.rst +++ b/doc/source/tutorials/bipartite_matching/bipartite_matching.rst @@ -6,10 +6,7 @@ Maximum Bipartite Matching ========================== -.. _maximum_bipartite_matching: https://igraph.org/python/doc/api/igraph.Graph.html#maximum_bipartite_matching -.. |maximum_bipartite_matching| replace:: :meth:`maximum_bipartite_matching` - -This example demonstrates an efficient way to find and visualise a maximum biparite matching using |maximum_bipartite_matching|_. First construct a bipartite graph +This example demonstrates an efficient way to find and visualise a maximum biparite matching using :meth:`igraph.Graph.maximum_bipartite_matching`. First construct a bipartite graph .. code-block:: python diff --git a/doc/source/tutorials/bipartite_matching_maxflow/bipartite_matching_maxflow.rst b/doc/source/tutorials/bipartite_matching_maxflow/bipartite_matching_maxflow.rst index 83ed53426..5034878cb 100644 --- a/doc/source/tutorials/bipartite_matching_maxflow/bipartite_matching_maxflow.rst +++ b/doc/source/tutorials/bipartite_matching_maxflow/bipartite_matching_maxflow.rst @@ -6,14 +6,9 @@ Maximum Bipartite Matching by Maximum Flow ========================================== -.. _maximum_bipartite_matching: https://igraph.org/python/doc/api/igraph.Graph.html#maximum_bipartite_matching -.. |maximum_bipartite_matching| replace:: :meth:`maximum_bipartite_matching` -.. _maxflow: https://igraph.org/python/doc/api/igraph.Graph.html#maxflow -.. |maxflow| replace:: :meth:`maxflow` +This example presents how to visualise bipartite matching using maximum flow (see :meth:`igraph.Graph.maxflow`). -This example presents how to visualise bipartite matching using maximum flow (see |maxflow|_). - -.. note:: |maximum_bipartite_matching|_ is usually a better way to find the maximum bipartite matching. For a demonstration on how to use that method instead, check out :ref:`tutorials-bipartite-matching`. +.. note:: :meth:`igraph.Graph.maximum_bipartite_matching` is usually a better way to find the maximum bipartite matching. For a demonstration on how to use that method instead, check out :ref:`tutorials-bipartite-matching`. .. code-block:: python @@ -38,7 +33,7 @@ This example presents how to visualise bipartite matching using maximum flow (se flow = g.maxflow(9, 10) # not setting capacities means that all edges have capacity 1.0 print("Size of maximum matching (maxflow) is:", flow.value) -Let's compare the output against |maximum_bipartite_matching|_ +Let's compare the output against :meth:`igraph.Graph.maximum_bipartite_matching`: .. code-block:: python diff --git a/doc/source/tutorials/bridges/bridges.rst b/doc/source/tutorials/bridges/bridges.rst index 13838b2a1..3505864d8 100644 --- a/doc/source/tutorials/bridges/bridges.rst +++ b/doc/source/tutorials/bridges/bridges.rst @@ -6,10 +6,7 @@ Bridges ======== -.. _bridges_method: https://igraph.org/python/doc/api/igraph._igraph.GraphBase.html#bridges -.. |bridges_method| replace:: :meth:`bridges_method` - -This example shows how to compute and visualize the `bridges `_ in a graph using |bridges_method|_. For an example on articulation points instead, see :ref:`tutorials-articulation-points`. +This example shows how to compute and visualize the `bridges `_ in a graph using :meth:`igraph.GraphBase.bridges`. For an example on articulation points instead, see :ref:`tutorials-articulation-points`. .. code-block:: python diff --git a/doc/source/tutorials/cluster_graph/cluster_graph.rst b/doc/source/tutorials/cluster_graph/cluster_graph.rst index 5e5e61921..4915984c7 100644 --- a/doc/source/tutorials/cluster_graph/cluster_graph.rst +++ b/doc/source/tutorials/cluster_graph/cluster_graph.rst @@ -6,12 +6,7 @@ Generating Cluster Graphs =========================== -.. _cluster_graph: https://igraph.org/python/doc/api/igraph.clustering.VertexClustering.html#cluster_graph -.. |cluster_graph| replace:: :meth:`cluster_graph` -.. _community_edge_betweenness: https://igraph.org/python/doc/api/igraph.Graph.html#community_edge_betweenness -.. |community_edge_betweenness| replace:: :meth:`community_edge_betweenness` - -This example shows how to find the communities in a graph, then contract each community into a single node using |cluster_graph|_. For this tutorial, we'll use the *Donald Knuth's Les Miserables Network*, which shows the coapperances of characters in the novel *Les Miserables*. The network can be obtained `here `_. +This example shows how to find the communities in a graph, then contract each community into a single node using :class:`igraph.clustering.VertexClustering`. For this tutorial, we'll use the *Donald Knuth's Les Miserables Network*, which shows the coapperances of characters in the novel *Les Miserables*. The network can be obtained `here `_. .. code-block:: python @@ -21,7 +16,7 @@ This example shows how to find the communities in a graph, then contract each co # Load the graph g = ig.load("./lesmis/lesmis.gml") -First, let's visualise the original communities, using |community_edge_betweenness|_ to separate out vertices into clusters. (For a more focused tutorial on just visualising communities, check out :ref:`tutorials-visualize-communities`). +First, let's visualise the original communities, using :meth:`igraph.Graph.community_edge_betweenness` to separate out vertices into clusters. (For a more focused tutorial on just visualising communities, check out :ref:`tutorials-visualize-communities`). .. code-block:: python @@ -69,7 +64,7 @@ Now let's try and contract the information down, using only a single vertex to r g.vs["size"] = 1 g.es["size"] = 1 -This is so we can define how each of these attributes get combined together when we call |cluster_graph|_. +This is so we can define how each of these attributes get combined together when we call :meth:`igraph.VertexClustering.cluster_graph`. .. code-block:: python @@ -88,12 +83,9 @@ This is so we can define how each of these attributes get combined together when Here, we take the mean of x and y values so that the nodes in the cluster graph are placed at the center of the original cluster's position. -.. _contract_vertices: https://igraph.org/python/doc/api/igraph._igraph.GraphBase.html#contract_vertices -.. |contract_vertices| replace:: :meth:`contract_vertices` - .. note:: - ``mean``, ``first``, and ``sum`` are all built-in collapsing functions, along with ``prod``, ``median``, ``max``, ``min``, ``last``, ``random``. You can also define your own custom collapsing functions, which take in a list and return a single element representing the combined attribute value. For more details on |igraph| contraction, see |contract_vertices|_ + ``mean``, ``first``, and ``sum`` are all built-in collapsing functions, along with ``prod``, ``median``, ``max``, ``min``, ``last``, ``random``. You can also define your own custom collapsing functions, which take in a list and return a single element representing the combined attribute value. For more details on |igraph| contraction, see :meth:`igraph.GraphBase.contract_vertices` Finally we plot out the graph using our calculated attributes: diff --git a/doc/source/tutorials/complement/complement.rst b/doc/source/tutorials/complement/complement.rst index 3b887ba41..cd51bcf61 100644 --- a/doc/source/tutorials/complement/complement.rst +++ b/doc/source/tutorials/complement/complement.rst @@ -6,10 +6,7 @@ Complement ================ -.. _complementer: https://igraph.org/python/doc/api/igraph._igraph.GraphBase.html#complementer -.. |complementer| replace:: :meth:`complementer` - -This example shows how to generate the `complement graph `_ of a graph (sometimes known as the anti-graph) using |complementer|_. +This example shows how to generate the `complement graph `_ of a graph (sometimes known as the anti-graph) using :meth:`igraph.GraphBase.complementer`. First we generate a random graph diff --git a/doc/source/tutorials/configuration/configuration.rst b/doc/source/tutorials/configuration/configuration.rst index 4a9a172ce..558f07fae 100644 --- a/doc/source/tutorials/configuration/configuration.rst +++ b/doc/source/tutorials/configuration/configuration.rst @@ -6,7 +6,7 @@ Configuration Instance ====================== -This example shows how to use |igraph|'s `configuration instance `_ to set default |igraph| settings. This is useful for setting global settings so that they don't need to be explicitly stated at the beginning of every |igraph| project you work on. +This example shows how to use |igraph|'s :class:`configuration instance ` to set default |igraph| settings. This is useful for setting global settings so that they don't need to be explicitly stated at the beginning of every |igraph| project you work on. First we define the default plotting backend, layout, and color palette, and save them. By default, ``ig.config.save()`` will save files to ``~/.igraphrc`` on Linux and Max OS X systems, or in ``%USERPROFILE%\.igraphrc`` for Windows systems. @@ -50,7 +50,7 @@ Note that we do not never explicitly state the backend, layout or palette, yet t Graph colored based on each node's betweenness centrality measure. -The full list of config settings can be found `here `_. +The full list of config settings can be found at :class:`igraph.Configuration`. .. note:: diff --git a/doc/source/tutorials/connected_components/connected_components.rst b/doc/source/tutorials/connected_components/connected_components.rst index 505af1494..d8a8578c3 100644 --- a/doc/source/tutorials/connected_components/connected_components.rst +++ b/doc/source/tutorials/connected_components/connected_components.rst @@ -6,10 +6,7 @@ Connected Components ===================== -.. _connected_components: https://igraph.org/python/doc/api/igraph.Graph.html#connected_components -.. |connected_components| replace:: :meth:`connected_components` - -This example demonstrates how to visualise the connected components in a graph using |connected_components|_. +This example demonstrates how to visualise the connected components in a graph using :meth:`igraph.GraphBase.connected_components`. .. code-block:: python @@ -47,4 +44,4 @@ The plotting results are: .. note:: - We use the integers from 0 to 200 instead of 0 to 255 in our vertex colors, since 255 in the `rainbow palette `_ corresponds to looping back to red. + We use the integers from 0 to 200 instead of 0 to 255 in our vertex colors, since 255 in the :class:`igraph.drawing.colors.RainbowPalette` corresponds to looping back to red. diff --git a/doc/source/tutorials/erdos_renyi/erdos_renyi.rst b/doc/source/tutorials/erdos_renyi/erdos_renyi.rst index 4ba1c3c31..dc0349652 100644 --- a/doc/source/tutorials/erdos_renyi/erdos_renyi.rst +++ b/doc/source/tutorials/erdos_renyi/erdos_renyi.rst @@ -6,11 +6,7 @@ Erdős-Rényi Graph ================= -.. _Erdos_Renyi: https://igraph.org/python/doc/api/igraph._igraph.GraphBase.html#Erdos_Renyi -.. |Erdos_Renyi| replace:: :meth:`Erdos_Renyi` - - -This example demonstrates how to generate `Erdős-Rényi Graphs `_ using |Erdos_Renyi|_. There are two variants of graphs: +This example demonstrates how to generate `Erdős-Rényi Graphs `_ using :meth:`igraph.GraphBase.Erdos_Renyi`. There are two variants of graphs: - ``Erdos_Renyi(n, p)`` will generate a graph where each edge between any two pair of nodes has an independent probability ``p`` of existing. - ``Erdos_Renyi(n, m)`` will pick a graph uniformly at random out of all graphs with ``n`` nodes and ``m`` edges. diff --git a/doc/source/tutorials/isomorphism/isomorphism.rst b/doc/source/tutorials/isomorphism/isomorphism.rst index e0b8b8a30..1d4175623 100644 --- a/doc/source/tutorials/isomorphism/isomorphism.rst +++ b/doc/source/tutorials/isomorphism/isomorphism.rst @@ -6,10 +6,7 @@ Isomorphism =========== -.. _isomorphic: https://igraph.org/python/doc/api/igraph._igraph.GraphBase.html#isomorphic -.. |isomorphic| replace:: :meth:`isomorphic` - -This example shows how to check for `isomorphism `_ between small graphs using |isomorphic|_. +This example shows how to check for `isomorphism `_ between small graphs using :meth:`igraph.GraphBase.isomorphic`. First we generate three different graphs: diff --git a/doc/source/tutorials/maxflow/maxflow.rst b/doc/source/tutorials/maxflow/maxflow.rst index 0e93ec577..85cb8a4ca 100644 --- a/doc/source/tutorials/maxflow/maxflow.rst +++ b/doc/source/tutorials/maxflow/maxflow.rst @@ -6,10 +6,7 @@ Maximum Flow ============ -.. _maxflow: https://igraph.org/python/doc/api/igraph.Graph.html#maxflow -.. |maxflow| replace:: :meth:`maxflow` - -This example shows how to construct a max flow on a directed graph with edge capacities using |maxflow|_. +This example shows how to construct a max flow on a directed graph with edge capacities using :meth:`igraph.Graph.maxflow`. .. code-block:: python diff --git a/doc/source/tutorials/minimum_spanning_trees/minimum_spanning_trees.rst b/doc/source/tutorials/minimum_spanning_trees/minimum_spanning_trees.rst index 8978eb30d..c24e67e3b 100644 --- a/doc/source/tutorials/minimum_spanning_trees/minimum_spanning_trees.rst +++ b/doc/source/tutorials/minimum_spanning_trees/minimum_spanning_trees.rst @@ -6,10 +6,7 @@ Minimum Spanning Trees ====================== -.. _spanning_tree: https://igraph.org/python/doc/api/igraph.Graph.html#spanning_tree -.. |spanning_tree| replace:: :meth:`spanning_tree` - -This example shows how to generate a `minimum spanning tree `_ from an input graph using |spanning_tree|_. If you only need a regular spanning tree, check out :ref:`tutorials-spanning-trees`. +This example shows how to generate a `minimum spanning tree `_ from an input graph using :meth:`igraph.Graph.spanning_tree`. If you only need a regular spanning tree, check out :ref:`tutorials-spanning-trees`. We start by generating a grid graph with random integer weights between 1 and 20: @@ -25,7 +22,7 @@ We start by generating a grid graph with random integer weights between 1 and 20 g = ig.Graph.Lattice([5, 5], circular=False) g.es["weight"] = [random.randint(1, 20) for _ in g.es] -We then call |spanning_tree|_, making sure to pass in the randomly generated weights. +We then call :meth:`igraph.Graph.spanning_tree`, making sure to pass in the randomly generated weights. .. code-block:: python diff --git a/doc/source/tutorials/ring_animation/ring_animation.rst b/doc/source/tutorials/ring_animation/ring_animation.rst index 455913572..e18411058 100644 --- a/doc/source/tutorials/ring_animation/ring_animation.rst +++ b/doc/source/tutorials/ring_animation/ring_animation.rst @@ -53,9 +53,6 @@ The received output is: Sequentially Animated Ring Graph -.. _induced_subgraph: https://igraph.org/python/api/latest/igraph._igraph.GraphBase.html#induced_subgraph -.. |induced_subgraph| replace:: :meth:`induced_subgraph` - .. note:: - We use *igraph*'s :meth:`Graph.subgraph()` (see |induced_subgraph|_) in order to obtain a section of the ring graph at a time for each frame. + We use *igraph*'s :meth:`Graph.subgraph()` (see :meth:`igraph.GraphBase.induced_subgraph`) in order to obtain a section of the ring graph at a time for each frame. diff --git a/doc/source/tutorials/shortest_paths/shortest_paths.rst b/doc/source/tutorials/shortest_paths/shortest_paths.rst index a8fe6c8e6..fab61b0cf 100644 --- a/doc/source/tutorials/shortest_paths/shortest_paths.rst +++ b/doc/source/tutorials/shortest_paths/shortest_paths.rst @@ -6,14 +6,9 @@ Shortest Paths ============== -.. _get_shortest_paths: https://igraph.org/python/doc/api/igraph._igraph.GraphBase.html#get_shortest_paths -.. |get_shortest_paths| replace:: :meth:`get_shortest_paths` -.. _get_all_shortest_paths: https://igraph.org/python/doc/api/igraph._igraph.GraphBase.html#get_all_shortest_paths -.. |get_all_shortest_paths| replace:: :meth:`get_all_shortest_paths` - This example demonstrates how to find the shortest distance between two vertices on a weighted and unweighted graph. -To find the shortest path or distance between two nodes, we can use |get_shortest_paths|_. If we're only interested in counting the unweighted distance, then we can do the following: +To find the shortest path or distance between two nodes, we can use :meth:`igraph.GraphBase.get_shortest_paths`. If we're only interested in counting the unweighted distance, then we can do the following: .. code-block:: python @@ -76,8 +71,8 @@ The output of these these two shortest paths are: .. note:: - - |get_shortest_paths|_ returns a list of lists becuase the `to` argument can also accept a list of vertex IDs. In that case, the shortest path to all each vertex is found and stored in the results array. - - If you're interested in finding *all* shortest paths, take a look at |get_all_shortest_paths|_. + - :meth:`igraph.GraphBase.get_shortest_paths` returns a list of lists becuase the `to` argument can also accept a list of vertex IDs. In that case, the shortest path to all each vertex is found and stored in the results array. + - If you're interested in finding *all* shortest paths, take a look at :meth:`igraph.GraphBase.get_all_shortest_paths`. In case you are wondering how the visualization figure was done, here's the code: diff --git a/doc/source/tutorials/simplify/simplify.rst b/doc/source/tutorials/simplify/simplify.rst index 3721f56b4..8012d5958 100644 --- a/doc/source/tutorials/simplify/simplify.rst +++ b/doc/source/tutorials/simplify/simplify.rst @@ -6,10 +6,7 @@ Simplify ======== -.. _simplify: https://igraph.org/python/doc/api/igraph._igraph.GraphBase.html#simplify -.. |simplify| replace:: :meth:`simplify` - -This example shows how to remove self loops and multiple edges using |simplify|_. +This example shows how to remove self loops and multiple edges using :meth:`igraph.GraphBase.simplify`. We start with a graph that includes loops and multiedges: diff --git a/doc/source/tutorials/spanning_trees/spanning_trees.rst b/doc/source/tutorials/spanning_trees/spanning_trees.rst index d60b58c95..cbc704269 100644 --- a/doc/source/tutorials/spanning_trees/spanning_trees.rst +++ b/doc/source/tutorials/spanning_trees/spanning_trees.rst @@ -6,10 +6,7 @@ Spanning Trees ============== -.. _spanning_tree: https://igraph.org/python/doc/api/igraph.Graph.html#spanning_tree -.. |spanning_tree| replace:: :meth:`spanning_tree` - -This example shows how to generate a spanning tree from an input graph using |spanning_tree|_. For the related idea of finding a *minimum spanning tree*, see :ref:`tutorials-minimum-spanning-trees`. +This example shows how to generate a spanning tree from an input graph using :meth:`igraph.Graph.spanning_tree`. For the related idea of finding a *minimum spanning tree*, see :ref:`tutorials-minimum-spanning-trees`. First we create a 6 by 6 lattice graph. @@ -21,10 +18,7 @@ First we create a 6 by 6 lattice graph. g = ig.Graph.Lattice([6, 6], circular=False) -.. _permute_vertices: https://igraph.org/python/doc/api/igraph._igraph.GraphBase.html#permute_vertices -.. |permute_vertices| replace:: :meth:`permute_vertices` - -As an optional step, we randomly rearrange some of the vertex IDs with |permute_vertices|_ in order to generate a more interesting spanning tree. +As an optional step, we randomly rearrange some of the vertex IDs with :meth:`igraph.GraphBase.permute_vertices` in order to generate a more interesting spanning tree. .. code-block:: python diff --git a/doc/source/tutorials/topological_sort/topological_sort.rst b/doc/source/tutorials/topological_sort/topological_sort.rst index d3d1b052b..451d72f5e 100644 --- a/doc/source/tutorials/topological_sort/topological_sort.rst +++ b/doc/source/tutorials/topological_sort/topological_sort.rst @@ -6,11 +6,7 @@ Topological sorting =================== -.. _topological_sorting: https://igraph.org/python/doc/api/igraph._igraph.GraphBase.html#topological_sorting -.. |topological_sorting| replace:: :meth:`topological_sorting` - - -This example demonstrates how to get a topological sorting on a directed acyclic graph (DAG). A topological sorting of a directed graph is a linear ordering based on the precedence implied by the directed edges. It exists iff the graph doesn't have any cycle. In ``igraph``, we can use |topological_sorting|_ to get a topological ordering of the vertices. +This example demonstrates how to get a topological sorting on a directed acyclic graph (DAG). A topological sorting of a directed graph is a linear ordering based on the precedence implied by the directed edges. It exists iff the graph doesn't have any cycle. In ``igraph``, we can use :meth:`igraph.GraphBase.topological_sorting` to get a topological ordering of the vertices. .. code-block:: python @@ -31,7 +27,7 @@ This example demonstrates how to get a topological sorting on a directed acyclic results = g.topological_sorting(mode='in') print('Topological sort of g (in):', *results) -There are two modes of |topological_sorting|_. ``'out'`` is the default mode which starts from a node with indegree equal to 0. Vice versa, the mode ``'in'`` starts from a node with outdegree equal to 0. +There are two modes of :meth:`igraph.GraphBase.topological_sorting`. ``'out'`` is the default mode which starts from a node with indegree equal to 0. Vice versa, the mode ``'in'`` starts from a node with outdegree equal to 0. The output of the code above is: diff --git a/doc/source/tutorials/visual_style/visual_style.rst b/doc/source/tutorials/visual_style/visual_style.rst index ec554aad3..095c043eb 100644 --- a/doc/source/tutorials/visual_style/visual_style.rst +++ b/doc/source/tutorials/visual_style/visual_style.rst @@ -47,4 +47,4 @@ The plots looks like this: Four graphs using the same palette and layout algorithm. .. note:: - If you would like to set global defaults, for example, always using the Matplotlib plotting backend, or using a particular color palette by default, you can use |igraph|'s `configuration instance `_. A quick example on how to use it can be found here: :ref:`tutorials-configuration` + If you would like to set global defaults, for example, always using the Matplotlib plotting backend, or using a particular color palette by default, you can use |igraph|'s `configuration instance :class:`igraph.configuration.Configuration`. A quick example on how to use it can be found here: :ref:`tutorials-configuration` diff --git a/doc/source/tutorials/visualize_cliques/visualize_cliques.rst b/doc/source/tutorials/visualize_cliques/visualize_cliques.rst index b2ac037fd..55b3c9dce 100644 --- a/doc/source/tutorials/visualize_cliques/visualize_cliques.rst +++ b/doc/source/tutorials/visualize_cliques/visualize_cliques.rst @@ -6,11 +6,7 @@ Cliques ============ -.. _cliques: https://igraph.org/python/doc/api/igraph._igraph.GraphBase.html#cliques -.. |cliques| replace:: :meth:`cliques` - -This example shows how to compute and visualize cliques of a graph using |cliques|_. - +This example shows how to compute and visualize cliques of a graph using :meth:`igraph.GraphBase.cliques`. .. code-block:: python diff --git a/doc/source/visualisation.rst b/doc/source/visualisation.rst index e766a1cd3..8d2274cff 100644 --- a/doc/source/visualisation.rst +++ b/doc/source/visualisation.rst @@ -11,7 +11,7 @@ In the following examples, we will assume |igraph| is imported as `ig` and a >>> import igraph as ig >>> g = ig.Graph(edges=[[0, 1], [2, 3]]) -Read the `API documentation`_ for details on each function and class. The `tutorial`_ contains examples to get started. +Read the :doc:`api/index` for details on each function and class. See the :ref:`tutorial ` and the :doc:`gallery` for examples. Graph layouts ============= @@ -221,12 +221,10 @@ You can also specify vertex and edge color, size, and labels - and more - via ad ... edge_color=['black', 'grey'], ... ) -See the `tutorial`_ for examples and a full list of options. +See the :ref:`tutorial ` for examples and a full list of options. -.. _API documentation: https://igraph.org/python/api/latest/ .. _matplotlib: https://matplotlib.org .. _Jupyter: https://jupyter.org/ -.. _tutorial: https://igraph.org/python/doc/tutorial/tutorial.html#layouts-and-plotting .. _Cairo: https://www.cairographics.org .. _graphviz: http://www.graphviz.org .. _networkx: https://networkx.org/ diff --git a/scripts/mkdoc.sh b/scripts/mkdoc.sh index 0636e9de7..ef820ae95 100755 --- a/scripts/mkdoc.sh +++ b/scripts/mkdoc.sh @@ -12,8 +12,9 @@ set -e STANDALONE=0 SERVE=0 DOC2DASH=0 +LINKCHECK=0 -while getopts ":sjd" OPTION; do +while getopts ":sjdl" OPTION; do case $OPTION in s) STANDALONE=1 @@ -24,6 +25,9 @@ while getopts ":sjd" OPTION; do d) DOC2DASH=1 ;; + l) + LINKCHECK=1 + ;; \?) echo "Usage: $0 [-sjd]" exit 1 @@ -38,6 +42,7 @@ cd ${SCRIPTS_FOLDER}/.. ROOT_FOLDER=`pwd` DOC_SOURCE_FOLDER=${ROOT_FOLDER}/doc/source DOC_HTML_FOLDER=${ROOT_FOLDER}/doc/html +DOC_LINKCHECK_FOLDER=${ROOT_FOLDER}/doc/linkcheck SCRIPTS_FOLDER=${ROOT_FOLDER}/scripts cd ${ROOT_FOLDER} @@ -52,7 +57,7 @@ if [ ! -d ".venv" ]; then fi # Make sure that Sphinx, PyDoctor (and maybe doc2dash) are up-to-date in the virtualenv -.venv/bin/pip install -U sphinx pydoctor +.venv/bin/pip install -U sphinx pydoctor sphinxbootstrap4theme if [ x$DOC2DASH = x1 ]; then .venv/bin/pip install -U doc2dash fi @@ -74,15 +79,27 @@ echo "Patching modularized Graph methods" .venv/bin/python3 ${SCRIPTS_FOLDER}/patch_modularized_graph_methods.py -# Remove previous docs +echo "Clean previous docs" rm -rf "${DOC_HTML_FOLDER}" -# Make sphinx +if [ "x$LINKCHECK" = "x1" ]; then + echo "Check for broken links" + .venv/bin/python -m sphinx \ + -T \ + -b linkcheck \ + -Dtemplates_path='' \ + -Dhtml_theme='alabaster' \ + ${DOC_SOURCE_FOLDER} ${DOC_LINKCHECK_FOLDER} +fi + + echo "Generating HTML documentation..." if [ "x$STANDALONE" = "x1" ]; then echo "Build standalone docs" - .venv/bin/sphinx-build \ + .venv/bin/python -m sphinx \ + -T \ + -b html \ -Dtemplates_path='' \ -Dhtml_theme='alabaster' \ ${DOC_SOURCE_FOLDER} ${DOC_HTML_FOLDER} diff --git a/scripts/rtd_prebuild.sh b/scripts/rtd_prebuild.sh new file mode 100755 index 000000000..b35e22f0a --- /dev/null +++ b/scripts/rtd_prebuild.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +echo "Compile and install igraph into venv. This might take a few minutes..." +/home/docs/checkouts/readthedocs.org/user_builds/igraph/envs/${READTHEDOCS_VERSION}/bin/pip wheel -q -w dist . +/home/docs/checkouts/readthedocs.org/user_builds/igraph/envs/${READTHEDOCS_VERSION}/bin/pip install -q --force-reinstall dist/*.whl + +echo "Modularize pure Python modules" +/home/docs/checkouts/readthedocs.org/user_builds/igraph/envs/${READTHEDOCS_VERSION}/bin/python3 scripts/patch_modularized_graph_methods.py + +echo "NOTE: Patch pydoctor to trigger build-finished before RTD extension" +# see https://www.sphinx-doc.org/en/master/extdev/appapi.html#sphinx.application.Sphinx.connect +# see also https://github.com/readthedocs/readthedocs.org/pull/4054 - might or might not be exactly what we are seeing here +sed -i 's/on_build_finished)/on_build_finished, priority=490)/' /home/docs/checkouts/readthedocs.org/user_builds/igraph/envs/${READTHEDOCS_VERSION}/lib/python3.9/site-packages/pydoctor/sphinx_ext/build_apidocs.py diff --git a/src/_igraph/graphobject.c b/src/_igraph/graphobject.c index d55122b5a..5453ef4d3 100644 --- a/src/_igraph/graphobject.c +++ b/src/_igraph/graphobject.c @@ -7912,13 +7912,13 @@ PyObject *igraphmodule_Graph_layout_sugiyama( return (PyObject *) result_o; } - /** \ingroup python_interface_graph - * \brief Places the vertices of a graph using Uniform Manifold Approximation and Projection (UMAP) +/** \ingroup python_interface_graph + * \brief Uniform Manifold Approximation and Projection (UMAP) * \return the calculated coordinates as a Python list of lists * \sa igraph_layout_umap */ -PyObject *igraphmodule_Graph_layout_umap(igraphmodule_GraphObject * self, - PyObject * args, PyObject * kwds) +PyObject *igraphmodule_Graph_layout_umap( + igraphmodule_GraphObject * self, PyObject * args, PyObject * kwds) { static char *kwlist[] = { "dist", "dim", "seed", "min_dist", "epochs", "sampling_prob", NULL }; @@ -15429,7 +15429,9 @@ struct PyMethodDef igraphmodule_Graph_methods[] = { {"layout_umap", (PyCFunction) igraphmodule_Graph_layout_umap, METH_VARARGS | METH_KEYWORDS, - "layout_umap(dist=None, dim=2, seed=None, min_dist=0.01, epochs=500, sampling_prob=0.3)\n--\n\n" + "layout_umap(\n" + " dist=None, dim=2, seed=None, min_dist=0.01,\n" + " epochs=500, sampling_prob=0.3)\n--\n\n" "Uniform Manifold Approximation and Projection (UMAP).\n\n" "This layout is a probabilistic algorithm that places vertices that are connected\n" "and have a short distance close by in the embedded space.\n\n" @@ -15443,16 +15445,16 @@ struct PyMethodDef igraphmodule_Graph_methods[] = { "@param min_dist: the minimal distance in the embedded space beyond which the\n" " probability of being located closeby decreases.\n" "@param epochs: the number of epochs (iterations) the algorithm will iterate\n" - " over. Accuracy increases with more epochs, at the cost of longer\n " - " runtimes. Values between 50 and 1000 are typical.\n" - " Notice that UMAP does not technically converge for symmetry reasons, but a \n" + " over. Accuracy increases with more epochs, at the cost of longer runtimes.\n" + " Values between 50 and 1000 are typical.\n" + " Notice that UMAP does not technically converge for symmetry reasons, but a\n" " larger number of epochs should generally give an equivalent or better layout.\n" "@param sampling_prob: the probability of sampling each vertex for repulsion at\n" " each epoch or iteration. A higher probability will give better results but\n" " also require more computations.\n" "@return: the calculated layout.\n\n" "@newfield ref: Reference\n" - "@ref: L McInnes, J Healy, J Melville: UMAP: Uniform Manifold Approximation \n" + "@ref: L McInnes, J Healy, J Melville: UMAP: Uniform Manifold Approximation\n" " and Projection for Dimension Reduction. arXiv:1802.03426."}, ////////////////////////////