Skip to content

Commit 67858e2

Browse files
authored
[ENH] Export and import graph classes from other common interfaces (#60)
* Working export and unit-tests for common external packages --------- Signed-off-by: Adam Li <[email protected]>
1 parent 953ecdb commit 67858e2

28 files changed

+1098
-293
lines changed

.github/workflows/main.yml

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -152,40 +152,6 @@ jobs:
152152
files: ./coverage.xml
153153
fail_ci_if_error: true
154154
verbose: true
155-
156-
integration_test:
157-
timeout-minutes: 30
158-
strategy:
159-
fail-fast: false
160-
matrix:
161-
os: [ubuntu]
162-
python-version: ["3.10"] # oldest and newest supported versions
163-
poetry-version: [1.3.0]
164-
networkx: [stable, main]
165-
name: Integration-test ${{ matrix.os }} - py${{ matrix.python-version }} - Networkx ${{ matrix.networkx }}
166-
runs-on: ${{ matrix.os }}-latest
167-
defaults:
168-
run:
169-
shell: bash
170-
steps:
171-
- name: Checkout repository
172-
uses: actions/checkout@v3
173-
- name: Setup Python ${{ matrix.python-version }}
174-
uses: actions/setup-python@v4
175-
with:
176-
python-version: ${{ matrix.python-version }}
177-
architecture: 'x64'
178-
- name: Install Poetry ${{ matrix.poetry-version }}
179-
uses: abatilo/[email protected]
180-
with:
181-
poetry-version: ${{ matrix.poetry-version }}
182-
- name: Install Poetry Dynamic Versioning Plugin
183-
run: pip install poetry-dynamic-versioning
184-
- name: Install packages via poetry
185-
run: |
186-
poetry install --with test,ts
187-
- name: Run pytest # headless via Xvfb on linux
188-
run: poetry run poe integration_test
189155

190156
# release is ran when a release is made on Github
191157
release:

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ We use [Sphinx](https://www.sphinx-doc.org/en/master/index.html) to build our AP
138138
of public classes and methods. All docstrings should adhere to the [Numpy styling convention](https://www.sphinx-doc.org/en/master/usage/extensions/example_numpy.html).
139139

140140
### Testing Changes Locally With Poetry
141-
With poetry installed, we have included a few convenience functions to check your code. These checks must pass and will be checked by the PR's continuous integration services. You can install the various different developer dependencies with poetry:
141+
With poetry installed, we have included a few convenience functions to check your code. **These checks must pass** and will be checked by the PR's continuous integration services. You can install the various different developer dependencies with poetry:
142142

143143
poetry install --with style, docs, test
144144

README.md

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
[![Checked with mypy](http://www.mypy-lang.org/static/mypy_badge.svg)](http://mypy-lang.org/)
55
[![codecov](https://codecov.io/gh/py-why/pywhy-graphs/branch/main/graph/badge.svg?token=H1reh7Qwf4)](https://codecov.io/gh/py-why/pywhy-graphs)
66

7-
# PyWhy-Graphs (Experimental)
7+
# PyWhy-Graphs
88

9-
pywhy-graphs is a Python graph library that extends `MixedEdgeGraph` in [networkx](https://github.com/networkx/networkx) to implement a light-weight API for causal graphical structures.
9+
pywhy-graphs is a Python graph library that extends [networkx](https://github.com/networkx/networkx) with the notion of a `MixedEdgeGraph` to implement a light-weight API for causal graphical structures that contain mixed-edges and contain causal graph traversal algorithms.
1010

1111
Note: The API is subject to change without deprecation cycles due to the current work-in-progress `MixedEdgeGraph` class in networkx. For more information, follow the PR at https://github.com/networkx/networkx/pull/5947
1212

@@ -17,7 +17,15 @@ Representation of causal graphical models in Python are severely lacking.
1717
PyWhy-Graphs implements a graphical API layer for ADMG, CPDAG and PAG. For causal DAGs, we recommend using the `networkx.DiGraph` class and
1818
ensuring acylicity via `networkx.is_directed_acyclic_graph` function.
1919

20-
Existing packages that aim to represent causal graphs either break from the networkX API, or only implement a subset of the relevant causal graphs. By keeping in-line with the robust NetworkX API, we aim to ensure a consistent user experience and a gentle introduction to causal graphical models.
20+
Existing packages that aim to represent causal graphs either break from the networkX API, or only implement a subset of the relevant causal graphs. By keeping in-line with the robust NetworkX API, we aim to ensure a consistent user experience and a gentle introduction to causal graphical models. A `MixedEdgeGraph` instance is a composition of networkx graphs and has a similar API, with the additional notion of an "edge type", which specifies what edge type subgraph any function should operate over. For example:
21+
22+
```Python
23+
# adds a directed edge from x to y
24+
G.add_edge('x', 'y', edge_type='directed')
25+
26+
# adds a bidirected edge from x to y
27+
G.add_edge('x', 'y', edge_type='bidirected')
28+
```
2129

2230
Moreover, sampling from causal models is non-trivial, but a requirement for benchmarking many causal algorithms in discovery, ID, estimation and more. We aim to provide simulation modules that are easily connected with causal graphs to provide a simple robust API for modeling causal graphs and then simulating data.
2331

@@ -29,17 +37,19 @@ Or see [stable version documentation](https://py-why.github.io/pywhy-graphs/stab
2937

3038
# Installation
3139

32-
Installation is best done via `pip` or `conda`. For developers, they can also install from source using `pip`. See [installation page](TBD) for full details.
40+
Installation is best done via `pip` or `conda`. For developers, they can also install from source using `pip`. See [installation page](https://py-why.github.io/pywhy-graphs/dev/installation.html) for full details.
3341

3442
## Dependencies
3543

36-
Minimally, pywhy-graphs requires:
44+
We aim to provide a very light-weight dependency structure. Minimally, pywhy-graphs requires:
3745

3846
* Python (>=3.8)
3947
* numpy
4048
* scipy
4149
* networkx
4250

51+
Additional functionality may be required when running unit-tests and documentation.
52+
4353
## User Installation
4454

4555
If you already have a working installation of numpy, scipy and networkx, the easiest way to install pywhy-graphs is using `pip`:
@@ -58,3 +68,9 @@ To install the package from github, clone the repository and then `cd` into the
5868
pip install -e .
5969

6070
pip install https://api.github.com/repos/py-why/pywhy-graphs/zipball/main
71+
72+
# Contributing
73+
74+
Pywhy-Graphs is always looking for new contributors to help make the package better, whether it is algorithms, documentation, examples of graph usage, and more! Contributing to Pywhy-Graphs will be rewarding because you will contribute to a much needed package for causal inference.
75+
76+
See our [contributing guide](https://github.com/py-why/pywhy-graphs/CONTRIBUTING.md) for more details.

docs/api.rst

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,19 @@ implement various causal inference procedures, but encode a causal graph object
6363
differently. This submodule converts between those causal graph data structures
6464
and corresponding causal graphs in pywhy-graphs.
6565

66-
.. currentmodule:: pywhy_graphs.array
66+
.. currentmodule:: pywhy_graphs.export
6767

6868
.. autosummary::
6969
:toctree: generated/
7070

71-
graph_to_arr
72-
clearn_arr_to_graph
71+
graph_to_clearn
72+
clearn_to_graph
73+
graph_to_numpy
74+
numpy_to_graph
75+
graph_to_tetrad
76+
tetrad_to_graph
77+
graph_to_pcalg
78+
pcalg_to_graph
7379

7480
NetworkX Experimental Functionality
7581
===================================

docs/index.rst

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ algorithms and data structures of ``networkx``.
99
We encourage you to use the package for your causal inference research and also build on top
1010
with relevant Pull Requests. Also, see our `contributing guide <https://github.com/mne-tools/mne-icalabel/blob/main/CONTRIBUTING.md>`_.
1111

12-
See our examples for walk-throughs of how to use the package.
13-
1412
Please refer to our :ref:`user_guide` for details on all the tools that we
1513
provide. You can also find an exhaustive list of the public API in the
1614
:ref:`api_ref`. You can also look at our numerous :ref:`examples <general_examples>`
@@ -25,7 +23,6 @@ eventually converge to a stable API that maintains the common software engineeri
2523
will be marked as "alpha" indicating that their might be drastic changes over different releases.
2624
One should use alpha functionality with caution.
2725

28-
2926
Contents
3027
--------
3128

@@ -42,7 +39,12 @@ Contents
4239
Team
4340
----
4441

45-
**pywhy-graphs** is developed and maintained by pywhy.
42+
**pywhy-graphs** is developed and maintained by open-source contributors like yourself, and is always interested
43+
in getting contributions from YOU! Our Github Issues page contains many issues that need to be solved to
44+
improve the overall package. If you are interested in contributing, please do not hesitate to reach out to us on Github!
45+
46+
See our `contributing document <https://github.com/py-why/pywhy-graphs/CONTRIBUTING.md>`_ for details on our approach to Issues and Pull Requests.
47+
4648
To learn more about who specifically contributed to this codebase, see
4749
`our contributors <https://github.com/py-why/pywhy-graphs/graphs/contributors>`_ page.
4850

docs/reference/export/index.rst

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
.. _export:
2+
3+
**************************************************************************************
4+
Importing causal graphs to PyWhy-Graphs, or exporting PyWhy-Graphs to another package
5+
**************************************************************************************
6+
7+
.. automodule:: pywhy_graphs.export
8+
:no-members:
9+
:no-inherited-members:
10+
11+
Pywhy-graphs provides light-weight data structures and networkx-like methods for
12+
storing causal graphs.
13+
14+
The causality community is quite large and currently there is no de-facto standard
15+
for representing causal graphs with mixed edges. Therefore, we provide an interface
16+
for importing/exporting graphs from other packages.
17+
18+
We currently only offer support for a package if they have a way of representing
19+
all types of causal graphs (not just DAGs). We welcome contributions here!
20+
21+
Causal-Learn
22+
============
23+
Causal-learn maintains its own graph interpretation in the form of a structured
24+
upper-triangular numpy array.
25+
26+
.. currentmodule:: pywhy_graphs.export
27+
28+
.. autosummary::
29+
:toctree: ../../generated/
30+
31+
graph_to_clearn
32+
clearn_to_graph
33+
34+
Numpy (graphviz and dagitty)
35+
============================
36+
GraphViz stores a graph that allows mixed-edges using a numpy array with values filled
37+
in following a specific enumeration, so all values can be mapped to an edge, or multiple
38+
edges if more than one edge is allowed between nodes.
39+
40+
.. autosummary::
41+
:toctree: ../../generated/
42+
43+
graph_to_numpy
44+
numpy_to_graph
45+
46+
47+
PCAlg from R (Experimental)
48+
===========================
49+
``pcalg`` from R uses the following mapping for their array:
50+
51+
- 0: no edge
52+
- 1: -o
53+
- 2: -> (arrowhead)
54+
- 3: - (tail)
55+
56+
and stores a structured numpy array following this format. This functionality
57+
is experimental because this is not tested against the actual implementation in R.
58+
Please raise an issue if you encounter errors, or issues.
59+
60+
.. autosummary::
61+
:toctree: ../../generated/
62+
63+
graph_to_pcalg
64+
pcalg_to_graph
65+
66+
Tetrad from Java
67+
================
68+
``tetrad`` from Java uses the following mapping for their endpoints
69+
stored in a text file:
70+
71+
- TAIL = "-"
72+
- ARROW = ">"
73+
- CIRCLE = "o"
74+
75+
This functionality is experimental because this is not tested against the actual implementation in Java.
76+
Please raise an issue if you encounter errors, or issues.
77+
78+
.. autosummary::
79+
:toctree: ../../generated/
80+
81+
graph_to_tetrad
82+
tetrad_to_graph

docs/user_guide.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ User Guide
1414
:numbered:
1515
:maxdepth: 3
1616

17+
1718
reference/classes/index
1819
reference/simulation/index
20+
reference/export/index
1921
glossary

docs/whats_new/v0.1.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ Changelog
3939
- |Feature| Add :class:`pywhy_graphs.networkx.MixedEdgeGraph` for mixed-edge graphs, by `Adam Li`_ (:pr:`29`)
4040
- |MajorFeature| Implement a series of graph classes for time-series graphs, such as ``pywhy_graphs.classes.timeseries.StationaryTimeSeriesMixedEdgeGraph``, by `Adam Li`_ (:pr:`21`)
4141
- |MajorFeature| Implement a series of graph classes for modeling interventions, such as :class:`pywhy_graphs.AugmentedGraph`, by `Adam Li`_ (:pr:`49`)
42+
- |Feature| Implement export/import functions to go to/from pywhy-graphs to causallearn and to/from pywhy-graphs to numpy, by `Adam Li`_ (:pr:`51`)
43+
- |Feature| Implement export/import functions to go to/from pywhy-graphs to pcalg and tetrad, by `Adam Li`_ (:pr:`60`)
4244

4345
Code and Documentation Contributors
4446
-----------------------------------

pyproject.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,7 @@ _pydocstyle = 'pydocstyle .'
108108
_codespell = 'codespell pywhy_graphs/ doc/ examples/ --ignore-words=.codespellignore --skip "**/_build/*"'
109109

110110
type_check = 'mypy -p pywhy_graphs --config-file pyproject.toml'
111-
unit_test = 'pytest ./pywhy_graphs ./integration_tests --cov=pywhy_graphs --cov-report=xml --cov-config=pyproject.toml'
112-
integration_test = 'pytest ./integration_tests'
111+
unit_test = 'pytest ./pywhy_graphs --cov=pywhy_graphs --cov-report=xml --cov-config=pyproject.toml'
113112
build_docs = 'make -C docs clean html'
114113
build_docs_noplot = 'make -C docs clean html-noplot'
115114

pywhy_graphs/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
StationaryTimeSeriesPAG,
1414
)
1515
from .algorithms import * # noqa: F403
16-
from .array import export
1716
from .config import sys_info
1817

18+
from . import export
1919
from . import classes
2020
from . import networkx
2121
from . import simulate

0 commit comments

Comments
 (0)