Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 145 additions & 0 deletions docs/source/adjusting.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
Adjusting the visualization
===========================

Once created, a :doc:`VisualizationGraph object <./api-reference/visualization-graph>` can be modified in various ways
to adjust what the visualization looks like the next time you render it.
In this section we will discuss how to color, size, and pin nodes, as well as how to directly modify nodes and
relationships of existing ``VisualizationGraph`` objects.

If you have not yet created a ``VisualizationGraph`` object, please refer to one of the following sections:

* :doc:`Getting started <./getting-started>` for creating a visualization graph from scratch using ``neo4j-viz``
primitives like :doc:`Node <./api-reference/node>` and :doc:`Relationship <./api-reference/relationship>` and
:doc:`VisualizationGraph <./api-reference/visualization-graph>` directly. Or
* :doc:`Integration with other libraries <./integration>` for importing data from a Pandas DataFrame or Neo4j GDS
projection.


Coloring nodes
--------------

Nodes can be colored directly by providing them with a color property, upon creation.
This can for example be done by passing a color as a string to the ``color`` parameter of the
:doc:`Node <./api-reference/node>` object.

Alternatively, you can color nodes based on a property (field) of the nodes after a ``VisualizationGraph`` object has been
created.


The ``color_nodes`` method
~~~~~~~~~~~~~~~~~~~~~~~~~~

By calling the :meth:`neo4j_viz.VisualizationGraph.color_nodes` method, you can color nodes based on a
node property (field).
This method will give a distinct color (if possible) to each unique value of the node ``property`` that you provide as
the first positional argument.

By default the Neo4j color palette that works for both light and dark mode will be used.
If you want to use a different color palette, you can pass a dictionary or iterable of colors as the ``colors``
parameter.
You can for example use the color palettes from the `palettable library <https://jiffyclub.github.io/palettable/>`_ as in
the following example:

.. code-block:: python

from palettable.wesanderson import Moonrise1_5

# VG is a VisualizationGraph object
VG.color_nodes("caption", Moonrise1_5.colors)

In this case, all nodes with the same caption will get the same color.

If there are fewer colors that unique values for the node ``property`` provided, the colors will be reused in a cycle.
To avoid that, you could use another palette or extend one with additional colors. Please refer to the
:doc:`Visualizing Neo4j Graph Data Science (GDS) Graphs tutorial <./tutorials/gds-nvl-example>` for an example on how
to do the latter.

If some nodes already have a ``color`` set, you can choose whether or not to override it with the ``override``
parameter.


Sizing nodes
--------------

Nodes can be given a size directly by providing them with a size property, upon creation.
This can for example be done by passing a size as an integer to the ``size`` parameter of the
:doc:`Node <./api-reference/node>` object.

Alternatively, you can size nodes after a ``VisualizationGraph`` object has been created.


The ``resize_nodes`` method
~~~~~~~~~~~~~~~~~~~~~~~~~~~

By calling the :meth:`neo4j_viz.VisualizationGraph.resize_nodes` method, you can resize nodes by:

* passing new nodes sizes as a dictionary ``sizes``, mapping node IDs to sizes in pixels, or
* providing a tuple of two numbers ``node_radius_min_max``: minimum and maximum radii (sizes) in pixels to which the
nodes will be scaled.

Or you could provide both ``sizes`` and ``node_radius_min_max``, in which case the dictionary will be used to first set
the sizes of the nodes, and then the minimum and maximum values of the tuple will be subsequently used to scale the
sizes to the provided range.

If you provide only the ``node_radius_min_max`` parameter, the sizes of the nodes will be scaled such that the smallest
node will have the size of the first value, and the largest node will have the size of the second value.
The other nodes will be scaled linearly between these two values according to their relative size.
This can be useful if node sizes vary a lot, or are all very small or very big.

In the following example, we resize the node with ID 42 to have a size of 88 pixels, and then scales all nodes to have
sizes between 5 and 20 pixels:

.. code-block:: python

# VG is a VisualizationGraph object
VG.resize_nodes(sizes={42: 88}, node_radius_min_max=(5, 20))

Please note that means that also the node with ID 42 will be scaled to be between 5 and 20 pixels in size.


Pinning nodes
-------------

Nodes can be pinned to their current position in the visualization, so that they will not be moved by the force-directed
layout algorithm.
This can be useful if you want to keep a node in a specific position, for example to highlight it.

Nodes can be pinned directly upon creation.
This can for example be done by passing ``pinned=True`` to the :doc:`Node <./api-reference/node>` object.

Alternatively, you can toggle node pinning after a ``VisualizationGraph`` object has been created.


The ``toggle_nodes_pinned`` method
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

By calling the :meth:`neo4j_viz.VisualizationGraph.toggle_nodes_pinned` method, you can toggle whether nodes should be
pinned or not.
This method takes dictionary that maps node IDs to boolean values, where ``True`` means that the node is pinned, and
``False`` means that the node is not pinned.

In the following example, we pin the node with ID 1337 and unpin the node with ID 42:

.. code-block:: python

# VG is a VisualizationGraph object
VG.toggle_nodes_pinned(1337: True, 42: False)})


Direct modification of nodes and relationships
----------------------------------------------

Nodes and relationships can also be modified directly by accessing the ``nodes`` and ``relationships`` attributes of an
existing ``VisualizationGraph`` object.
These attributes list of all the :doc:`Nodes <./api-reference/node>` and
:doc:`Relationships <./api-reference/relationship>` in the graph, respectively.

Each node and relationship has attributes that can be accessed and modified directly, as in the following example:

.. code-block:: python

# VG is a VisualizationGraph object
VG.nodes[0].size = 10
VG.relationships[4].caption = "BUYS"

Any changes made to the nodes and relationships will be reflected in the next rendering of the graph.
4 changes: 2 additions & 2 deletions docs/source/api-reference/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.

API Reference
API reference
=====================================================

This is an API reference for the `neo4j-viz` library.
This is an API reference for the ``neo4j-viz`` library.


.. toctree::
Expand Down
8 changes: 6 additions & 2 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ Graph Visualization for Python by Neo4j documentation
This is the documentation for the ``neo4j-viz`` Python library by Neo4j.
The library allows you to visualize graph data interactively in Python using a simple API.

The library wraps the `Neo4j Visualization JavaScript library (NVL) <https://neo4j.com/docs/nvl/current/>`_, and provides additional features for working with graph data in Python.
Notably, there are convenience methods for importing data from `Pandas DataFrames <https://pandas.pydata.org/>`_ and `Neo4j Graph Data Science <https://neo4j.com/docs/graph-data-science/current/>`_.
The library wraps the `Neo4j Visualization JavaScript library (NVL) <https://neo4j.com/docs/nvl/current/>`_, and
provides additional features for working with graph data in Python.
Notably, there are convenience methods for importing data from `Pandas DataFrames <https://pandas.pydata.org/>`_ and
`Neo4j Graph Data Science <https://neo4j.com/docs/graph-data-science/current/>`_.


.. toctree::
Expand All @@ -20,5 +22,7 @@ Notably, there are convenience methods for importing data from `Pandas DataFrame
installation.rst
getting-started.nblink
integration.rst
rendering.rst
adjusting.rst
api-reference/index.rst
tutorials/index.rst
8 changes: 4 additions & 4 deletions docs/source/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ Optional dependencies
In addition, there are a few optional dependencies that you can install to enable additional features of the library.


Pandas `from_dfs` importer
~~~~~~~~~~~~~~~~~~~~~~~~~~
Pandas DataFrames ``from_dfs`` importer
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To install the additional dependencies required for the :doc:`from_dfs importer <./api-reference/from_pandas>` you can run:

Expand All @@ -25,8 +25,8 @@ To install the additional dependencies required for the :doc:`from_dfs importer
pip install neo4j-viz[pandas]


Neo4j Graph Data Science `from_gds` importer
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Neo4j Graph Data Science ``from_gds`` importer
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To install the additional dependencies required for the :doc:`from_gds importer <./api-reference/from_gds>` you can run:

Expand Down
31 changes: 19 additions & 12 deletions docs/source/integration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,20 @@ The ``from_dfs`` method takes two mandatory positional parameters:

* A Pandas ``DataFrame``, or iterable (eg. list) of DataFrames representing the nodes of the graph.
The rows of the DataFrame(s) should represent the individual nodes, and the columns should represent the node
IDs and properties. The columns map directly to fields on :doc:`Nodes <./api-reference/node>`, and as such
IDs and properties. The columns map directly to fields of :doc:`Node <./api-reference/node>`, and as such
should follow the same naming conventions.
* A Pandas ``DataFrame``, or iterable (eg. list) of DataFrames representing the relationships of the graph.
The rows of the DataFrame(s) should represent the individual relationships, and the columns should represent the
relationship IDs and properties. The columns map directly to fields on
:doc:`Relationships <./api-reference/relationship>`, and as such should follow the same naming conventions.
relationship IDs and properties. The columns map directly to fields of
:doc:`Relationship <./api-reference/relationship>`, and as such should follow the same naming conventions.

``from_dfs`` also takes an optional property, ``node_radius_min_max``, can be used (and is used by default) to scale
the node sizes for the visualization.
It is a tuple of two floats, representing the radii (sizes) in pixels of the smallest and largest nodes respectively in
``from_dfs`` also takes an optional property, ``node_radius_min_max``, that can be used (and is used by default) to
scale the node sizes for the visualization.
It is a tuple of two numbers, representing the radii (sizes) in pixels of the smallest and largest nodes respectively in
the visualization.
The node sizes will be scaled such that the smallest node will have the size of the first value, and the largest node
will have the size of the second value.
The other nodes will be scaled linearly between these two values according to their relative size.
This can be useful if node sizes vary a lot, or are all very small or very big.


Expand All @@ -43,9 +46,10 @@ Example

In this small example, we import a tiny toy graph representing a social network from two Pandas DataFrames.
As we can see the column names of the DataFrames map directly to the fields of :doc:`Nodes <./api-reference/node>`
and :d
and :doc:`Relationships <./api-reference/relationship>`.

.. code-block:: python

from pandas import DataFrame
from neo4j_viz.pandas import from_dfs

Expand Down Expand Up @@ -85,17 +89,20 @@ The ``from_gds`` method takes two mandatory positional parameters:
* An initialized ``GraphDataScience`` object for the connection to the GDS instance, and
* A ``Graph`` representing the projection that one wants to import.

We can also provide an optional ``size_property`` parameter, which should refer to a node property of the projection, and
will be used to determine the size of the nodes in the visualization.
We can also provide an optional ``size_property`` parameter, which should refer to a node property of the projection,
and will be used to determine the size of the nodes in the visualization.

The ``additional_node_properties`` parameter is also optional, and should be a list of additional node properties of the
projection that you want to include in the visualization.
For example, these properties could be used to color the nodes, or give captions to them in the visualization.

The last optional property, ``node_radius_min_max``, can be used (and is used by default) to scale the node sizes for the
visualization.
It is a tuple of two floats, representing the radii (sizes) in pixels of the smallest and largest nodes respectively in
The last optional property, ``node_radius_min_max``, can be used (and is used by default) to scale the node sizes for
the visualization.
It is a tuple of two numbers, representing the radii (sizes) in pixels of the smallest and largest nodes respectively in
the visualization.
The node sizes will be scaled such that the smallest node will have the size of the first value, and the largest node
will have the size of the second value.
The other nodes will be scaled linearly between these two values according to their relative size.
This can be useful if node sizes vary a lot, or are all very small or very big.


Expand Down
47 changes: 47 additions & 0 deletions docs/source/rendering.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
Rendering a graph
=================

In this section, we will discuss how to render a :doc:`VisualizationGraph object <./api-reference/visualization-graph>`
to display the graph visualization.

If you have not yet created a ``VisualizationGraph`` object, please refer to one of the following sections:

* :doc:`Getting started <./getting-started>` for creating a visualization graph from scratch using ``neo4j-viz``
primitives like :doc:`Node <./api-reference/node>` and :doc:`Relationship <./api-reference/relationship>` and
:doc:`VisualizationGraph <./api-reference/visualization-graph>` directly. Or
* :doc:`Integration with other libraries <./integration>` for importing data from a Pandas DataFrame or Neo4j GDS
projection.


The ``render`` method
---------------------

Once you have a ``VisualizationGraph`` object, you can render it using the ``render`` method.
This will return a HTML object that will be displayed in an environment that supports HTML rendering, such as
Jupyter notebooks or streamlit.

All parameter of the ``render`` method are optional, and the full list of parameters of them is listed in the API
reference: :meth:`neo4j_viz.VisualizationGraph.render`.

The most important parameters to be aware of are the ``width`` and ``height`` parameters, which control the size of
HTML object that will be rendered.
You can provide these either as a percentage of the available space (eg. ``"80%"``), or as an absolute pixel value
(eg. ``"800px"``).

Further you can change the layout of the graph using the ``layout`` parameter, which can be set to one of the following values:
* ``Layout.FORCE_DIRECTED`` - Nodes are arranged using the Force-Directed algorithm, which simulates physical forces
* ``Layout.HIERARCHICAL`` - Arranges nodes by the directionality of their relationships, creating a tree-like structure
* ``Layout.COORDINATE`` - Arranges nodes based on coordinates defined in `x` and `y` properties on each node.

Another thing of note is the ``max_allowed_nodes`` parameter, which controls the maximum number of nodes that is allowed
for the graph to contain in order to be rendered.
It defaults to 10.000, because rendering a large number of nodes can be slow and unresponsive.
However, you can increase this value if you are confident that your environment can handle the scale.
In this case you might also want to pass ``Renderer.WEB_GL`` as the ``renderer`` to improve performance.


Examples
--------
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Layout could be useful to mention as well

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think I understand the layouts well enough to write that. You can if you want perhaps?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I gave it a try


Please refer to the :doc:`Getting started section <./getting-started>` and the :doc:`tutorials <./tutorials/index>` for
examples of ``render`` method usage.