Metadata-Version: 2.4
Name: moonframe
Version: 1.0.3
Summary: Simple and interactive plots using d3js
Author-email: CoopTeam-CERFACS <coop@cerfacs.fr>
License: Copyright (c) 2021 Cerfacs/COOP Team
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
Project-URL: Homepage, https://gitlab.com/cerfacs/moonframe
Project-URL: Documentation, https://gitlab.com/cerfacs/moonframe/-/tree/main/docs
Project-URL: Issues, https://gitlab.com/cerfacs/moonframe/-/issues
Project-URL: Changelog, https://gitlab.com/cerfacs/moonframe/-/blob/main/CHANGELOG.md
Keywords: data visualization,d3js,plot,charts,graph,scatter
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Topic :: Scientific/Engineering :: Visualization
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE.txt
Requires-Dist: click
Requires-Dist: flask
Requires-Dist: waitress
Requires-Dist: loguru
Requires-Dist: markdown
Requires-Dist: networkx
Requires-Dist: pandas
Provides-Extra: tests
Requires-Dist: pytest; extra == "tests"
Requires-Dist: pytest-coverage; extra == "tests"
Requires-Dist: pytest-datadir; extra == "tests"
Requires-Dist: pytest-allclose; extra == "tests"
Dynamic: license-file

<div align="center"><img src=https://gitlab.com/cerfacs/moonframe/raw/main/docs/images/moonframe.png width=90% alt="Moonframe's banner containing the logo, the title of the repo and a subtitle : d3.js visuals with Python."/></div>

<div align="center"><h1>Moonframe </h1></div>

<i>Moonframe is an open-source Python library that helps you create interactive graphs using <a href="https://d3js.org/">D3.js</a> without writing a single line of JavaScript.  
It’s built for quick data exploration and aims to be as simple and accessible as possible.</i>

## Main features

### Customizable charts without coding

Moonframe provides a simple user interface that handles all customization in real time, with no need to code. You can set the color palette, change the element properties (color, size, ...), filter the displayed data, and more.

<div>
<img src=https://gitlab.com/cerfacs/moonframe/-/raw/main/docs/images/readme/circular_packing_change.gif?ref_type=heads width=49% alt="Network graph demo. A menu on the left allows you to select a category to set the color scale, the size scale and group some of the nodes together."/>
<img src=https://gitlab.com/cerfacs/moonframe/-/raw/main/docs/images/readme/scatter_custom_color.gif?ref_type=heads width=49% alt="Scatter plot demo. With the menu on the left, you can change the color palette of the chart."/>
</div>

### Dynamic navigation

All graphs are interactive and dynamic, thanks to D3.js. Navigate your way through click, hover, zoom, and pan.

<div>
<img src=https://gitlab.com/cerfacs/moonframe/-/raw/main/docs/images/readme/network_navigation.gif?ref_type=heads width=49% alt="Network graph demo. Panning and zooming interactions are shown. We also see the mouse grab a node and drag it to someanother location, untangling the visualization."/>  
<img src=https://gitlab.com/cerfacs/moonframe/-/raw/main/docs/images/readme/circular_packing_navigation.gif?ref_type=heads width=49% alt="Circular packing plot demo. After clicking on a circle, the view zooms in on that circle."/>
</div>

### Ways of exploring your data

Moonframe lets you deeply explore your dataset: access your data with tooltips or cards, reveal relationships between elements with highlighting, flag important points, or hide useless ones.  
You are also free to remove or add fields to be displayed in tooltips or cards.

<div><img src=https://gitlab.com/cerfacs/moonframe/-/raw/main/docs/images/readme/scatter_group_by_color.gif?ref_type=heads width=49% alt="Scatter plot demo. An option allows you to group points that share the same color group. As a result, when you hover over a point, all the points in the same group are shown."/>
<img src=https://gitlab.com/cerfacs/moonframe/-/raw/main/docs/images/readme/network_highlight.gif?ref_type=heads width=49% alt="Click on a node to highlight its connections and display a data card with the selected node’s details. Unconnected nodes fade into the background, creating a clear visual contrast with the highlighted connections. You can also hover over any connected node to view its tooltip."/>
</div>

### Others features

- Easy to use
- Handling missing data
- Dark/light theme
- Search

## Usage

Moonframe handles web applications based on [Flask](https://flask.palletsprojects.com/en/stable/). Each application is run on a server and is rendered in a web browser.

> [!IMPORTANT]
> For Moonframe's applications, a server doesn't refer to a cloud or remote machine. Instead, it refers to an application running locally on your own computer. You will notice the URL of any Moonframe application is looking like `127.0.0.1:5000`, where `127.0.0.1` refers to your local machine (equivalent to `localhost`) and `5000` is the port used on your computer (can be something else, of course).

To keep things simple, Moonframe follows the philosophy: _"one application = one graph"_. **All available applications are stored in the `app_builder` module.**

In practice, you can either include Moonframe directly in your Python projects:

```python
from moonframe.app_builder import build_scatter_app
from moonframe.serve import serve_app

# Create a scatter plot app
app = build_scatter_app(filepath="dataset.csv", delimiter=";")
# Serve it locally
serve_app(app=app)
```

Or use it through the CLI:

```bash
> moonframe
Usage: moonframe [OPTIONS] COMMAND [ARGS]...

  Package moonframe v0.7.0

                  ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
                  ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣤⣴⡶⠖⠋⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
                  ⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣴⣾⣿⠟⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
                  ⠀⠀⠀⠀⠀⠀⠀⢀⣾⣿⣿⡿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
                  ⠀⠀⠀⠀⠀⠀⣰⣿⣿⣿⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣶⣶⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
                  ⠀⠀⠀⠀⠀⢀⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣶⣶⡆⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
                  ⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣧⠀⠀⠀⠀⠀⠀⣶⣤⡄⠀⣿⣿⡇⠀⣿⣿⡇⠀⠀⠀⠀⠀⡄⠀⠀⠀⠀⠀
                  ⠀⠀⠀⠀⠀⠸⣿⣿⣿⣿⣿⡆⠀⣶⣶⡆⠀⣿⣿⡇⠀⣿⣿⡇⠀⣿⣿⡇⠀⠀⠀⠀⢠⠇⠀⠀⠀⠀⠀
                  ⠀⠀⠀⠀⠀⠀⢻⣿⣿⣿⣿⣿⣦⡙⢿⡇⠀⣿⣿⡇⠀⣿⣿⡇⠀⣿⣿⡇⠀⠀⢀⣴⡟⠀⠀⠀⠀⠀⠀
                  ⠀⠀⠀⠀⠀⠀⠀⠻⣿⣿⣿⣿⣿⣿⣦⣀⡀⠿⢿⡇⠀⣿⣿⡇⠀⡿⠿⢃⣠⣴⣿⠟⠀⠀⠀⠀⠀⠀⠀
                  ⠀⠀⠀⠀⠀⠀⠀⠀⠙⠿⣿⣿⣿⣿⣿⣿⣿⣷⣶⣦⣤⣭⣭⣤⣴⣶⣾⣿⣿⠿⠋⠀⠀⠀⠀⠀⠀⠀⠀
                  ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠛⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠿⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
                  ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠉⠛⠛⠛⠛⠛⠉⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀

  ------------------------------  Moonframe  ------------------------------

  You are now using the Command line interface of moonframe package, a set of
  tools created at CERFACS (https://cerfacs.fr).

  This is a python package currently installed in your python environement.

  All graphs are displayed in your default web browser.

Options:
  --help  Show this message and exit.

Commands:
  circular-packing  Circular packing graph.
  network           Network graph.
  scatter           Scatter plot
```

## Getting started

> If you’re completely new to Python, the easiest way to begin is by following the <a href="docs/tutorials/getting_started.md">getting started tutorial</a>. This guide walks you through installing Moonframe and introduces a few essential basics. Give it a try!

### Requirements

- Web browser
- Python >= 3.7
- An internet connexion (just during graph generation, see Important note above)

### Installation

Install it from PyPI with :

```
pip install moonframe
```

> [!IMPORTANT]
> Since Moonframe is a Python package, it cannot directly include JavaScript packages as dependencies. Therefore, the required JavaScript libraries are loaded at runtime from [jsDelivr](https://www.jsdelivr.com/), a public content delivery network (CDN) for open-source software projects. In other words, when you open a graph, the browser loads the necessary JavaScript libraries (such as D3.js) from the word wild web (usually from [NPM](https://www.npmjs.com/), the JavaScript package registry; comparable to PyPi in the Python ecosystem).

## Available charts

### Table of contents

| <a href="#scatter-plot"><img src="https://gitlab.com/cerfacs/moonframe/-/raw/main/docs/images/readme/scatter.png?ref_type=heads" width="100px;" alt="Screenshot of a scatter graph."><br> _Scatter_ </a> | <a href="#circular-packing"><img src="https://gitlab.com/cerfacs/moonframe/-/raw/main/docs/images/readme/circular_packing.png?ref_type=heads" width="100px;" alt="Screenshot of a circular packing graph."> <br> _Circular packing_</a> | <a href="#network"><img src="https://gitlab.com/cerfacs/moonframe/-/raw/main/docs/images/readme/network.png?ref_type=heads" width="100px;" alt="Screenshot of a network graph."> <br> _Network_</a> |
| :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

### Scatter plot

The scatter plot displays data as points on a 2D axis. It is perfect to do quick data exploration on a variety of datasets.  
It takes as input CSV files structured in columns. It must include a header row to name each column. For example, [the film dataset](https://perso.telecom-paristech.fr/eagan/class/igr204/datasets) from the personal website of James R. Eagan:

```
Year;Length;Title;Subject;Actor;Actress;Director;Popularity;Awards;*Image
1990;111;Tie Me Up! Tie Me Down!;Comedy;Banderas, Antonio;Abril, Victoria;AlmodÛvar, Pedro;68;No;NicholasCage.png
1991;113;High Heels;Comedy;BosÈ, Miguel;Abril, Victoria;AlmodÛvar, Pedro;68;No;NicholasCage.png
1983;104;Dead Zone, The;Horror;Walken, Christopher;Adams, Brooke;Cronenberg, David;79;No;NicholasCage.png
```

> [!NOTE]
> Since you can specify the separator when running Moonframe, any separator should work.

More on this subject on [the dataset documentation](https://gitlab.com/cerfacs/moonframe/-/blob/main/docs/tutorials/tuto_scatter.md?ref_type=heads).

You can open the scatter plot either using the following command:

```
moonframe scatter film.csv -d ";"
```

Or in your application:

```python
from moonframe.app_builder import build_scatter_app
from moonframe.serve import serve_app

# Create a scatter plot app
app = build_scatter_app(filepath="film.csv", delimiter=";")
# Serve it locally
serve_app(app=app)
```

[Learn more on the scatter plot documentation](/docs/tutorials/tuto_scatter.md).

### Circular packing

The circular packing graph displays hierarchical data as nested circles.  
It takes as input JSON files looking like this:

```json
{
  "root": {
    "field1": 5,
    "field2": true,
    "field3": "coffee",
    "field4": 1.5,
    "field5": ["hello", "world"],
    "field6": { "hello": 1, "world": 2 }
  },
  "root/element1": {
    "field1": 2,
    "field2": false,
    "field3": "tea",
    "field4": 3.2,
    "field5": ["hello", "world"],
    "field6": { "hello": 1, "world": 2 }
  }
}
```

Hierarchy is expresses as paths using "/" to separate the different levels. **A common root is required to work**.

You can open the graph either using the following command:

```
moonframe circular-packing dataset.json
```

Or directly in your application:

```python
from moonframe.app_builder import build_app_circular_packing
from moonframe.serve import serve_app
from json import load

with open("dataset.json", "r") as file:
    data = load(file)

app = build_app_circular_packing(filedata=data, delimiter=";")
serve_app(app=app)
```

[Learn more on the circular packing plot documentation](https://gitlab.com/cerfacs/moonframe/-/blob/main/docs/tutorials/tuto_circular_packing.md?ref_type=heads).

### Network

The network graph displays relationships between elements within a network as nodes and edges (links).  
It takes as input [NetworkX graph](https://networkx.org/en/) or a JSON file generated from one (using `node_link_data`, [see the offical documentation](https://networkx.org/documentation/latest/reference/readwrite/generated/networkx.readwrite.json_graph.node_link_data.html#node-link-data)).

For example, you can open a Network graph in a Python script:

```python
import networkx as nx
from moonframe.app_builder import build_app_network
from moonframe.server import serve_app

# set the graph - example taken from https://networkx.org/documentation/latest/auto_examples/basic/plot_simple_graph.html
G = nx.Graph()
G.add_edge(1, 2)
G.add_edge(1, 3)
G.add_edge(1, 5)
G.add_edge(2, 3)
G.add_edge(3, 4)
G.add_edge(4, 5)

# create the graph and opens it with Moonframe
app = build_app_network(G, title="Simple Network")
serve_app(app)
```

Or using the following command:

```bash
moonframe network dataset.json
```

`dataset.json` is, in this case, the output of the NetworkX function `node_link_data` dumped to JSON:

```python
data = nx.readwrite.json_graph.node_link_data(G)

with open("dataset.json", "w") as f:
    json.dump(data, f, indent=4)
```

Giving the following:

```json
{
  "directed": false,
  "multigraph": false,
  "graph": {},
  "nodes": [
    {
      "id": 1
    },
    {
      "id": 2
    },
    {
      "id": 3
    },
    {
      "id": 5
    },
    {
      "id": 4
    }
  ],
  "edges": [
    {
      "source": 1,
      "target": 2
    },
    {
      "source": 1,
      "target": 3
    },
    {
      "source": 1,
      "target": 5
    },
    {
      "source": 2,
      "target": 3
    },
    {
      "source": 3,
      "target": 4
    },
    {
      "source": 5,
      "target": 4
    }
  ]
}
```

[Learn more on the network graph documentation](https://gitlab.com/cerfacs/moonframe/-/blob/main/docs/tutorials/tuto_network.md?ref_type=heads).

## Most common troubleshoots

- **Wrong data format** : Makes sure to double check the input data format requirements. You can take a look at the [Dataset documentation](/docs/tutorials/compatible-dataset.md). Be extra careful with the delimiter of your CSV file when using the scatter plot.
- **Internet connexion** : Even though the graph is hosted locally, an internet connection is briefly required during generation to load the necessary packages.
- **Port number**: If you manually set the port using the `-p` option, make sure the port is available and not reserved by your system. If unsure, simply run the application without specifying a port, this lets it automatically choose a suitable one.
- **Cache** : If something isn't working as expected, try clearing your browser cache and restarting the application.
- **Version** : Of course, make sure you are up-to-date. Run `pip install --upgrade moonframe`.
- **Not responsive**: Either your dataset is too big and it takes a lot of time to load - either you have disconnect your server by closing your terminal or pression `CTRL+D`.

> [!IMPORTANT]
> **Don't forget to tracks errors in your browser’s console !**  
> Frontend issues (coming from JavaScript, HTML or CSS) are displayed on your browser's console and not in your terminal. As most of Moonframe mechanics are developped in JavaScript, there is a good chance that an error occurs here.
