Skip to content

Commit c9f2170

Browse files
committed
Add coord polar and radial coverage tests
1 parent 49bcd6d commit c9f2170

1 file changed

Lines changed: 257 additions & 0 deletions

File tree

tests/test_coord_polar.py

Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,72 @@
11
import numpy as np
22
import pandas as pd
3+
from matplotlib import pyplot as plt
4+
from numpy.testing import assert_allclose
35

6+
from plotnine import (
7+
aes,
8+
coord_radial,
9+
element_blank,
10+
element_line,
11+
geom_col,
12+
ggplot,
13+
theme,
14+
)
415
from plotnine.coords.coord_polar import coord_polar
16+
from plotnine.scales import scale_x_continuous, scale_y_continuous
17+
18+
19+
def trained_scales(
20+
x=(0, 10),
21+
y=(0, 10),
22+
x_breaks=(0, 5, 10),
23+
y_breaks=(0, 5, 10),
24+
x_labels=("0", "5", "10"),
25+
y_labels=("0", "5", "10"),
26+
):
27+
scale_x = scale_x_continuous(breaks=x_breaks, labels=x_labels)
28+
scale_y = scale_y_continuous(breaks=y_breaks, labels=y_labels)
29+
scale_x.train(x)
30+
scale_y.train(y)
31+
return scale_x, scale_y
32+
33+
34+
def test_coord_polar_setup_panel_params_theta_x():
35+
scale_x, scale_y = trained_scales(
36+
y_breaks=(0, 2, 5, 10),
37+
y_labels=("0", "2", "5", "10"),
38+
)
39+
coord = coord_polar(theta="x", start=np.pi / 4, expand=False)
40+
41+
panel_params = coord.setup_panel_params(scale_x, scale_y)
42+
43+
assert coord.params["theta_range"] == (0, 10)
44+
assert coord.params["r_range"] == (0, 10)
45+
assert panel_params.x.range == (np.pi / 4, np.pi / 4 + 2 * np.pi)
46+
assert panel_params.x.breaks == []
47+
assert panel_params.x.labels == []
48+
assert panel_params.y.breaks == [0, 2, 5, 10]
49+
50+
51+
def test_coord_polar_setup_panel_params_theta_y():
52+
scale_x, scale_y = trained_scales(
53+
x_breaks=(0, 2, 5, 10),
54+
x_labels=("0", "2", "5", "10"),
55+
)
56+
coord = coord_polar(theta="y", expand=False)
57+
58+
panel_params = coord.setup_panel_params(scale_x, scale_y)
59+
60+
assert coord.params["theta_range"] == (0, 10)
61+
assert coord.params["r_range"] == (0, 10)
62+
assert panel_params.y.breaks == [0, 2, 5, 10]
63+
64+
65+
def test_coord_polar_to_radians_zero_width_range():
66+
coord = coord_polar()
67+
coord.params = {"theta_range": (1, 1)}
68+
69+
assert_allclose(coord._to_radians(np.array([1, 2, 3])), [0, 0, 0])
570

671

772
def test_coord_polar_transforms_segment_endpoints_theta_x():
@@ -28,3 +93,195 @@ def test_coord_polar_transforms_segment_endpoints_theta_y():
2893
assert out.loc[0, "y"] == 1
2994
assert np.isclose(out.loc[0, "xend"], 2 * np.pi)
3095
assert out.loc[0, "yend"] == 2
96+
97+
98+
def test_coord_polar_transforms_theta_y_without_endpoints():
99+
coord = coord_polar(theta="y")
100+
coord.params = {"theta_range": (0, 10), "r_range": (0, 10)}
101+
data = pd.DataFrame({"x": [1], "y": [5]})
102+
103+
out = coord.transform(data, None)
104+
105+
assert_allclose(out.loc[0, "x"], np.pi)
106+
assert out.loc[0, "y"] == 1
107+
108+
109+
def test_coord_polar_munches_before_radian_transform():
110+
coord = coord_polar()
111+
coord.params = {"theta_range": (0, 10), "r_range": (0, 10)}
112+
data = pd.DataFrame({"x": [0, 10], "y": [1, 2], "group": [1, 1]})
113+
114+
out = coord.transform(data, None, munch=True)
115+
116+
assert len(out) > len(data)
117+
assert out["x"].between(0, 2 * np.pi).all()
118+
119+
120+
def test_coord_polar_leaves_non_position_data_unchanged():
121+
coord = coord_polar()
122+
data = pd.DataFrame({"label": ["A"]})
123+
124+
assert coord.transform(data, None) is data
125+
126+
127+
def test_coord_polar_distance_and_backtransform_theta_x():
128+
coord = coord_polar()
129+
coord.params = {"theta_range": (0, 10), "r_range": (0, 20)}
130+
131+
distance = coord.distance(pd.Series([0, 10]), pd.Series([0, 10]), None)
132+
133+
assert_allclose(distance, [np.sqrt(1.25)])
134+
assert coord.backtransform_range(None).x == (0, 10)
135+
assert coord.backtransform_range(None).y == (0, 20)
136+
137+
138+
def test_coord_polar_distance_and_backtransform_theta_y():
139+
coord = coord_polar(theta="y")
140+
coord.params = {"theta_range": (0, 10), "r_range": (0, 20)}
141+
142+
distance = coord.distance(pd.Series([0, 10]), pd.Series([0, 10]), None)
143+
144+
assert_allclose(distance, [np.sqrt(1.25)])
145+
assert coord.backtransform_range(None).x == (0, 20)
146+
assert coord.backtransform_range(None).y == (0, 10)
147+
148+
149+
def test_coord_polar_draw_sets_polar_axis():
150+
coord = coord_polar(direction=-1)
151+
coord.params = {"r_range": (2, 8)}
152+
fig, ax = plt.subplots(subplot_kw={"projection": "polar"})
153+
154+
try:
155+
coord.draw([ax])
156+
assert ax.get_theta_direction() == 1
157+
assert_allclose(ax.get_ylim(), (2, 8))
158+
finally:
159+
plt.close(fig)
160+
161+
162+
def test_coord_polar_aspect_is_square():
163+
assert coord_polar().aspect(None) == 1
164+
165+
166+
def test_coord_polar_draw_uses_polar_axes_and_hides_blank_border():
167+
data = pd.DataFrame({"x": ["a", "b"], "y": [1, 2]})
168+
p = (
169+
ggplot(data, aes("x", "y"))
170+
+ geom_col()
171+
+ coord_polar()
172+
+ theme(panel_border=element_blank(), axis_line=element_line())
173+
)
174+
175+
fig = p.draw()
176+
177+
try:
178+
ax = fig.axes[0]
179+
assert ax.name == "polar"
180+
assert not ax.spines["polar"].get_visible()
181+
finally:
182+
plt.close(fig)
183+
184+
185+
def test_coord_radial_arc_uses_end_or_direction():
186+
assert coord_radial(start=1, end=4)._arc == 3
187+
assert coord_radial(direction=-1)._arc == -2 * np.pi
188+
189+
190+
def test_coord_radial_setup_panel_params_for_partial_arc():
191+
scale_x, scale_y = trained_scales(
192+
y_breaks=(0, 2, 4, 8, 10),
193+
y_labels=("0", "2", "4", "8", "10"),
194+
)
195+
coord = coord_radial(
196+
start=0,
197+
end=np.pi,
198+
thetalim=(0, 10),
199+
rlim=(2, 8),
200+
expand=False,
201+
)
202+
203+
panel_params = coord.setup_panel_params(scale_x, scale_y)
204+
205+
assert coord.params["theta_range"] == (0, 10)
206+
assert coord.params["r_range"] == (2, 8)
207+
assert_allclose(panel_params.x.breaks, [0, np.pi / 2, np.pi])
208+
assert panel_params.x.labels == ["0", "5", "10"]
209+
assert panel_params.x.range == (0, np.pi)
210+
assert panel_params.y.range == (2, 8)
211+
assert panel_params.y.breaks == [2, 4, 8]
212+
assert panel_params.y.labels == ["2", "4", "8"]
213+
214+
215+
def test_coord_radial_setup_panel_params_theta_y_with_labels():
216+
scale_x, scale_y = trained_scales(
217+
y_breaks=(0, 5, 10),
218+
y_labels=("low", "mid", "high"),
219+
)
220+
coord = coord_radial(theta="y", theta_labels=True, expand=False)
221+
222+
panel_params = coord.setup_panel_params(scale_x, scale_y)
223+
224+
assert_allclose(panel_params.x.breaks, [0, np.pi, 2 * np.pi])
225+
assert panel_params.x.labels == ["low", "mid", "high"]
226+
227+
228+
def test_coord_radial_to_radians_zero_width_range():
229+
coord = coord_radial()
230+
coord.params = {"theta_range": (1, 1)}
231+
232+
assert_allclose(coord._to_radians(np.array([1, 2, 3])), [0, 0, 0])
233+
234+
235+
def test_coord_radial_transform_rotates_angle():
236+
coord = coord_radial(rotate_angle=True)
237+
coord.params = {"theta_range": (0, 10), "r_range": (0, 10)}
238+
data = pd.DataFrame({"x": [0, 5], "y": [1, 1], "angle": [10, 20]})
239+
240+
out = coord.transform(data, None)
241+
242+
assert_allclose(out["x"], [0, np.pi])
243+
assert_allclose(out["angle"], [10, 200])
244+
245+
246+
def test_coord_radial_draw_sets_arc_inner_radius_and_axis_position():
247+
coord = coord_radial(
248+
start=np.pi / 4,
249+
end=3 * np.pi / 4,
250+
inner_radius=0.5,
251+
r_axis_inside=True,
252+
)
253+
coord.params = {"r_range": (2, 10)}
254+
fig, ax = plt.subplots(subplot_kw={"projection": "polar"})
255+
256+
try:
257+
coord.draw([ax])
258+
assert_allclose(ax.get_xlim(), (np.pi / 4, 3 * np.pi / 4))
259+
assert_allclose(ax.get_rorigin(), -6)
260+
assert ax.get_rlabel_position() == 55
261+
finally:
262+
plt.close(fig)
263+
264+
265+
def test_coord_radial_draw_float_r_axis_position():
266+
coord = coord_radial(r_axis_inside=np.pi / 2)
267+
coord.params = {"r_range": (0, 10)}
268+
fig, ax = plt.subplots(subplot_kw={"projection": "polar"})
269+
270+
try:
271+
coord.draw([ax])
272+
assert ax.get_rlabel_position() == 90
273+
finally:
274+
plt.close(fig)
275+
276+
277+
def test_coord_radial_post_setup_ax_sets_pad_and_unclips_text():
278+
coord = coord_radial(theta_label_pad=17, theta_labels=True)
279+
fig, ax = plt.subplots(subplot_kw={"projection": "polar"})
280+
text = ax.text(0, 1, "label", clip_on=True)
281+
282+
try:
283+
coord.post_setup_ax(ax)
284+
assert ax.xaxis.get_tick_params()["pad"] == 17
285+
assert not text.get_clip_on()
286+
finally:
287+
plt.close(fig)

0 commit comments

Comments
 (0)