Skip to main content

Simple and interactive plots using d3js

Project description

Moonframe's banner containing the logo, the title of the repo and a subtitle : d3.js visuals with Python.

Moonframe

Moonframe is an open-source Python library that helps you create interactive graphs using D3.js without writing a single line of JavaScript.
It’s built for quick data exploration and aims to be as simple and accessible as possible.

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.

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. Scatter plot demo. With the menu on the left, you can change the color palette of the chart.

Dynamic navigation

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

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. Circular packing plot demo. After clicking on a circle, the view zooms in on that circle.

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.

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. 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.

Others features

  • Easy to use
  • Handling missing data
  • Dark/light theme
  • Search
  • Save to PNG (only in scatter)

Usage

Moonframe handles web applications based on Flask. 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:

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:

> 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 getting started tutorial. 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, 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, the JavaScript package registry; comparable to PyPi in the Python ecosystem).

Available charts

Table of contents

Screenshot of a scatter graph.
Scatter
Screenshot of a circular packing graph.
Circular packing
Screenshot of a network graph.
Network

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 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.

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

moonframe scatter film.csv -d ";"

Or in your application:

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.

Circular packing

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

{
  "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:

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.

Network

The network graph displays relationships between elements within a network as nodes and edges (links).
It takes as input NetworkX graph or a JSON file generated from one (using node_link_data, see the offical documentation).

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

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:

moonframe network dataset.json

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

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:

{
  "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.

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. 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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

moonframe-1.0.1.tar.gz (66.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

moonframe-1.0.1-py3-none-any.whl (75.7 kB view details)

Uploaded Python 3

File details

Details for the file moonframe-1.0.1.tar.gz.

File metadata

  • Download URL: moonframe-1.0.1.tar.gz
  • Upload date:
  • Size: 66.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.9

File hashes

Hashes for moonframe-1.0.1.tar.gz
Algorithm Hash digest
SHA256 8a19ea130aac2cdcffabdcecd81ac29d3db23bad095e9db3951e9e277e4607b5
MD5 3cfd7f5c89a7716a9f653a4810b3df71
BLAKE2b-256 bc14d42a73c9c5b63591a8b2f3e87dcee8a26b119cdd610d1c5547cb2f24e4a5

See more details on using hashes here.

File details

Details for the file moonframe-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: moonframe-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 75.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.9

File hashes

Hashes for moonframe-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 60d59f5c92958e311c3fe2dd56b56b08e39f383de187ed4f129c3cc970fa9188
MD5 4f0775bad3cf65c679a8e074566cc0a3
BLAKE2b-256 ddf0548004b102e795aab5b1c60b188ac34cb868dfd730de2b822fff4763a063

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page