Skip to content

Commit

Permalink
Merge pull request #46 from moshi4/develop
Browse files Browse the repository at this point in the history
Bump to v1.2.0
  • Loading branch information
moshi4 authored Dec 26, 2023
2 parents 2e186d3 + 67cb7fc commit 65b3559
Show file tree
Hide file tree
Showing 14 changed files with 901 additions and 772 deletions.
19 changes: 7 additions & 12 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
python-version: ["3.8", "3.9", "3.10", "3.11"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
steps:
- name: Checkout
uses: actions/checkout@v3
Expand All @@ -24,19 +24,14 @@ jobs:
with:
python-version: ${{ matrix.python-version }}

- name: Install Poetry
run: |
curl -sSL https://install.python-poetry.org | python3 -
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install dependencies
run: pip install -e . pytest pytest-cov ruff

- name: Install Dependencies
run: poetry install -n

- name: Run black format check
run: poetry run black src tests --check --diff --verbose
- name: Run ruff format check
run: ruff format --check --diff

- name: Run ruff lint check
run: poetry run ruff .
run: ruff check --diff

- name: Run pytest
run: poetry run pytest tests --tb=line --cov=src --cov-report=xml --cov-report=term
run: pytest tests --tb=line --cov=src --cov-report=xml --cov-report=term
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
- [API Usage](#api-usage)
- [Code Example](#code-example)
- [Not Implemented Features](#not-implemented-features)
- [Star History](#star-history)

## Overview

Expand Down Expand Up @@ -231,3 +232,7 @@ I may implement them when I feel like it.
- Plot boxplot
- Plot violin
- Label position auto adjustment

## Star History

[![Star History Chart](https://api.star-history.com/svg?repos=moshi4/pyCirclize&type=Date)](https://star-history.com/#moshi4/pyCirclize&Date)
2 changes: 1 addition & 1 deletion docs/circos_plot.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@
" trna_track = sector.add_track((67, 74), r_pad_ratio=0.1)\n",
" for feature in seqid2features[sector.name]:\n",
" if feature.type == \"CDS\":\n",
" if feature.strand == 1:\n",
" if feature.location.strand == 1:\n",
" f_cds_track.genomic_features([feature], fc=\"tomato\")\n",
" else:\n",
" r_cds_track.genomic_features([feature], fc=\"skyblue\")\n",
Expand Down
47 changes: 47 additions & 0 deletions docs/plot_api_example.ipynb

Large diffs are not rendered by default.

1,273 changes: 577 additions & 696 deletions poetry.lock

Large diffs are not rendered by default.

45 changes: 27 additions & 18 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "pyCirclize"
version = "1.1.0"
version = "1.2.0"
description = "Circular visualization in Python"
authors = ["moshi4"]
license = "MIT"
Expand All @@ -26,25 +26,32 @@ minversion = "6.0"
addopts = "--cov=src --tb=line --cov-report=xml --cov-report=term"
testpaths = ["tests"]

# Lint Rules: https://beta.ruff.rs/docs/rules
[tool.ruff]
select = ["E", "F", "W", "I", "D", "B"]
ignore = [
"D100",
"D101",
"D104",
"D105",
"D205",
"D400",
"D401",
"D403",
"D415",
"B905",
]
src = ["src", "tests"]
line-length = 88

[tool.ruff.pydocstyle]
# Lint Rules: https://docs.astral.sh/ruff/rules/
[tool.ruff.lint]
select = [
"F", # pyflakes
"E", # pycodestyle (Error)
"W", # pycodestyle (Warning)
"I", # isort
"D", # pydocstyle
]
ignore = [
"D100", # Missing docstring in public module
"D101", # Missing docstring in public class
"D104", # Missing docstring in public package
"D105", # Missing docstring in magic method
"D205", # 1 blank line required between summary line and description
"D400", # First line should end with a period
"D401", # First line should be in imperative mood
"D403", # First word of the first line should be properly capitalized
"D415", # First line should end with a period, question mark, or exclamation point
]

[tool.ruff.lint.pydocstyle]
convention = "numpy"

[tool.poetry.dependencies]
Expand All @@ -55,15 +62,17 @@ numpy = ">=1.21.1"
pandas = ">=1.3.5"

[tool.poetry.group.dev.dependencies]
ruff = ">=0.1.6"
pytest = ">=7.1.2"
black = ">=22.10.0"
ruff = ">=0.0.264"
pytest-cov = ">=4.0.0"
ipykernel = ">=6.13.0"

[tool.poetry.group.docs.dependencies]
mkdocs = ">=1.2"
mkdocstrings = { extras = ["python"], version = ">=0.19.0" }
mkdocs-jupyter = ">=0.21.0"
mkdocs-material = ">=8.2"
black = ">=22.10.0"

[build-system]
requires = ["poetry-core>=1.0.0"]
Expand Down
2 changes: 1 addition & 1 deletion src/pycirclize/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from pycirclize.circos import Circos

__version__ = "1.1.0"
__version__ = "1.2.0"

__all__ = [
"Circos",
Expand Down
93 changes: 84 additions & 9 deletions src/pycirclize/circos.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import math
import textwrap
from collections import defaultdict
from collections.abc import Mapping
from copy import deepcopy
from pathlib import Path
from typing import Any, Callable
Expand All @@ -21,7 +22,13 @@

from pycirclize import config, utils
from pycirclize.parser import Bed, Matrix
from pycirclize.patches import ArcLine, ArcRectangle, BezierCurve, Line
from pycirclize.patches import (
ArcLine,
ArcRectangle,
BezierCurveLine,
BezierCurveLink,
Line,
)
from pycirclize.sector import Sector
from pycirclize.track import Track
from pycirclize.tree import TreeViz
Expand All @@ -32,20 +39,20 @@ class Circos:

def __init__(
self,
sectors: dict[str, int] | dict[str, float],
sectors: Mapping[str, int | float],
start: float = 0,
end: float = 360,
*,
space: float | list[float] = 0,
endspace: bool = True,
sector2start_pos: dict[str, int] | dict[str, float] | None = None,
sector2start_pos: Mapping[str, int | float] | None = None,
sector2clockwise: dict[str, bool] | None = None,
show_axis_for_debug: bool = False,
):
"""
Parameters
----------
sectors : dict[str, int] | dict[str, float]
sectors : Mapping[str, int | float]
Sector name & size dict
start : float, optional
Plot start degree (`-360 <= start < end <= 360`)
Expand All @@ -55,7 +62,7 @@ def __init__(
Space degree(s) between sector
endspace : bool, optional
If True, insert space after the end sector
sector2start_pos : dict[str, int] | dict[str, float] | None, optional
sector2start_pos : Mapping[str, int | float] | None, optional
Sector name & start position dict. By default, `start_pos=0`.
sector2clockwise : dict[str, bool] | None, optional
Sector name & clockwise bool dict. By default, `clockwise=True`.
Expand Down Expand Up @@ -693,7 +700,7 @@ def link(
rad_start2, rad_end2 = rad_end2, rad_start2

# Create bezier curve path patch
bezier_curve = BezierCurve(
bezier_curve_link = BezierCurveLink(
rad_start1,
rad_end1,
r1,
Expand All @@ -705,7 +712,75 @@ def link(
arrow_length_ratio,
**kwargs,
)
self._patches.append(bezier_curve)
self._patches.append(bezier_curve_link)

def link_line(
self,
sector_pos1: tuple[str, float],
sector_pos2: tuple[str, float],
r1: float | None = None,
r2: float | None = None,
*,
color: str = "black",
height_ratio: float = 0.5,
direction: int = 0,
arrow_height: float = 3.0,
arrow_width: float = 2.0,
**kwargs,
) -> None:
"""Plot link line to specified position within or between sectors
Parameters
----------
sector_pos1 : tuple[str, float]
Link line sector position1 (name, position)
sector_pos2 : tuple[str, float]
Link line sector position2 (name, position)
r1 : float | None, optional
Link line radius end position for sector_pos1.
If None, lowest radius position of track in target sector is set.
r2 : float | None, optional
Link line radius end position for sector_pos2.
If None, lowest radius position of track in target sector is set.
color : str, optional
Link line color
height_ratio : float, optional
Bezier curve height ratio
direction : int, optional
`0`: No direction edge shape (Default)
`1`: Forward direction arrow edge shape (pos1 -> pos2)
`-1`: Reverse direction arrow edge shape (pos1 <- pos2)
`2`: Bidirectional arrow edge shape (pos1 <-> pos2)
arrow_height : float, optional
Arrow height size (Radius unit)
arrow_width : float, optional
Arrow width size (Degree unit)
**kwargs : dict, optional
Patch properties (e.g. `lw=1.0, ls="dashed", ...`)
<https://matplotlib.org/stable/api/_as_gen/matplotlib.patches.Patch.html>
"""
# Set data for plot link
name1, pos1 = sector_pos1
name2, pos2 = sector_pos2
sector1, sector2 = self.get_sector(name1), self.get_sector(name2)
r1 = sector1.get_lowest_r() if r1 is None else r1
r2 = sector2.get_lowest_r() if r2 is None else r2
rad_pos1, rad_pos2 = sector1.x_to_rad(pos1), sector2.x_to_rad(pos2)

kwargs.update(color=color)

bezier_curve_line = BezierCurveLine(
rad_pos1,
r1,
rad_pos2,
r2,
height_ratio,
direction,
arrow_height,
arrow_width,
**kwargs,
)
self._patches.append(bezier_curve_line)

def colorbar(
self,
Expand Down Expand Up @@ -809,7 +884,7 @@ def plotfig(
for plot_func in self._get_all_plot_funcs():
plot_func(ax)

return fig # type: ignore
return fig

def savefig(
self,
Expand Down Expand Up @@ -887,7 +962,7 @@ def _initialize_figure(
"""
fig = plt.figure(figsize=figsize, dpi=dpi, tight_layout=True)
ax = fig.add_subplot(projection="polar")
return fig, ax # type: ignore
return fig, ax

def _initialize_polar_axes(self, ax: PolarAxes) -> None:
"""Initialize polar axes params
Expand Down
Loading

0 comments on commit 65b3559

Please sign in to comment.