Skip to content

Commit f0fa7ca

Browse files
committed
added layout_v2 to sp. namespace
1 parent cee7f1d commit f0fa7ca

File tree

3 files changed

+62
-23
lines changed

3 files changed

+62
-23
lines changed

notebooks/sp_layout.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
# %%
1717
import numpy as np
18+
1819
import spaceplot as sp
1920

2021
sp.display('dark', retina=True, transparent=False)
@@ -26,6 +27,7 @@
2627

2728
# %%
2829
import layout_v2 as l2
30+
2931
import spaceplot.appearance.layout as ly
3032
from spaceplot.appearance import tools as aptls
3133

@@ -62,8 +64,8 @@
6264
axs = sp.montage_plot(1, panel_size=(4.5, 3.5))
6365
axs.scatter(datax, datay)
6466

65-
l2.tick_grid_visibility(axs, axis='x', ticks='1', minor=True, grid='major')
66-
l2.tick_grid_visibility(axs, axis='y', ticks='1', minor=True, grid='major')
67+
l2.set_tick_grid_visibility(axs, axis='x', ticks='1', minor=True, grid='major')
68+
l2.set_tick_grid_visibility(axs, axis='y', ticks='1', minor=True, grid='major')
6769

6870

6971
# %%
@@ -78,6 +80,7 @@
7880

7981
import numpy as np
8082

83+
8184
def calculate_figure_size(design, ref_panel_idx, ref_panel_size, w_ratios, h_ratios):
8285
"""
8386
Calculate the figure size needed for a given subplot design.

src/spaceplot/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from .appearance import palettes as plts
77
from .appearance.display import Theme, display
88
from .appearance.layout import layout
9+
from .appearance.layout_v2 import layout_v2
910
from .montage_plot import montage_plot
1011
from .plotting import plt_category, plt_continous
1112

Lines changed: 56 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,25 @@
1+
from collections.abc import Iterable
2+
from itertools import cycle
13
from typing import Literal
24

35
import spaceplot.appearance.layout as ly
46

7+
from .. import utils
8+
59
_tick_vis = Literal[True, False, '1', '2', 'both', 'all', None]
610
_grid_vis = Literal[True, False, 'both', 'major', 'minor', None]
711

12+
major_grid_style = 'solid'
13+
minor_grid_style = (0, (1, 2))
14+
815
# TODO tick param hygiene... there are likely some grid, tick, minor params that don't belong
16+
# I think currently, tick visibility will override settings from other setters... need to fix that
917
# implement allowed_params check like started in layout_v1
1018
# find solution for tick_labels
1119
# parse_axis_params needs better input filtering... currently everything goes through
1220

1321

14-
def layout(
22+
def layout_v2(
1523
axs,
1624
*,
1725
title: str | list = None,
@@ -51,14 +59,14 @@ def layout(
5159
title_settings = get_hook_dict(static_kwargs, 'title_', remove_hook=True)
5260

5361
# ensure axs is a list
54-
if not isinstance(axs, ly.Iterable):
62+
if not isinstance(axs, Iterable):
5563
axs = [axs]
5664
if not isinstance(title, list):
5765
title = [title]
5866

5967
ly.handle_abc_labels(axs, abc, **kwargs)
6068

61-
pairs = list(zip(axs, ly.cycle(title)))
69+
pairs = list(zip(axs, cycle(title)))
6270

6371
for ax, title in pairs:
6472
viz(ax, ticks=ticks, grid=grid, minor=minor, **kwargs)
@@ -86,10 +94,14 @@ def layout(
8694

8795

8896
def handle_tick_settings(ax, axis, tick_settings):
89-
if len(tick_settings) == 0:
90-
return
97+
# Set default grid style, since rcParams don't offer minor grid style
98+
if 'grid_linestyle' not in tick_settings:
99+
tick_settings['grid_linestyle'] = [major_grid_style, minor_grid_style]
100+
101+
# if len(tick_settings) == 0:
102+
# return
91103

92-
majmin_settings = {k: ly.utils.maj_min_args(maj_min=v) for k, v in tick_settings.items()}
104+
majmin_settings = {k: utils.maj_min_args(maj_min=v) for k, v in tick_settings.items()}
93105

94106
for i, which in enumerate(['major', 'minor']):
95107
tick_settings_select = {k: v[i] for k, v in majmin_settings.items()}
@@ -114,14 +126,21 @@ def viz(
114126
if v is not None
115127
}
116128

117-
viz_kwargs = {k: v for k, v in kwargs.items() if any([k.endswith(h) for h in ['ticks', 'grid', 'minor']])}
129+
ax_below = False if 'grid_zorder' in kwargs else True
130+
ax.set_axisbelow(ax_below)
131+
132+
# filter kwargs and merge with args to a single dict
133+
viz_kwargs = {k: v for k, v in kwargs.items() if any([k.endswith(h) for h in ['_ticks', '_grid', '_minor']])}
118134
merged = {**viz_args, **viz_kwargs}
135+
136+
# break down merged into x_ and y_ specific params
119137
viz_params = parse_axis_params(params=merged)
120138
xviz = get_hook_dict(viz_params, 'x_', remove_hook=True)
121139
yviz = get_hook_dict(viz_params, 'y_', remove_hook=True)
122140

123-
tick_grid_visibility(ax, axis='x', **xviz)
124-
tick_grid_visibility(ax, axis='y', **yviz)
141+
# apply settings
142+
set_tick_grid_visibility(ax, axis='x', **xviz)
143+
set_tick_grid_visibility(ax, axis='y', **yviz)
125144

126145

127146
def parse_grid_visibility(
@@ -144,30 +163,46 @@ def parse_grid_visibility(
144163
return major_setter, minor_setter
145164

146165

147-
def tick_grid_visibility(ax, *, axis='x', ticks=None, minor=None, grid=None):
166+
def set_tick_grid_visibility(ax, *, axis='x', ticks=None, minor=None, grid=None):
167+
# mapping for tick visibility in x/y axis
168+
p1 = 'bottom' if axis == 'x' else 'left'
169+
p2 = 'top' if axis == 'x' else 'right'
170+
171+
# this determines the logic for tick visibility
172+
def apply_logic(value):
173+
logic_1 = True if value in ('1', 'both', 'all', True) else False
174+
logic_2 = True if value in ('2', 'both', 'all') else False
175+
return logic_1, logic_2
176+
148177
if ticks is None:
149178
viz = {}
179+
# viz_min = {}
150180
else:
151-
logic_1 = True if ticks in ('1', 'both', 'all', True) else False
152-
logic_2 = True if ticks in ('2', 'both', 'all') else False
181+
logic_1, logic_2 = apply_logic(ticks)
153182

154183
viz = {
155-
'bottom': logic_1,
156-
'labelbottom': logic_1,
157-
'top': logic_2,
158-
'labeltop': logic_2,
184+
p1: logic_1,
185+
f'label{p1}': logic_1,
186+
p2: logic_2,
187+
f'label{p2}': logic_2,
159188
}
160189

190+
logic_1, logic_2 = apply_logic(minor)
191+
192+
viz_min = {
193+
p1: viz.get(p1, logic_1),
194+
f'label{p1}': viz.get(f'label{p1}', logic_1),
195+
p2: viz.get(p2, logic_2),
196+
f'label{p2}': viz.get(f'label{p2}', logic_2),
197+
}
198+
161199
grid_maj, grid_min = parse_grid_visibility(grid=grid, minor=minor)
162200

163201
axis_obj = getattr(ax, f'{axis}axis')
164202

165203
axis_obj.set_tick_params(which='major', gridOn=grid_maj, **viz)
166-
if minor:
167-
axis_obj.set_tick_params(which='minor', gridOn=grid_min, **viz)
168-
axis_obj.minorticks_on()
169-
if minor is False:
170-
axis_obj.minorticks_off()
204+
axis_obj.minorticks_on()
205+
axis_obj.set_tick_params(which='minor', gridOn=grid_min, **viz_min)
171206

172207

173208
def get_hook_dict(params, hook, remove_hook: bool = True) -> dict:

0 commit comments

Comments
 (0)