Skip to content

Commit 44f59c1

Browse files
committed
Make rel_dfs of from_dfs optional
1 parent e6ffd44 commit 44f59c1

File tree

3 files changed

+51
-7
lines changed

3 files changed

+51
-7
lines changed

changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
## New features
1010

1111
* Allow passing a `neo4j.Driver` instance as input to `from_neo4j`, in which case the driver will be used internally to fetch the graph data using a simple query
12+
* The `rel_dfs` parameter of `from_dfs` is now optional, allowing for loading a graph with only nodes and no relationships
1213

1314

1415
## Bug fixes

python-wrapper/src/neo4j_viz/pandas.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,19 @@ def _parse_validation_error(e: ValidationError, entity_type: type[BaseModel]) ->
2727

2828

2929
def _from_dfs(
30-
node_dfs: Optional[DFS_TYPE],
31-
rel_dfs: DFS_TYPE,
30+
node_dfs: Optional[DFS_TYPE] = None,
31+
rel_dfs: Optional[DFS_TYPE] = None,
3232
node_radius_min_max: Optional[tuple[float, float]] = (3, 60),
3333
rename_properties: Optional[dict[str, str]] = None,
3434
dropna: bool = False,
3535
) -> VisualizationGraph:
36-
relationships = _parse_relationships(rel_dfs, rename_properties=rename_properties, dropna=dropna)
36+
if node_dfs is None and rel_dfs is None:
37+
raise ValueError("At least one of `node_dfs` or `rel_dfs` must be provided")
38+
39+
if rel_dfs is None:
40+
relationships = []
41+
else:
42+
relationships = _parse_relationships(rel_dfs, rename_properties=rename_properties, dropna=dropna)
3743

3844
if node_dfs is None:
3945
has_size = False
@@ -124,8 +130,8 @@ def _parse_relationships(
124130

125131

126132
def from_dfs(
127-
node_dfs: Optional[DFS_TYPE],
128-
rel_dfs: DFS_TYPE,
133+
node_dfs: Optional[DFS_TYPE] = None,
134+
rel_dfs: Optional[DFS_TYPE] = None,
129135
node_radius_min_max: Optional[tuple[float, float]] = (3, 60),
130136
) -> VisualizationGraph:
131137
"""
@@ -137,11 +143,12 @@ def from_dfs(
137143
138144
Parameters
139145
----------
140-
node_dfs: Optional[Union[DataFrame, Iterable[DataFrame]]]
146+
node_dfs: Optional[Union[DataFrame, Iterable[DataFrame]]], optional
141147
DataFrame or iterable of DataFrames containing node data.
142148
If None, the nodes will be created from the source and target node ids in the rel_dfs.
143-
rel_dfs: Union[DataFrame, Iterable[DataFrame]]
149+
rel_dfs: Optional[Union[DataFrame, Iterable[DataFrame]]], optional
144150
DataFrame or iterable of DataFrames containing relationship data.
151+
If None, no relationships will be created.
145152
node_radius_min_max : tuple[float, float], optional
146153
Minimum and maximum node radius.
147154
To avoid tiny or huge nodes in the visualization, the node sizes are scaled to fit in the given range.

python-wrapper/tests/test_pandas.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,3 +190,39 @@ def test_rel_errors() -> None:
190190
match=r"Error for relationship column 'caption_size' with provided input '-300.0'. Reason: Input should be greater than 0",
191191
):
192192
from_dfs(nodes, relationships)
193+
194+
195+
def test_from_dfs_no_rels() -> None:
196+
nodes = [
197+
DataFrame(
198+
{
199+
"id": [0],
200+
"caption": ["A"],
201+
"size": [1337],
202+
"color": "#FF0000",
203+
}
204+
),
205+
DataFrame(
206+
{
207+
"id": [1],
208+
"caption": ["B"],
209+
"size": [42],
210+
"color": "#FF0000",
211+
}
212+
),
213+
]
214+
VG = from_dfs(nodes, [], node_radius_min_max=(42, 1337))
215+
216+
assert len(VG.nodes) == 2
217+
218+
assert VG.nodes[0].id == 0
219+
assert VG.nodes[0].caption == "A"
220+
assert VG.nodes[0].size == 1337
221+
assert VG.nodes[0].color == Color("#ff0000")
222+
223+
assert VG.nodes[1].id == 1
224+
assert VG.nodes[1].caption == "B"
225+
assert VG.nodes[1].size == 42
226+
assert VG.nodes[0].color == Color("#ff0000")
227+
228+
assert len(VG.relationships) == 0

0 commit comments

Comments
 (0)