Skip to content

Commit

Permalink
Merge pull request #8 from Wytamma/pyLangevitour
Browse files Browse the repository at this point in the history
Python interface for langevitour contributed by Wytamma Wirth.
  • Loading branch information
pfh authored Sep 12, 2023
2 parents ed7ddeb + ac952f5 commit 20be80e
Show file tree
Hide file tree
Showing 16 changed files with 878 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,8 @@ inst/doc
docs
/doc/
/Meta/

# python
*.pyc
dist
.ipynb_checkpoints/
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: langevitour
Title: Langevin Tour
Version: 0.5.2
Version: 0.5.5
Authors@R:
person("Paul", "Harrison", , "[email protected]", role = c("aut", "cre"),
comment = c(ORCID = "0000-0002-3980-268X"))
Expand Down
51 changes: 50 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# langevitour

langevitour is an HTML widget that randomly tours projections of a high-dimensional dataset with an animated scatter-plot. The user can manipulate the plot to use specified axes, or turn on Guided Tour mode to perform [projection pursuit](https://en.wikipedia.org/wiki/Projection_pursuit), finding an informative projection of the data. Groups within the data can be hidden or shown, as can particular axes. Known projections of interest can be added as "extra axes" and also manipulated. The widget can be used from within R, or included in a self-contained Rmarkdown document, or a Shiny app, or used directly from Javascript.
langevitour is an HTML widget that randomly tours projections of a high-dimensional dataset with an animated scatter-plot. The user can manipulate the plot to use specified axes, or turn on Guided Tour mode to perform [projection pursuit](https://en.wikipedia.org/wiki/Projection_pursuit), finding an informative projection of the data. Groups within the data can be hidden or shown, as can particular axes. Known projections of interest can be added as "extra axes" and also manipulated. The widget can be used from within R or Python, or included in a self-contained Rmarkdown document, or a Shiny app, or used directly from Javascript.

<a href="https://logarithmic.net/langevitour/2022-abacbs/" style="display: block; margin: 5px; border: 1px solid #000; float: right">
<img src="https://logarithmic.net/langevitour/2022-abacbs/abacbs-langevitour-poster-2022-small.png" width=300>
Expand All @@ -20,6 +20,8 @@ langevitour is a twist on the "tour" concept from software such as [XGobi](http:

* [Javascript example](https://pfh.github.io/langevitour/example.html)

* [Python example](https://colab.research.google.com/github/Wytamma/pyLangevitour/blob/main/examples/notebook.ipynb)

<br>

## R installation
Expand Down Expand Up @@ -108,6 +110,53 @@ For example, to define a new guide you would:

<br>

## Python installation
```bash
pip install langevitour
```

## Python usage

```python
import numpy as np

from langevitour import Langevitour

# Generate a sample dataset
X = []
group = []
n = 20000

def r():
return np.random.normal(0, 0.02)

for i in range(n):
a = i/n * np.pi * 2
X.append([
10 + np.sin(a)/3 + r(),
20 + np.sin(a*2)/3 + r(),
30 + np.sin(a*3)/3,
40 + np.sin(a*4)/3,
50 + np.sin(a*5)/3
])
group.append(int(i*4/n))

# Extra axes (specified as columns of a matrix)
extra_axes = [[1], [2], [0], [0], [0]]
extra_axes_names = ["V1+2*V2"]

tour = Langevitour(
X,
group=group,
extra_axes=extra_axes,
extra_axes_names=extra_axes_names,
point_size=1,
)
tour.write_html("langevitour_plot.html")
```

langevitour also works in [jupyter notebooks](https://colab.research.google.com/github/pfh/langevitour/blob/main/py/examples/langevitour.ipynb).

## Copyright

Langevitour is free software made available under the [MIT license](https://github.com/pfh/langevitour/blob/main/LICENSE.md). Included libraries [jStat](https://github.com/jstat/jstat) and [SVD-JS](https://github.com/danilosalvati/svd-js) are also provided under the MIT license. Included library [D3](https://github.com/d3/d3) is provided under the [ISC license](https://github.com/d3/d3/blob/main/LICENSE).
2 changes: 1 addition & 1 deletion inst/htmlwidgets/langevitour.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
dependencies:
- name: langevitour
version: "0.5.2"
version: "0.5.5"
src: htmlwidgets/lib/
script:
- langevitour-pack.js
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
{
"name": "langevitour",
"version": "0.5.2",
"version": "0.5.5",
"description": "An HTML widget that randomly tours 2D projections of numerical data.",
"type": "module",
"main": "lib/langevitour.js",
"sideEffects": false,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"sync-versions": "VERSION=$(grep '^Version:' DESCRIPTION | cut -d' ' -f2) && sed -i '/^ \\\"version\\\"/ c\\ \\\"version\\\": \\\"'$VERSION'\\\",' package.json && sed -i '/^ version:/ c\\ version: \\\"'$VERSION'\\\"' inst/htmlwidgets/langevitour.yaml",
"sync-versions": "VERSION=$(grep '^Version:' DESCRIPTION | cut -d' ' -f2) && sed -i '/^ \\\"version\\\"/ c\\ \\\"version\\\": \\\"'$VERSION'\\\",' package.json && sed -i '/^ version:/ c\\ version: \\\"'$VERSION'\\\"' inst/htmlwidgets/langevitour.yaml && hatch version $VERSION",
"js-build": "npx tsc && npx webpack",
"js-build-quick": "npx tsc && npx webpack --mode=development",
"js-docs": "npx typedoc src/langevitour.ts --out docs/jsdoc/ --excludeNotDocumented --readme none",
"r-document": "Rscript -e 'devtools::document()'",
"r-docs": "npm run r-document && Rscript -e 'pkgdown::build_site()'",
"build": "npm run sync-versions && npm run js-build && npm run js-docs && npm run r-docs",
"py-build": "cp inst/htmlwidgets/lib/langevitour-pack.js py/langevitour/static/langevitour-pack.js && hatch build",
"py-publish": "hatch publish",
"build": "npm run sync-versions && npm run js-build && npm run js-docs && npm run r-docs && npm run py-build",
"r-install": "Rscript -e 'devtools::install()'",
"r-install-quick": "Rscript -e 'devtools::install(quick=TRUE)'"
},
Expand Down
56 changes: 56 additions & 0 deletions py/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# langevitour for Python

[![PyPI - Version](https://img.shields.io/pypi/v/langevitour.svg)](https://pypi.org/project/langevitour)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/langevitour.svg)](https://pypi.org/project/langevitour)

Python interface for [langevitour](https://github.com/pfh/langevitour/) a HTML widget that randomly tours projections of a high-dimensional dataset with an animated scatter-plot.

For more information see the langevitour [Github repo](https://github.com/pfh/langevitour) or [website](https://logarithmic.net/langevitour/).

## Installation

```bash
pip install langevitour
```

## Python usage

```python
import numpy as np

from langevitour import Langevitour

# Generate a sample dataset
X = []
group = []
n = 20000

def r():
return np.random.normal(0, 0.02)

for i in range(n):
a = i/n * np.pi * 2
X.append([
10 + np.sin(a)/3 + r(),
20 + np.sin(a*2)/3 + r(),
30 + np.sin(a*3)/3,
40 + np.sin(a*4)/3,
50 + np.sin(a*5)/3
])
group.append(int(i*4/n))

# Extra axes (specified as columns of a matrix)
extra_axes = [[1], [2], [0], [0], [0]]
extra_axes_names = ["V1+2*V2"]

tour = Langevitour(
X,
group=group,
extra_axes=extra_axes,
extra_axes_names=extra_axes_names,
point_size=1,
)
tour.write_html("langevitour_plot.html")
```

langevitour also works in [jupyter notebooks](https://colab.research.google.com/github/pfh/langevitour/blob/main/py/examples/langevitour.ipynb).
229 changes: 229 additions & 0 deletions py/examples/langevitour.ipynb

Large diffs are not rendered by default.

35 changes: 35 additions & 0 deletions py/examples/tour.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import numpy as np

from langevitour import Langevitour

# Generate a sample dataset
X = []
group = []
n = 20000

def r():
return np.random.normal(0, 0.02)

for i in range(n):
a = i/n * np.pi * 2
X.append([
10 + np.sin(a)/3 + r(),
20 + np.sin(a*2)/3 + r(),
30 + np.sin(a*3)/3,
40 + np.sin(a*4)/3,
50 + np.sin(a*5)/3
])
group.append(int(i*4/n))

# Extra axes (specified as columns of a matrix)
extra_axes = [[1], [2], [0], [0], [0]]
extra_axes_names = ["V1+2*V2"]

tour = Langevitour(
X,
group=group,
extra_axes=extra_axes,
extra_axes_names=extra_axes_names,
point_size=1,
)
tour.write_html("langevitour_plot.html")
4 changes: 4 additions & 0 deletions py/langevitour/__about__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# SPDX-FileCopyrightText: 2023-present Wytamma Wirth <[email protected]>
#
# SPDX-License-Identifier: MIT
__version__ = "0.5.5"
4 changes: 4 additions & 0 deletions py/langevitour/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# SPDX-FileCopyrightText: 2023-present Wytamma Wirth <[email protected]>
#
# SPDX-License-Identifier: MIT
from .langevitour import Langevitour
Loading

0 comments on commit 20be80e

Please sign in to comment.