CompleX Group Interactions (XGI) provides an ecosystem for the analysis and representation of complex systems with group interactions.

Overview

XGI

CompleX Group Interactions (XGI) is a Python package for the representation, manipulation, and study of the structure, dynamics, and functions of complex systems with group (higher-order) interactions.

Table of Contents:

Installation

XGI runs on Python 3.7 or higher.

To install the latest version of XGI, run the following command:

pip install xgi

To install this package locally:

  • Clone this repository
  • Navigate to the folder on your local machine
  • Run the following command:
pip install -e .["all"]
  • If that command does not work, you may try the following instead
pip install -e .\[all\]

Getting Started

To get started, take a look at the tutorials illustrating the library's basic functionality.

Documentation

For more documentation, see our Read The Docs page.

Contributing

Contributions are always welcome. Please report any bugs that you find here. Or, even better, fork the repository on GitHub and create a pull request (PR). We welcome all changes, big or small, and we will help you make the PR if you are new to git (just ask on the issue and/or see our contributing guidelines).

How to Cite

We acknowledge the importance of good software to support research, and we note that research becomes more valuable when it is communicated effectively. To demonstrate the value of XGI, we ask that you cite XGI in your work. Currently, the best way to cite XGI is to go to our repository page (if you haven't already) and click the "cite this repository" button on the right sidebar. This will generate a citation in your preferred format, and will also integrate well with citation managers.

Code of Conduct

Our full code of conduct, and how we enforce it, can be read in our repository.

License

Released under the 3-Clause BSD license (see LICENSE.md)

Copyright (C) 2021 XGI Developers

Nicholas Landry [email protected]

Leo Torres [email protected]

Iacopo Iacopini [email protected]

Maxime Lucas [email protected]

Giovanni Petri [email protected]

Alice Patania [email protected]

The XGI library has copied or modified code from the HyperNetX and NetworkX libraries, the licenses of which can be found in our license file

Funding

The XGI package has been supported by NSF Grant 2121905, "HNDS-I: Using Hypergraphs to Study Spreading Processes in Complex Social Networks".

Other resources

This library may not meet your needs and if this is this case, consider checking out these other resources:

  • HyperNetX: A package in Python for representing, analyzing, and visualizing hypergraphs.
  • SimpleHypergraphs.jl: A package in Julia for representing, analyzing, and generating hypergraphs.
  • hyperG: A package in R for storing and analyzing hypergraphs
  • NetworkX: A package in Python for representing, analyzing, and visualizing networks.
Issues
  • Interface of NodeView

    Interface of NodeView

    NodeView supports accessing the edge ids that contain a node in three different ways:

    H = some_hypergraph()
    H.nodes[1] == H.nodes(1) == H.members(1)
    # -> True
    

    I find this unpythonic. I'd much rather there was a single way of doing things if at all possible. If there was exactly one way of accessing the edges that contain a node, which would you prefer? If anyone can argue that we should support two (or more) ways of doing the same thing, I'm all ears.

    Related to #20.

    opened by leotrs 21
  • Add function to get list of edges (not edge ids)

    Add function to get list of edges (not edge ids)

    Currently,

    H.edges 
    # EdgeView([3, 2, 4, 9])
    

    outputs edge ids, not edges as list of member nodes. It's often useful to access edges as list of member nodes. One current way is list(H._edge.values()) but it's long and hidden.

    Should we have a two views?

    • EdgeIdView (to replace current EdgeView): for ids
    H.edges_id
    # EdgeIdView([3, 2, 4, 9])
    
    • EdgeView:for list of member nodes
    H.edges
    # EdgeView([[0], [3, 4], [4], [4]])
    
    opened by maximelucas 10
  • Add functions to get largest connected component

    Add functions to get largest connected component

    Graph generators may sometimes return hypergraphs with isolated nodes (e.g. ER hypergraph with small p). In these cases, and others, it is usual to obtain the largest component. Ideally, we would like to do something like this:

    G = xgi.erdos_renyi_hypergraph(n, m, p).largest_component()
    G = xgi.erdos_renyi_hypergraph(n, m, p).remove_isolates()
    
    opened by leotrs 9
  • Add ability to specify hyperdegree order

    Add ability to specify hyperdegree order

    The current functionality only specifies the number of hyperedges to which a node belongs. In principle, one should be able to specify a hyperedge size or list of sizes and it returns the number of hyperedges of that size of which that node is a part.

    enhancement 
    opened by nwlandry 9
  • order, shape, number_of_edges, number_of_nodes

    order, shape, number_of_edges, number_of_nodes

    All these functions do very similar things. In keeping with the idea of doing things only once, I vote we simplify them somehow.

    I personally lean toward the nuclear option and just keeping shape. All the others are not necessary...

    opened by leotrs 7
  • neighbors

    neighbors

    I was thinking that, when doing simulations (particularly for games), it is very useful to have the neighbors of a node divided by hyperedge. To explain better, here's what the current neighbors function returns:

    hyperedge_list = [[1, 2], [2, 3, 4]]
    H.neighbors(2)
    # {1, 3, 4}
    

    which is basically the neighbors in the graph projection of H. What I was imagining is actually a higher-order neighbor function that returns {[1], [3, 4]}. This is extremely useful in loops when you want to scroll over the hyperedges attached to a node and then the neighbors in those.

    Do you think something like this could be integrated into the current neighbors function? Or maybe two different ones? In my old code I had H.graph_neighbors() and H.neighbors().

    improve 
    opened by iaciac 7
  • Lazy View construction not working

    Lazy View construction not working

    When calling the .nodes property, cProfile indicates that every time that H.nodes is called, a new object is constructed (the hypergraph for which this profile was run has 2261 nodes): image This shouldn't happen with the Lazy View construction. The same thing happens with calling H.edges

    opened by nwlandry 6
  • A way to get edge members (not edge ids)

    A way to get edge members (not edge ids)

    Fixes #28.

    Demo:

    H = xgi.Hypergraph([[1, 2, 3], [3, 4], [4, 5, 6]])
    
    H.edges
    # -> EdgeView((0, 1, 2))
    H.edges.members()
    # -> [[1, 2, 3], [3, 4], [4, 5, 6]]
    H.edges.members(dtype=dict)
    # -> {0: [1, 2, 3], 1: [3, 4], 2: [4, 5, 6]}
    
    opened by leotrs 6
  • Filter edges by order and nodes by degree

    Filter edges by order and nodes by degree

    This is an addition to the view interface. Essentially, now we can do the following:

    H = xgi.Hypergraph([[1, 2, 3], [3, 4], [4, 5, 6]])
    
    # filter nodes by degree
    H.nodes
    # -> NodeView((1, 2, 3, 4, 5, 6))
    H.nodes(degree=2)     # awesome new stuff
    # -> NodeView((3, 4))
    
    # filter edges by order
    H.edges
    # -> EdgeView((0, 1, 2))
    H.edges(order=2)     # whoa
    # -> EdgeView((0, 2))
    
    # awesome stuff happens
    1 in H.edges
    # -> True
    1 in H.edges(order=2)     # magic
    # -> False
    

    Using H.nodes(degree) or H.edges(order) return view objects that contain only a subset of nodes or edges. These are still instances of the same old view classes. The difference is that now IDView contains a list of IDs that it keeps track of. So it will always contain the entire dictionary and attributes of all nodes/edges, just like before, but now whenever it reads from them, it uses the provided subset of IDs that it is keeping track of. This is probably going to be a pain in the ass later on because whenever we add or change functionality of IDView, we will need to remember to use the subset of ids, and not the keys of the stored dictionary which would be more natural.

    One technical comment is that I had to implement the class method IDView.from_view to create a new view from a different view. This is because the constructor of NodeView and EdgeView take only a hypergraph, so we didn't have a way of creating a view from a view.

    One drawback of the current implementation is that the views no longer preserve order. In particular, I had to change all the tests that use views from lists to sets. So that made the diff a little messy.

    Finally, in the process of writing this I found a bug in how json hypergraphs were being read. The specified nodetype was not being respected. This is now fixed.

    opened by leotrs 5
  • Egonet a.k.a. per-edge neighbors

    Egonet a.k.a. per-edge neighbors

    I'm moving the conversation from #32 to here.

    The current is a proof of concept. We just have to agree on the name and whether we want an analogous method for edges. Once we agree on that, I'll implement those and add tests.

    Demo:

    In [6]: H = xgi.Hypergraph([(0,1,2), (1,2), (0, 3)])
    
    In [7]: H.neighbors(0)
    Out[7]: {1, 2, 3}
    
    In [8]: H.egonet(0)
    Out[8]: [[1, 2], [3]]
    
    In [9]: H.egonet(0, include_self=True)
    Out[9]: [[0, 1, 2], [0, 3]]
    

    Closes #32.

    opened by leotrs 5
  • Add ability create/look at subhypergraphs

    Add ability create/look at subhypergraphs

    • Add a function which allows you to specify a list of nodes and an option to shrink edges (false if you want an induced subhypergraph) and it will return the subhypergraph.
    • Add a function which allows you to specify a list of edges and it will return the subhypergraph.
    enhancement 
    opened by nwlandry 5
  • Add features to `degree_histogram`

    Add features to `degree_histogram`

    I wanted to easily visualize the degree/edge size distribution and the way that I found easiest to get both was the following:

    degrees = dict(H.degree())
    edge_sizes = dict(H.edge_size())
    
    d, count_d = np.unique(list(degrees.values()), return_counts=True)
    p_d = count_d/len(degrees)
    e, count_e = np.unique(list(edge_sizes.values()), return_counts=True)
    p_e = count_e/len(edge_sizes)
    

    Currently, there is a way to do some of this with degree_histogram, but I would like to be able to a) specify either edge sizes or degrees and b) specify whether it is normalized. And perhaps we should return numpy arrays instead of lists.

    good first issue improve 
    opened by nwlandry 3
  • The current

    The current "egonet" method is wrong

    The current method returns all edges a node belongs to. This is not called the egonet, it should be called something else. The egonet includes edges among nodes that are neighbors of the specified node.

    opened by leotrs 0
  • Move some methods away from the base classes

    Move some methods away from the base classes

    The base classes are already bloated as it is, so we should try to do some cleanup. I propose the base classes only keep methods that directly modify the underlying structure. All other methods should go to auxiliary classes. For example:

    These should move to NodeView:

    • isolates
    • neighbors

    These should move to EdgeView:

    • singleton_edges (and rename to singletons)
    • max_edge_order (and rename to max_order)
    • duplicate_edges (and rename to duplicates)
    • is_possible_order (do we really need this method?)

    For example, instead of H.neighbors, we would do H.nodes.neighbors. Yes this is longer but I think it's worth it. Maintenance, documentation, and end-user code will be better.

    These methods should be removed completely:

    • get_edge_data (data can be accessed via View objects)
    • has_edge (do n in H.edges instead)
    • has_node (do n in H.nodes instead)
    opened by leotrs 0
  • `remove_simplex_ids_from` does not enforce removing subfaces

    `remove_simplex_ids_from` does not enforce removing subfaces

    remove_simplex_id enforces removing all subfaces as well and calls remove_simplex_ids_from to do so. Because of this, remove_simplex_ids_from does not enforce simpliciality. I think that remove_simplex_ids_from should call remove_simplex_id and either

    1. Implement the contents of remove_simplex_ids_from directly in remove_simplex_id
    2. rename remove_simplex_ids_from to be a helper function.

    so that calling remove_simplex_id in remove_simplex_ids_from is not circular.

    opened by nwlandry 0
  • Myst notebooks

    Myst notebooks

    • Added jupytext as a dependency in the tutorials requirements file.
    • Converted the tutorials to MyST (markdown) files
    • Removed the Jupyter notebooks
    • Provided a brief description for how to convert between markdown and Jupyter notebooks.
    opened by nwlandry 3
Releases(v0.3)
  • v0.3(Apr 29, 2022)

    • Added the ability to convert to and from a NetworkX bipartite graph.
    • Removed the shape property from Hypergraph and renamed the number_of_nodes() and number_of_edges() methods to the num_nodes and num_edges properties, respectively.
    • Added random seed decorator as in NetworkX.
    • Added a SimplicialComplex class.
    • Added order and weighted arguments to the incidence_matrix and adjacency_matrix functions.
    • Added an intersection_profile function.
    • Added a laplacian function with argument order and a multiorder_laplacian function.
    • Fix: Return an empty array rather than a 1x1 zero array when appropriate.
    • Fix: Ensured that the incidence matrix is always has dimensions num_nodes x num_edges.
    • Added 2 generators of random (maximal) simplicial complexes, and toy star-clique generator
    • Extensively rewrote the documentation, updating the content and format on Read The Docs.
    • Added an egonet function to get the edges neighboring a specified node.
    • Added functions to visualize hypergraphs and simplicial complexes.
    • Added the ability to get nodes and edges of given degrees/sizes respectively.
    • Extended the members() function to be able to get different data types and to either get a single edge or all edges.
    • Added the load_xgi_data function to load datasets from the xgi-data repository.
    • Added two additional tutorials: a tutorial on visualizing higher-order networks and a case study replicating a recent paper.
    • Changed the API of degree_histogram and added degree_counts based on #23.
    • Refactored the IDDegreeView class and changed the API. Added the ability to specify order and the datatype.
    • Added an abstract class IDDict to handle data validation.

    Contributors: @iaciac @leotrs @lordgrilo @maximelucas @nwlandry @tlarock

    Source code(tar.gz)
    Source code(zip)
  • v0.2(Feb 8, 2022)

    • H[attr] now accesses hypergraph attributes
    • H.nodes[id] now accesses attributes, not bipartite neighbors
    • Removed the__call__() functionality from H.nodes and H.edges
    • H.nodes.memberships(id) and H.edges.members(id) now access the bipartite neighbors
    • Created base classes for the Node/Edge Views and Degree/Edge Size Views to inherit from.
    • Removed the NodeDataView and EdgeDataView.
    • Updated the list of developers
    • __getitem__() in the NodeView and EdgeView are now in a try-except block for greater efficiency.
    • Removed the name attribute and fixed methods and tests to match.
    • Fixed the erdos_renyi_hypergraph(), chung_lu_hypergraph(), and dcsbm_hypergraph() methods such that the number of nodes will always match the number the user specifies, even if the resulting hypergraph is disconnected.
    • Changed the construction method from reading in a Pandas DataFrame to using the add_node_to_edge() method for a 2x speedup.
    • Added some basic unit tests for the generative models.
    • Added the dual keyword for the read_bipartite_edgelist() method.
    • Added small functions to the Hypergraph class
    • Added generator of random hypergraph
    • Added functions for finding and removing isolates
    • Refactored the has_edge() method in the Hypergraph class.

    Contributors: @leotrs @maximelucas @nwlandry

    Source code(tar.gz)
    Source code(zip)
  • v0.1.4(Dec 12, 2021)

  • v0.1.3(Dec 3, 2021)

  • v0.1.2(Dec 3, 2021)

  • v0.1.1(Dec 1, 2021)

    • Fixed bug in the unique_edge_sizes function
    • Automated the import of necessary packages from the requirements file
    • Added documentation to the PyPi page
    Source code(tar.gz)
    Source code(zip)
  • v0.1(Nov 17, 2021)

Owner
Complex Group Interactions
CompleX Group Interactions (XGI) provides an ecosystem for the analysis and representation of complex systems with group interactions.
Complex Group Interactions
A tool for automatically generating 3D printable STLs from freely available lidar scan data.

mini-map-maker A tool for automatically generating 3D printable STLs from freely available lidar scan data. Screenshots Tutorial To use this script, g

Mike Abbott 43 Jan 24, 2022
An automatic prover for tautologies in Metamath

completeness An automatic prover for tautologies in Metamath This program implements the constructive proof of the Completeness Theorem for propositio

Scott Fenton 2 Dec 14, 2021
A Simple Flask-Plotly Example for NTU 110-1 DSSI Class

A Simple Flask-Plotly Example for NTU 110-1 DSSI Class Live Demo Prerequisites We will use Flask and Ploty to build a Flask application. If you haven'

Ting Ni Wu 1 Dec 10, 2021
A tool for creating SVG timelines from simple JSON input.

A tool for creating SVG timelines from simple JSON input.

Jason Reisman 409 Jan 24, 2022
Collection of data visualizing projects through Tableau, Data Wrapper, and Power BI

Data-Visualization-Projects Collection of data visualizing projects through Tableau, Data Wrapper, and Power BI Indigenous-Brands-Social-Movements Pyt

Jinwoo(Roy) Yoon 1 Feb 04, 2022
`charts.css.py` brings `charts.css` to Python. Online documentation and samples is available at the link below.

charts.css.py charts.css.py provides a python API to convert your 2-dimension data lists into html snippet, which will be rendered into charts by CSS,

Ray Luo 3 Sep 22, 2021
Runtime analysis of code with plotting

Runtime analysis of code with plotting A quick comparison among Python, Cython, and the C languages A Programming Assignment regarding the Programming

Cena Ashoori 2 Dec 23, 2021
Make scripted visualizations in blender

Scripted visualizations in blender The goal of this project is to script 3D scientific visualizations using blender. To achieve this, we aim to bring

Praneeth Namburi 8 Jan 17, 2022
A Jupyter - Three.js bridge

pythreejs A Python / ThreeJS bridge utilizing the Jupyter widget infrastructure. Getting Started Installation Using pip: pip install pythreejs And the

Jupyter Widgets 787 Feb 01, 2022
Streamlit component for Let's-Plot visualization library

streamlit-letsplot This is a work-in-progress, providing a convenience function to plot charts from the Lets-Plot visualization library. Example usage

Randy Zwitch 4 Jan 06, 2022
SummVis is an interactive visualization tool for text summarization.

SummVis is an interactive visualization tool for analyzing abstractive summarization model outputs and datasets.

Robustness Gym 220 Jan 12, 2022
Interactive chemical viewer for 2D structures of small molecules

👀 mols2grid mols2grid is an interactive chemical viewer for 2D structures of small molecules, based on RDKit. ➡️ Try the demo notebook on Google Cola

Cédric Bouysset 104 Jan 19, 2022
mysql relation charts

sqlcharts 自动生成数据库关联关系图 复制settings.py.example 重命名为settings.py 将数据库配置信息填入settings.DATABASE,目前支持mysql和postgresql 执行 python build.py -b,-b是读取数据库表结构,如果只更新匹

5 Aug 18, 2021
又一个云探针

ServerStatus-Murasame 感谢ServerStatus-Hotaru,又一个云探针诞生了(大雾 本项目在ServerStatus-Hotaru的基础上使用fastapi重构了服务端,部分修改了客户端与前端 项目还在非常原始的阶段,可能存在严重的问题 演示站:https://stat

6 Oct 18, 2021
python partial dependence plot toolbox

PDPbox python partial dependence plot toolbox Motivation This repository is inspired by ICEbox. The goal is to visualize the impact of certain feature

Li Jiangchun 646 Jan 20, 2022
Simple Inkscape Scripting

Simple Inkscape Scripting Description In the Inkscape vector-drawing program, how would you go about drawing 100 diamonds, each with a random color an

Scott Pakin 61 Jan 13, 2022
A GUI for Pandas DataFrames

PandasGUI A GUI for analyzing Pandas DataFrames. Demo Installation Install latest release from PyPi: pip install pandasgui Install directly from Githu

Adam 2.6k Feb 10, 2022
Flow-based visual scripting for Python

A simple visual node editor for Python Ryven combines flow-based visual scripting with Python. It gives you absolute freedom for your nodes and a simp

Leon Thomm 2.6k Jan 28, 2022
Visual Python is a GUI-based Python code generator, developed on the Jupyter Notebook environment as an extension.

Visual Python is a GUI-based Python code generator, developed on the Jupyter Notebook environment as an extension.

Visual Python 390 Jan 31, 2022
Simple plotting for Python. Python wrapper for D3xter - render charts in the browser with simple Python syntax.

PyDexter Simple plotting for Python. Python wrapper for D3xter - render charts in the browser with simple Python syntax. Setup $ pip install PyDexter

D3xter 31 Mar 05, 2021