Metadata-Version: 2.4
Name: juxt
Version: 0.10.0
Summary: Fast desktop tool for navigating N-dimensional hypercubes of plots
Project-URL: Homepage, https://github.com/ColinMoldenhauer/juxt
Project-URL: Documentation, https://juxt.readthedocs.io
Project-URL: Repository, https://github.com/ColinMoldenhauer/juxt
Project-URL: Bug Tracker, https://github.com/ColinMoldenhauer/juxt/issues
Author-email: Colin Moldenhauer <colin.moldenhauer@posteo.de>
License: MIT
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: X11 Applications :: Qt
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Visualization
Requires-Python: >=3.10
Requires-Dist: pyside6
Requires-Dist: pyyaml
Provides-Extra: docs
Requires-Dist: mkdocs-include-markdown-plugin; extra == 'docs'
Requires-Dist: mkdocs-material; extra == 'docs'
Provides-Extra: ssh
Requires-Dist: paramiko>=3.0; extra == 'ssh'
Provides-Extra: test
Requires-Dist: pytest-qt>=4.4; extra == 'test'
Requires-Dist: pytest>=8.0; extra == 'test'
Description-Content-Type: text/markdown

<p align="center">
  <img src="docs/assets/logo_bg.png" width="120" alt="juxt logo">
</p>

# juxt

`juxt` is a fast desktop tool for visually comparing plots across multiple parameter axes. Define axes (model, date, data source, ...) and flip through the resulting image hypercube with keyboard navigation.

*juxt* comes from *juxtapose* — placing things side by side to compare. That's the whole idea: flip through congruent plots fast enough to visually identify differences.

## Install

```
pip install juxt
```

For SSH remote loading:

```
pip install juxt[ssh]
```

## Quick start

`juxt` accepts several forms as its first argument:

```bash
juxt /path/to/plots/                        # auto-detect axes from a directory of images
juxt "plots/{sensor}_{date}.png"            # explicit local template
juxt myhost:/path/to/plots/                 # remote directory over SSH
juxt "myhost:/path/{sensor}_{date}.png"     # remote template over SSH
juxt config.yaml                            # explicit config file
```

For directory and remote-directory modes, filenames are split on separators (`_` and `/` by default) and any position with more than one distinct value becomes an axis. You'll be prompted to name the axes on first run; use `-a` to skip.

## Config

### Auto-discover mode

Point juxt at a directory and it figures out the axes from the filenames:

```bash
juxt /path/to/plots/
```

Or with an explicit config:

```yaml
discover:
  directory: plots/
  separator: "_"
```

### Template mode

For full control, define the template and axes explicitly:

```yaml
template: "plots/{sensor}_{date}_{overpass}_{source}.png"
axes:
  sensor:   [ASCAT, SMAP, SMOS]
  date:     [2024-03-15, 2024-03-16]
  overpass: [AM, PM]
  source:   [L2, L3]
keys:
  s: sensor
  d: date
  o: overpass
  r: source
```

### Remote mode (SSH)

Images are downloaded over SFTP at startup and cached locally; navigation afterwards is identical to local use. Auth uses your SSH agent or `~/.ssh/config` key, with a password fallback.

```yaml
remote: myhost               # or user@myhost, or user@myhost:port
template: "/data/plots/{sensor}_{date}.png"
axes:
  sensor: [ASCAT, SMAP]
  date:   [2024-03-15, 2024-03-16]
```

Or pass the remote path directly on the command line — juxt will detect axes from the remote filenames automatically:

```bash
juxt myhost:/data/plots/
```

Requires the SSH extra: `pip install juxt[ssh]`



## Navigation

Default mode is **tap**. Each axis is assigned one letter key — tap it to step forward, hold Shift to step backward. Every navigation is a single keypress, no modifiers, no menus.

| Key | Action |
|---|---|
| `←` / `→` | cycle the active axis |
| `↑` / `↓` | cycle the secondary axis |
| lowercase letter | navigate +1 on that axis |
| uppercase letter | navigate −1 on that axis |
| `Ctrl`+letter | open value picker for that axis |
| `Space` | toggle between current and previous position |
| `Home` / `End` | jump to first / last value |
| `1`–`9` | jump to the Nth value |

Use `:mode tap|seek|pin` in the command bar to switch navigation modes.

## Command mode

Press `:` to open the command bar (vim-style). Tab-completion narrows candidates as you type.

| Command | Action |
|---|---|
| `:q` | quit |
| `:fit` | fit image to window |
| `:fit height` / `:fit width` | fit to height or width |
| `:zoom N` | set zoom to N% |
| `:fullscreen` | toggle fullscreen |
| `:mode twin\|multi\|case` | switch navigation mode |

## Controls

#### Zoom
| Key | Action |
|---|---|
| double-click | fit image to window |
| `0` | reset zoom to 100% |
| scroll wheel | step forward / backward on active axis |
| `Shift` + scroll wheel | step backward / forward on active axis |
| `Ctrl` + scroll wheel | zoom (anchored under cursor) |
| drag | pan |

#### View
| Key | Action |
|---|---|
| `Enter` | toggle fullscreen |
| `Ctrl+H` | toggle status bar |
