Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Publish to PyPI

on:
release:
types: [created]

jobs:
build-and-publish:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.11"

- name: Install build backend
run: |
pip install build twine

- name: Build package
run: python -m build

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.PYPI_API_TOKEN }}
31 changes: 31 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Run tests / CI

on:
push:
branches: [ main ]
pull_request:

jobs:
test:
runs-on: ubuntu-latest

strategy:
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
pip install -e .[test]
pip install pytest pytest-cov

- name: Run tests with coverage
run: |
pytest tests --cov=figctx --cov-report=term-missing --cov-fail-under=80
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
__pycache__
.pytest_cache
figctx.egg-info
.venv
.coverage
.pytest_cache
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# v0.1.0 - First Release


- Added features : single, multi, circuit
- Added categorical & sequential palettes

2 changes: 2 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
include README.md
recursive-include resource *.png *.svg
94 changes: 94 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Figctx - Figure Context for QuiME

This Package helps you to conveniently make figures with QuiME template

## How to install


```bash
pip install figctx
```

## Example1 (single figure context)

```python
import numpy as np
import figctx as ctx

testdata = np.random.rand(2,100)

with ctx.single(80, 60, './example.png') as (fig,ax):

ax.scatter(testdata[0], testdata[1], label='data')
ax.set_title('title')
```

![Example Single Figure](./resource/example.png)


## Example2 (multi figure context)

```python
import numpy as np
import figctx as ctx

testdata = np.random.rand(2,100)
testdata[0] = np.sort(testdata[0])

with ctx.multi(70, 150, 2, 1, [1], [1,2], './example2.png') as (fig, subfig):

c = subfig[0]

ax = c.subplots(1,1)
ax.tick_params(
direction='in',
width=1,
length=3,
pad=2
)
ax.plot(testdata[0], 2*testdata[1]+1, label='Test1')

temp = np.random.rand(100)
ax.plot(testdata[0], temp, label='Test2')

temp = np.random.rand(100)
ax.plot(testdata[0], 1.5*temp+0.5, label='Test3')

ax.legend()
ax.set_title('ax title1')

ax.set_xlabel('x')
ax.set_ylabel('y')

c.suptitle('fig suptitle1')

c = subfig[1]

axes = c.subplots(1,2)
for ax in axes:
ax.tick_params(
direction='in',
width=1,
length=3,
pad=2
)

ax = axes[0]

ax.plot(testdata[1], testdata[0])
ax.set_title('ax title2')

ax = axes[1]

ax.scatter(testdata[0], 0.5*testdata[1], label='Test3', color='black')
ax.scatter(2*testdata[1], 0.5*testdata[0], label='Test4')
ax.set_title('ax title3')

ax.legend()

c.suptitle('fig suptitle2')

fig.suptitle('Suptitle')
```

![Example Multi Figure](./resource/example2.png)
37 changes: 37 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
[build-system]
requires = ["setuptools>=61.0", "wheel", "build"]
build-backend = "setuptools.build_meta"


[project]
name = "figctx"
version = "0.1.0"
description = "Figure context manager for QuiME Lab"
readme = "README.md"
requires-python = ">=3.8"
authors = [{name = "Lee Chan-yeong", email = "ckckdud123@gmail.com"}]
license = {text="MIT"}
dependencies = ["matplotlib >=3.3"]


[tool.setuptools.packages.find]
where = ["src"]


[project.optional-dependencies]
test = ["pytest", "pytest-cov"]


[tool.pytest.ini_options]
pythonpath = ["src"]
testpaths = ["tests"]
addopts = "--cov=figctx --cov-report=term-missing --cov-fail-under=80"


[tool.coverage.run]
source = ["src/figctx"]
branch = true

[tool.coverage.report]
show_missing = true
skip_covered = true
Binary file added resource/example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resource/example2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions src/figctx/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from .context import single, multi, circuit

__all__ = ['single', 'multi', 'circuit']
__version__ = '1.0'
__license__ = 'MIT'
127 changes: 127 additions & 0 deletions src/figctx/context.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import matplotlib.pyplot as plt
from .palette import *
from contextlib import contextmanager
from cycler import cycler


def mti(mm):
return mm / 25.4


# single figure context manager
@contextmanager
def single(width_mm, height_mm, save_to, nrows=1, ncols=1):

color_cycle = cycler(color=palette_categorical)

custom_rc = {
'font.family': 'Arial',
'font.size': 7,
'axes.prop_cycle': color_cycle,
'axes.linewidth': 1,
'lines.linewidth': 1.5,
'lines.markersize': 3.5,
'figure.dpi': 500,
'savefig.dpi': 500,
}

with plt.rc_context(rc=custom_rc):
fig, axes = plt.subplots(
nrows=nrows,
ncols=ncols,
figsize=(mti(width_mm), mti(height_mm)),
layout='constrained'
)

if isinstance(axes, (list, tuple, plt.Axes)):
axs = axes.ravel() if hasattr(axes, 'ravel') else [axes]
else:
axs = axes

for ax in axs:
ax.tick_params(
direction='in',
width=1,
length=3,
pad=2
)

if len(axs) == 1:
yield fig, axs[0]
else:
yield fig, axs

fig.savefig(save_to)
plt.close(fig)


# multi figure context manager
@contextmanager
def multi(
width_mm, height_mm,
nrows, ncols, # (nrows, ncols) subfigure grid
width_ratios, height_ratios,
save_to,
wspace=0.08,
hspace=0.08,
constrained=True,
):

color_cycle = cycler(color=palette_categorical)

custom_rc = {
'font.family': 'Arial',
'font.size': 7,
'axes.prop_cycle': color_cycle,
'axes.linewidth': 1,
'lines.linewidth': 1.5,
'lines.markersize': 3.5,
'figure.dpi': 500,
'savefig.dpi': 500,
}

with plt.rc_context(rc=custom_rc):

fig = plt.figure(figsize=(mti(width_mm), mti(height_mm))
, constrained_layout=constrained)

subfigs = fig.subfigures(nrows, ncols,
wspace=wspace, hspace=hspace,
width_ratios=width_ratios, height_ratios=height_ratios)

if nrows==1 and ncols==1:
subfigs = [subfigs]

yield fig, subfigs

fig.savefig(save_to)
plt.close(fig)


# Pennylane-fit circuit context
@contextmanager
def circuit(width_mm, height_mm): # pragma: no cover

custom_rc = {
'font.family': 'Arial',
'font.size': 7,
'axes.linewidth': 1,
'lines.linewidth': 1.5,
'figure.dpi': 500,
'savefig.dpi': 500,
'patch.facecolor': '#E4F1F7',
'patch.edgecolor': '#0D4A70',
'patch.linewidth': 1.5,
'patch.force_edgecolor': True,
'lines.color': '#0D4A70',
'lines.linewidth': 1.5,
}

figsize=(mti(width_mm), mti(height_mm))

with plt.rc_context(rc=custom_rc):
fig, _ = plt.subplots()

yield fig, figsize

plt.close(fig)
Loading