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.0.tar.gz (65.4 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.0-py3-none-any.whl (75.3 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: moonframe-1.0.0.tar.gz
  • Upload date:
  • Size: 65.4 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.0.tar.gz
Algorithm Hash digest
SHA256 4fa6abfb1b5a553e9dd721f86b07611fed5ba6244bdde96a5cf4fd7730a41046
MD5 f141fc73df98841da4beb368ca3ab77c
BLAKE2b-256 2ca7a575436bd510916263ce1d1f76483759fddb8db1a5f8d3652ed90f7d8965

See more details on using hashes here.

File details

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

File metadata

  • Download URL: moonframe-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 75.3 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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e95ad8d7a729dbd40fcfaf38aab55255cb8dbfa082d8666197cdcba4da2e7bd1
MD5 372b40c0aca84fa19f860393de9f3369
BLAKE2b-256 d7ebbef5089bcc69e68c3957ac52f31f08070aa9422a088dae2f588e937b53a1

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