Skip to content

Commit 53ec414

Browse files
committed
Make rel_dfs of from_dfs optional
1 parent 4677de6 commit 53ec414

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
@@ -10,6 +10,7 @@
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
1212
* Added optional argument `dropna` to `from_dfs` loader allowing for not including NaN properties in the created visualization graph
13+
* The `rel_dfs` parameter of `from_dfs` is now optional, allowing for loading a graph with only nodes and no relationships
1314

1415

1516
## 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
dropna: bool = False,
131137
) -> VisualizationGraph:
@@ -138,11 +144,12 @@ def from_dfs(
138144
139145
Parameters
140146
----------
141-
node_dfs: Optional[Union[DataFrame, Iterable[DataFrame]]]
147+
node_dfs: Optional[Union[DataFrame, Iterable[DataFrame]]], optional
142148
DataFrame or iterable of DataFrames containing node data.
143149
If None, the nodes will be created from the source and target node ids in the rel_dfs.
144-
rel_dfs: Union[DataFrame, Iterable[DataFrame]]
150+
rel_dfs: Optional[Union[DataFrame, Iterable[DataFrame]]], optional
145151
DataFrame or iterable of DataFrames containing relationship data.
152+
If None, no relationships will be created.
146153
node_radius_min_max : tuple[float, float], optional
147154
Minimum and maximum node radius.
148155
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)