Metadata-Version: 2.4
Name: pyremoteplot
Version: 0.1.0
Summary: Display matplotlib figures from remote SSH sessions on your local machine
Author-email: Hwaipy Li <hwaipy@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/hwaipy/RemotePlot
Project-URL: Repository, https://github.com/hwaipy/RemotePlot
Project-URL: Issues, https://github.com/hwaipy/RemotePlot/issues
Keywords: matplotlib,ssh,remote,plot,tunnel,visualization
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: MacOS
Classifier: Operating System :: Microsoft :: Windows
Classifier: Programming Language :: Python :: 3
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: Topic :: Scientific/Engineering :: Visualization
Classifier: Topic :: System :: Networking
Classifier: Framework :: Matplotlib
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: matplotlib>=3.5
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"
Requires-Dist: numpy>=1.21; extra == "dev"
Requires-Dist: build; extra == "dev"
Requires-Dist: twine; extra == "dev"
Dynamic: license-file

# RemotePlot

Display matplotlib figures from a remote SSH session on your local machine — with full interactivity (zoom, pan, save).

Uses SSH's built-in reverse port forwarding as the transport layer. No VNC, no X11, no browser required.

## How it works

```
Remote Python  ──serialize──►  SSH tunnel  ──►  Local viewer (tkinter)
  plt.show()      figure data    -R 19840        interactive window
```

The remote machine runs a custom matplotlib backend that serializes figure data (axes, lines, scatter points, images…) as plain Python types and sends them through an SSH reverse tunnel. The local viewer reconstructs the figure using the local matplotlib installation.

Because only raw data is transferred — not Python objects — it works across different matplotlib and numpy versions.

## Requirements

| Machine | Requirements |
|---------|-------------|
| Local   | Python 3.9+, matplotlib, tkinter |
| Remote  | Python 3.9+, matplotlib |

## Installation

**Local machine:**
```bash
pip install pyremoteplot
```

**Remote machine:**
```bash
pip install pyremoteplot
```

> The package is published as `pyremoteplot` on PyPI but imports as `remoteplot`
> in Python (`import remoteplot`).

## Usage

**1. Start the viewer on your local machine:**
```bash
remoteplot viewer
```

**2. SSH into the remote machine with a reverse tunnel:**
```bash
# Using the built-in wrapper (recommended):
remoteplot ssh user@remote-host

# Or manually:
ssh -R 19840:localhost:19840 user@remote-host
```

**3. Run your plotting script on the remote machine:**
```python
import remoteplot
remoteplot.use()                    # set the backend

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 2 * np.pi, 200)
plt.plot(x, np.sin(x), label='sin')
plt.plot(x, np.cos(x), label='cos')
plt.legend()
plt.show()                          # figure appears on your local machine
```

Alternatively, set the backend via environment variable before running any script:
```bash
MPLBACKEND=module://remoteplot.backend python3 myscript.py
```

## Multiple programs

You can run several plotting programs on the remote simultaneously. Each figure appears in its own window on the local machine, titled with the remote process ID.

```bash
# Remote — all three display locally at the same time
python3 program_a.py &
python3 program_b.py &
python3 program_c.py &
```

## Animation / dynamic plots

Dynamic updates work out of the box. The backend rate-limits sends to 30 fps.

```python
import remoteplot; remoteplot.use()
import matplotlib.pyplot as plt
import numpy as np, time

fig, ax = plt.subplots()
ax.set_xlim(0, 2 * np.pi); ax.set_ylim(-1.5, 1.5)
line, = ax.plot([], [])
x = np.linspace(0, 2 * np.pi, 200)

for i in range(300):
    line.set_data(x, np.sin(x + i * 0.1))
    fig.canvas.draw()
    time.sleep(0.033)
```

## Supported plot types

Line plots, scatter plots, imshow / matshow, bar charts, histograms, text annotations, legends, log scales, subplots.

## Options

| Environment variable | Default | Description |
|----------------------|---------|-------------|
| `REMOTEPLOT_HOST`    | `localhost` | Viewer host to connect to |
| `REMOTEPLOT_PORT`    | `19840`     | Port (must match `-R` tunnel) |
| `REMOTEPLOT_MAX_FPS` | `30`        | Maximum send rate for animations |
