55import textwrap
66import warnings
77from collections import defaultdict
8- from collections .abc import Mapping
8+ from collections .abc import Callable , Sequence
99from copy import deepcopy
1010from pathlib import Path
11- from typing import Any , Callable , Sequence
11+ from typing import TYPE_CHECKING , Any
1212
1313import matplotlib .pyplot as plt
1414import numpy as np
1515import pandas as pd
16- from Bio .Phylo .BaseTree import Tree
17- from matplotlib .axes import Axes
1816from matplotlib .collections import PatchCollection
1917from matplotlib .colorbar import Colorbar
2018from matplotlib .colors import Colormap , Normalize
21- from matplotlib .figure import Figure
22- from matplotlib .patches import Patch
2319from matplotlib .projections .polar import PolarAxes
2420
2521from pycirclize import config , utils
3935 to_cytoband_tooltip ,
4036 to_link_tooltip ,
4137)
42- from pycirclize .track import Track
4338from pycirclize .tree import TreeViz
44- from pycirclize .typing import Numeric
39+
40+ if TYPE_CHECKING :
41+ from collections .abc import Mapping
42+
43+ from Bio .Phylo .BaseTree import Tree
44+ from matplotlib .axes import Axes
45+ from matplotlib .figure import Figure
46+ from matplotlib .patches import Patch
47+
48+ from pycirclize .track import Track
49+ from pycirclize .typing import Numeric
4550
4651
4752class Circos :
@@ -57,7 +62,7 @@ def __init__(
5762 endspace : bool = True ,
5863 sector2clockwise : dict [str , bool ] | None = None ,
5964 show_axis_for_debug : bool = False ,
60- ):
65+ ) -> None :
6166 """
6267 Parameters
6368 ----------
@@ -87,7 +92,7 @@ def __init__(
8792 if isinstance (space , Sequence ):
8893 if len (space ) != space_num :
8994 raise ValueError (f"{ space = } is invalid.\n Length of space list must be { space_num } ." ) # fmt: skip # noqa: E501
90- space_list = list (space ) + [ 0 ]
95+ space_list = [ * list (space ), 0 ]
9196 space_deg_size = sum (space )
9297 else :
9398 space_list = [space ] * space_num + [0 ]
@@ -181,22 +186,22 @@ def ax(self) -> PolarAxes:
181186 ############################################################
182187
183188 @classmethod
184- def set_tooltip_enabled (cls , enabled : bool = True ):
189+ def set_tooltip_enabled (cls , enabled : bool = True ) -> None :
185190 """Enable/disable tooltip annotation using ipympl"""
186191 if enabled :
187192 try :
188- import ipympl # noqa: F401
189- from IPython import get_ipython # type: ignore
193+ import ipympl # noqa: F401, PLC0415
194+ from IPython import get_ipython # noqa: PLC0415
190195
191196 get_ipython ().run_line_magic ("matplotlib" , "widget" )
192197 config .tooltip .enabled = True
193198 except Exception :
194- warnings .warn ("Failed to enable tooltip. To enable tooltip, an interactive python environment such as jupyter and ipympl installation are required." ) # fmt: skip # noqa: E501
199+ warnings .warn ("Failed to enable tooltip. To enable tooltip, an interactive python environment such as jupyter and ipympl installation are required." , stacklevel = 2 ) # fmt: skip # noqa: E501
195200 else :
196201 config .tooltip .enabled = False
197202
198203 @staticmethod
199- def radar_chart (
204+ def radar_chart ( # noqa: PLR0912, PLR0915
200205 table : str | Path | pd .DataFrame | RadarTable ,
201206 * ,
202207 r_lim : tuple [float , float ] = (0 , 100 ),
@@ -267,6 +272,7 @@ def radar_chart(
267272 circos : Circos
268273 Circos instance initialized for radar chart
269274 """
275+ # TODO: Refactor complex codes
270276 if not vmin < vmax :
271277 raise ValueError (f"vmax must be larger than vmin ({ vmin = } , { vmax = } )" )
272278 size = vmax - vmin
@@ -306,8 +312,8 @@ def radar_chart(
306312 if grid_label_formatter :
307313 text = grid_label_formatter (v )
308314 else :
309- v = float (f"{ v :.9f} " ) # Correct rounding error
310- text = f"{ v :.0f} " if math .isclose (int (v ), float ( v )) else str (v )
315+ v2 = float (f"{ v :.9f} " ) # Correct rounding error
316+ text = f"{ v2 :.0f} " if math .isclose (int (v2 ), v2 ) else str (v2 )
311317 track .text (text , 0 , r , ** grid_label_kws )
312318 # Plot vertical grid line
313319 for p in x [:- 1 ]:
@@ -319,7 +325,7 @@ def radar_chart(
319325 else :
320326 row_name2color = cmap
321327 for row_name , values in radar_table .row_name2values .items ():
322- y = values + [ values [0 ]]
328+ y = [ * values , values [0 ]]
323329 color = row_name2color [row_name ]
324330 line_kws = line_kws_handler (row_name ) if line_kws_handler else {}
325331 line_kws .setdefault ("lw" , 1.0 )
@@ -441,13 +447,12 @@ def chord_diagram(
441447 if isinstance (cmap , str ):
442448 utils .ColorCycler .set_cmap (cmap )
443449 colors = utils .ColorCycler .get_color_list (len (names ))
444- name2color = dict (zip (names , colors ))
450+ name2color = dict (zip (names , colors , strict = True ))
451+ elif isinstance (cmap , defaultdict ):
452+ name2color = cmap
445453 else :
446- if isinstance (cmap , defaultdict ):
447- name2color = cmap
448- else :
449- name2color : dict [str , str ] = defaultdict (lambda : "grey" )
450- name2color .update (cmap )
454+ name2color : dict [str , str ] = defaultdict (lambda : "grey" )
455+ name2color .update (cmap )
451456
452457 # Initialize circos sectors
453458 circos = Circos (matrix .to_sectors (), start , end , space = space , endspace = endspace )
@@ -876,10 +881,8 @@ def link(
876881 if "lw" not in kwargs and "linewidth" not in kwargs :
877882 kwargs .update (dict (lw = 0.1 ))
878883
879- if not allow_twist :
880- # Resolve twist
881- if (rad_end1 - rad_start1 ) * (rad_end2 - rad_start2 ) > 0 :
882- rad_start2 , rad_end2 = rad_end2 , rad_start2
884+ if not allow_twist and (rad_end1 - rad_start1 ) * (rad_end2 - rad_start2 ) > 0 :
885+ rad_start2 , rad_end2 = rad_end2 , rad_start2
883886
884887 # Set tooltip content
885888 gid = gen_gid ("link" )
0 commit comments