Metadata-Version: 2.1
Name: pyfig
Version: 1.0.2
Summary: Windows-only utilities for arranging and managing Matplotlib and Mayavi figure windows.
Keywords: matplotlib,mayavi,windows,figure,window,gui
Author-Email: "Per A. Brodtkorb" <per.andreas.brodtkorb@gmail.com>
License: BSD 3-Clause License
         
         Copyright (c) 2026, Per A. Brodtkorb
         
         Redistribution and use in source and binary forms, with or without
         modification, are permitted provided that the following conditions are met:
         
         1. Redistributions of source code must retain the above copyright notice, this
            list of conditions and the following disclaimer.
         
         2. Redistributions in binary form must reproduce the above copyright notice,
            this list of conditions and the following disclaimer in the documentation
            and/or other materials provided with the distribution.
         
         3. Neither the name of the copyright holder nor the names of its
            contributors may be used to endorse or promote products derived from
            this software without specific prior written permission.
         
         THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
         AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
         IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
         DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
         FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
         DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
         SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
         CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
         OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
         OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
         
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Programming Language :: Python :: 3
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: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Operating System :: Microsoft :: Windows
Project-URL: Homepage, https://github.com/pbrod/pyfig
Project-URL: Repository, https://github.com/pbrod/pyfig
Project-URL: Issues, https://github.com/pbrod/pyfig/issues
Project-URL: Documentation, https://github.com/pbrod/pyfig#readme
Project-URL: Changelog, https://github.com/pbrod/pyfig/blob/main/CHANGELOG.md
Requires-Python: >=3.10
Requires-Dist: pywin32; platform_system == "Windows"
Provides-Extra: plot
Requires-Dist: matplotlib>=3.8.0; extra == "plot"
Provides-Extra: wx
Requires-Dist: wxPython>=4.2; extra == "wx"
Description-Content-Type: text/markdown

# pyfig

[![PyPI version](https://img.shields.io/pypi/v/pyfig.svg)](https://pypi.org/project/pyfig/)
[![Python versions](https://img.shields.io/pypi/pyversions/pyfig.svg)](https://pypi.org/project/pyfig/)
[![License](https://img.shields.io/pypi/l/pyfig.svg)](LICENSE)
[![CI Status](https://github.com/pbrod/pyfig/actions/workflows/ci-test.yml/badge.svg)](https://github.com/pbrod/pyfig/actions/workflows/ci-test.yml)
[![Ruff](https://img.shields.io/badge/lint-ruff-blueviolet)](https://github.com/astral-sh/ruff)
[![Mypy](https://img.shields.io/badge/type--checked-mypy-blue)](http://mypy-lang.org/)
[![Downloads](https://pepy.tech/badge/pyfig/month)](https://pepy.tech/project/pyfig)

Interactive figure and window management for Windows.

`pyfig` is a Windows-only Python package for interactively arranging and managing figure windows created by Matplotlib, Mayavi/TVTK, and Chaco.

It provides convenient functions for:

- Tiling, stacking, piling, and cascading windows
- Minimizing, maximizing, restoring, and hiding figures
- Snapping windows to screen regions
- Cycling through figures
- Closing or keeping selected figures
- Querying figure positions and screen geometry

The package uses the Win32 API and works directly with figure windows after they have been created.

---

## Gallery

The examples below use Matplotlib figures, but pyfig can also manipulate
Mayavi/TVTK and Chaco figure windows.

### Tile all open figures

Arrange all open figures in a non-overlapping grid:

```python
from pyfig import fig

fig.tile()
```

![Tile layout](https://raw.githubusercontent.com/pbrod/pyfig/main/docs/images/tile.png)

### Stack all open figures with partial overlap

Arrange figures with a staircase-style overlap:

```python
from pyfig import fig

fig.stack()
```

![Stack layout](https://raw.githubusercontent.com/pbrod/pyfig/main/docs/images/stack.png)


### Snap a figure to the right side of the screen

Snap figure number four to the right half of the screen.

```python
fig.snap_right(4)
```

![Snap-right layout](https://raw.githubusercontent.com/pbrod/pyfig/main/docs/images/snap_right.png)

---

## Features

The screenshots above demonstrate only a subset of the functionality available in pyfig.

### Window management

```python
fig.maximize()
fig.minimize()
fig.restore()
fig.hide()
```

### Layout management

```python
fig.tile()
fig.stack()
fig.pile()
fig.cascade()
```

### Screen snapping

```python
fig.snap_left()
fig.snap_right()
fig.snap_top()
fig.snap_bottom()
```

### Figure selection

```python
fig.close(1, 2)
fig.keep(3)
```

### Interactive cycling

```python
fig.cycle()
fig.cycle(pairs=2)
fig.cycle(interval=1.0)
```

---

## Requirements

- Windows
- Python 3.10+
- pywin32

---

## Installation

### Matplotlib support

```bash
pip install pyfig[plot]
```

### Core package

```bash
pip install pyfig
```

### wxPython support

```bash
pip install pyfig[wx]
```

### Everything

```bash
pip install pyfig[plot,wx]
```

---

## Quick Check

After installation, verify that pyfig is working:

```python
import pyfig

pyfig.test()
```

---

## Quick Start

Create some figures:

```python
import matplotlib.pyplot as plt

for i in range(1, 5):
    plt.figure(i)
```

Arrange them:

```python
from pyfig import fig

fig.tile()
```

Stack them:

```python
fig.stack()
```

Pile them:

```python
fig.pile()
```

Maximize a figure:

```python
fig.maximize(4)
```

Close all figures:

```python
fig.close()
```

---

## Selecting Figures

By default, functions operate on all open figures:

```python
fig.tile()
```

You can also target specific figures:

```python
fig.maximize(4)
fig.snap_right(4)
```

or multiple figures:

```python
fig.stack(1, 2, 3)
fig.tile([1, 2, 3, 4])
```

---

## Examples

### Tile all open figures

```python
import matplotlib.pyplot as plt
from pyfig import fig

for i in range(1, 5):
    plt.figure(i)

fig.tile()

# Tile figures in pairs
fig.tile(pairs=2)
```

### Keep only selected figures

```python
fig.keep(1, 3)
```

### Snap a figure to the right side of the screen

```python
fig.snap_right(4)
```

### Center all figures

```python
fig.center()
```

### Cycle through open figures

```python
fig.cycle(interval=1.0)
```

### Cycle through figures in pairs

```python
fig.cycle(pairs=2)
```

---

## Public API

All functionality is available through the `pyfig.fig` module:

### Window operations

```python
close()
hide()
restore()
minimize()
maximize()
keep()
cycle()
```

### Layout operations

```python
tile()
stack()
pile()
cascade()
center()
set_size()
```

### Screen snapping

```python
snap_left()
snap_right()
snap_top()
snap_bottom()
```

### Information functions

```python
find_all_figure_numbers()
find_figure_handles()

get_window_position_and_size()
get_screen_position_and_size()
```

### Configuration

```python
set_prefer_wx()
```

---

## wxPython Support

If wxPython is installed, pyfig can provide a GUI dialog for figure cycling.

Enable it by setting the environment variable:

```bash
set FIG_USE_WX=1
```

or programmatically:

```python
from pyfig import fig

fig.set_prefer_wx(True)
```

Without wxPython, pyfig automatically falls back to a console-based interface.

---

## Testing

pyfig includes a convenience function for running its test suite.

Run all tests:

```python
import pyfig

pyfig.test()
```

Run with additional pytest options:

```python
import pyfig

pyfig.test("-v")
```

Show available pytest options:

```python
import pyfig

pyfig.test("--help")
```

For development, tests may also be executed directly using PDM:

```bash
pdm run tests
```

or:

```bash
pdm all-tests
```

---

## License

BSD License.

See the `LICENSE` file for details.