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
4 changes: 4 additions & 0 deletions docs/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
build

# Antora docs
antora/package-lock.json
antora/node_modules/
7 changes: 3 additions & 4 deletions docs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXOPTS ?= -b dirhtml
SPHINXBUILD ?= sphinx-build
SOURCEDIR = source
BUILDDIR = build
Expand All @@ -14,7 +14,6 @@ help:

.PHONY: help Makefile

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
# Use this format to make use of the "-b dirhtml" switch
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
@$(SPHINXBUILD) $(SPHINXOPTS) "$(SOURCEDIR)" "$(BUILDDIR)"
12 changes: 12 additions & 0 deletions docs/antora/antora.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: python-graph-visualization
title: Neo4j Python Graph Visualization
version: '1'
start_page: ROOT:index.adoc
nav:
- modules/ROOT/content-nav.adoc
asciidoc:
attributes:
# Version needs to be updated manually for now
docs-version: '1'
api-docs-uri: '{neo4j-docs-base-uri}/python-graph-visualization/{docs-version}/reference/api-reference'
tutorials-docs-uri: '{neo4j-docs-base-uri}/python-graph-visualization/{docs-version}/reference/tutorials'
8 changes: 8 additions & 0 deletions docs/antora/modules/ROOT/content-nav.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
* xref:index.adoc[]
* xref:installation.adoc[]
* xref:getting-started.adoc[]
* xref:integration.adoc[]
* xref:rendering.adoc[]
* xref:customizing.adoc[]
* link:{tutorials-docs-uri}[Tutorials]
* link:{api-docs-uri}[API reference]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
222 changes: 222 additions & 0 deletions docs/antora/modules/ROOT/pages/customizing.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
= Customizing the visualization

Once created, a link:{api-docs-uri}/visualization-graph[`VisualizationGraph` object] 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, refer to one of the following sections:

* xref:getting-started.adoc[Getting started] for creating a visualization graph from scratch using `neo4j-viz`
primitives like link:{api-docs-uri}/node/[Node] and link:{api-docs-uri}/relationship/[Relationship] and
link:{api-docs-uri}/visualization-graph[`VisualizationGraph`] directly.
* xref:integration.adoc[] for importing data from a Pandas DataFrame or Neo4j GDS projection.

== Setting node captions

Node captions are the text labels displayed on nodes in the visualization.

=== The `set_node_captions` method

By calling the `neo4j_viz.VisualizationGraph.set_node_captions()` method, you can set node captions based on a node field (like `id`, `size`, etc.) or a node property (members of the `Node.properties` map).

The method accepts an `override` parameter (default `True`) that controls whether to replace existing captions.
If `override=False`, only nodes without captions will be updated.

Here is an example of setting node captions from a property:

[source, python]
----
# VG is a VisualizationGraph object with nodes that have a "name" property
VG.set_node_captions(property="name")
----

You can also set captions from a node field, and choose not to override existing captions:

[source, python]
----
# VG is a VisualizationGraph object
VG.set_node_captions(field="id", override=False)
----

For more complex scenarios where you need fallback logic or want to combine multiple properties, you can iterate over nodes directly:

[source, python]
----
# VG is a VisualizationGraph object
for node in VG.nodes:
caption = node.properties.get("name") or node.properties.get("title") or node.id
node.caption = str(caption)
----

== Coloring nodes

Nodes can be colored directly by providing them with a color field, upon creation.
This can for example be done by passing a color as a string to the `color` parameter of the
link:{api-docs-uri}/node[Node] object.

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

=== The `color_nodes` method

By calling the link:{api-docs-uri}/visualization-graph/#neo4j_viz.VisualizationGraph.color_nodes[`neo4j_viz.VisualizationGraph.color_nodes()`] method, you can color nodes based on a node field or property (members of the `Node.properties` map).

It's possible to color the nodes based on a discrete or continuous color space (see link:{api-docs-uri}/colors[`ColorSpace`]).
In the discrete case, a new color from the `colors` provided is assigned to each unique value of the node field/property.
In the continuous case, the `colors` should be a list of colors representing a range that are used to
create a gradient of colors based on the values of the node field/property.

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.
A color value can for example be either strings like "blue", or hexadecimal color codes like "#FF0000", or even a tuple of RGB values like (255, 0, 255).

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

==== By discrete color space

To not use the default colors, we can provide a list of custom colors based on the discrete node field "caption" to the `color_nodes` method:

[source, python]
----
from neo4j_viz.colors import ColorSpace

# VG is a VisualizationGraph object
VG.color_nodes(
field="caption",
["red", "#7fffd4", (255, 255, 255, 0.5), "hsl(270, 60%, 70%)"],
color_space=ColorSpace.DISCRETE
)
----

The full set of allowed values for colors are listed link:https://docs.pydantic.dev/2.0/usage/types/extra_types/color_types/[here].

Instead of defining your own colors, you could also for example use the color palettes from the link:https://jiffyclub.github.io/palettable/[`palettable` library] as in this snippet:

[source, python]
----
from palettable.wesanderson import Moonrise1_5

# VG is a VisualizationGraph object
VG.color_nodes(field="caption", Moonrise1_5.colors) # PropertyType.DISCRETE is default
----

In theses cases, all nodes with the same caption will get the same color.

If there are fewer colors than unique values for the node `field` or `property` provided, the colors will be reused in a cycle.
To avoid that, you could use a larger palette or extend one with additional colors.
Refer to the link:/tutorials/gds-example[Visualizing Neo4j Graph Data Science (GDS) Graphs tutorial] for an example on how
to do the latter.

==== By continuous color space

To not use the default colors, we can provide a list of custom colors representing a range to the `color_nodes` method:

[source, python]
----
from neo4j_viz.colors import PropertyType

# VG is a VisualizationGraph object
VG.color_nodes(
property="centrality_score",
[(255, 0, 0), (191, 64, 0), (128, 128, 0), (64, 191, 0), (0, 255, 0)] # From red to green
color_space=ColorSpace.CONTINUOUS
)
----

In this case, the nodes will be colored based on the value of the "centrality_score" property, with the lowest values being colored red and the highest values being colored green.
Since we only provided five colors in the range, the granularity of the gradient will be limited to five steps.

`palettable` and `matplotlib` are great libraries to use to create custom color gradients.

== Sizing nodes

Nodes can be given a size directly by providing them with a size field, upon creation.
This can for example be done by passing a size as an integer to the `size` parameter of the link:{api-docs-uri}/node[Node] object.

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

=== The `resize_nodes` method

By calling the link:{api-docs-uri}/visualization-graph/#neo4j_viz.VisualizationGraph.resize_nodes[`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:

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

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 link:{api-docs-uri}/node[Node] object.

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

=== The `toggle_nodes_pinned` method

By calling the link:{api-docs-uri}/visualization-graph/#neo4j_viz.VisualizationGraph.toggle_nodes_pinned[`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:

[source, 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` fields of an
existing `VisualizationGraph` object.
These fields list of all the link:{api-docs-uri}/node[Nodes] and link:{api-docs-uri}/relationship[Relationships] in the graph, respectively.

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

[source, python]
----
# VG is a VisualizationGraph object

# Modify the first node and fifth relationship
VG.nodes[0].size = 10
VG.nodes[0].properties["height"] = 170
VG.relationships[4].caption = "BUYS"

# Set the coordinates for all nodes from an existing property
for node in VG.nodes:
node.x = node.properties.get("x")
node.y = node.properties.get("y")

# Change the caption size for all relationships
for relationship in VG.relationships:
relationship.caption_size = 15
----

Any changes made to the nodes and relationships will be reflected in the next rendering of the graph.
91 changes: 91 additions & 0 deletions docs/antora/modules/ROOT/pages/getting-started.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
= Getting started

In this section, we will cover the very basics of creating a visualization graph using the `neo4j-viz` library.
We will use a small toy graph representing the purchase history of a few people and products.

To follow along with the example below, please make sure you have xref:installation.adoc[installed the library] first.

We start by instantiating the link:{api-docs-uri}/node/[Nodes] and link:{api-docs-uri}/relationship[Relationships] we want in our graph.
The only mandatory fields for a node are the “id”, and “source” and “target” for a relationship.
But the other fields can optionally be used to customize the appearance of the nodes and relationships in the visualization.

Lastly we create a link:{api-docs-uri}/visualization-graph/[VisualizationGraph] object with the nodes and relationships we created, and call its `render` method to display the graph.

[source, python, role=nocollapse]
----
from neo4j_viz import Node, Relationship, VisualizationGraph

nodes = [
Node(id=0, size=10, caption="Person"),
Node(id=1, size=10, caption="Product"),
Node(id=2, size=20, caption="Product"),
Node(id=3, size=10, caption="Person"),
Node(id=4, size=10, caption="Product"),
]

relationships = [
Relationship(
source=0,
target=1,
caption="BUYS",
),
Relationship(
source=0,
target=2,
caption="BUYS",
),
Relationship(
source=3,
target=2,
caption="BUYS",
),
]

VG = VisualizationGraph(nodes=nodes, relationships=relationships)

VG.render(initial_zoom=2)
----

[TIP]
====
See the link:{tutorials-docs-uri}/getting-started/[Jupyter notebook] to interact with the graph.
====

image::graph_2120034f.png["Graph"]

As we can see in the graph above, the radius of one of the nodes is larger than the others.
This is because we set the “size” field of the node to 20, while the others are set to 10.

At this time all nodes have the same color.
If we want to distinguish between the different types of nodes, we can color them differently with the `color_nodes` method.
We can pass the field we want to use to color the nodes as an argument.
In this case, we will use the "caption" field.
Nodes with the same "caption" will have the same color.
We will use the default color scheme, which is the Neo4j color scheme.

[source, python]
----
VG.color_nodes(field="caption")

VG.render(initial_zoom=2)
----

[TIP]
====
See the link:{tutorials-docs-uri}/getting-started/[Jupyter notebook] to interact with the graph.
====

image::graph_00ff5513.png["Graph with colors"]

We are now easily able to distinguish between the different types of nodes in the graph.

== Next steps

Now that we have covered the basics of creating and rendering a visualization graph, we can move on to more advanced topics.

Here are some suggestions for what to do next:

* Browse the link:{tutorials-docs-uri}[notebook examples] for more examples and use cases
* Learn about the xref:integration.adoc[integrations] with other libraries such as Neo4j GDS and Pandas
* Check out the xref:rendering.adoc[rendering options] and convenience methods of `VisualizationGraph`
* Read about our link:{api-docs-uri}/[API reference]
10 changes: 10 additions & 0 deletions docs/antora/modules/ROOT/pages/index.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
= Introduction

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 link:https://neo4j.com/docs/nvl/current/[Neo4j Visualization JavaScript library (NVL)], and provides additional features for working with graph data in Python.
Notably, there are convenience methods for importing data from source such as link:https://pandas.pydata.org/[Pandas DataFrames], link:https://neo4j.com/docs/graph-data-science/current/[Neo4j Graph Data Science], link:https://neo4j.com/docs/python-manual/current/[Neo4j Database], and link:https://docs.snowflake.com/[Snowflake tables].

The source code is available on link:https://github.com/neo4j/python-graph-visualization[GitHub].
If you have a suggestion on how we can improve the library or want to report a problem, you can create a link:https://github.com/neo4j/python-graph-visualization/issues/new[new issue].
Loading