Skip to content

Commit 4a78cb5

Browse files
paavalipopovpre-commit-ci[bot]drammock
authored
FIX: correct label orientation for 0-90 deg nodes in plot_connectivity_circle (#13855)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Daniel McCloy <dan@mccloy.info>
1 parent 7b0ed9f commit 4a78cb5

4 files changed

Lines changed: 56 additions & 1 deletion

File tree

doc/changes/dev/13855.bugfix.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fixed incorrect label orientation for nodes in the 0–90° polar range (the
2+
12–3 o'clock quadrant) of the connectivity circle plot, by
3+
:newcontrib:`Pavel Popov`.

doc/changes/names.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@
258258
.. _Paul Pasler: https://github.com/ppasler
259259
.. _Paul Roujansky: https://github.com/paulroujansky
260260
.. _Pavel Navratil: https://github.com/navrpa13
261+
.. _Pavel Popov: https://github.com/paavalipopov
261262
.. _Peter Molfese: https://github.com/pmolfese
262263
.. _Phillip Alday: https://palday.bitbucket.io
263264
.. _Pierre Ablin: https://pierreablin.com

mne/viz/circle.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,9 @@ def _plot_connectivity_circle(
338338
# Draw node labels
339339
angles_deg = 180 * node_angles / np.pi
340340
for name, angle_rad, angle_deg in zip(node_names, node_angles, angles_deg):
341-
if angle_deg >= 270:
341+
if (
342+
angle_deg >= 270 or angle_deg < 90
343+
): # [0, 90] and [270, 360] cover right half
342344
ha = "left"
343345
else:
344346
# Flip the label, so text is always upright

mne/viz/tests/test_circle.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44

55

66
import matplotlib
7+
import numpy as np
78
import pytest
89

910
from mne.viz import plot_channel_labels_circle
11+
from mne.viz.circle import _plot_connectivity_circle
1012

1113

1214
@pytest.mark.filterwarnings(
@@ -33,3 +35,50 @@ def test_plot_channel_labels_circle():
3335
plot_channel_labels_circle(
3436
dict(brain=["big", "great", "smart"]), colors=dict(big="r", great="y")
3537
)
38+
39+
40+
def test_plot_connectivity_circle_label_orientation():
41+
"""Labels in the 0-90 deg polar range (12-3 o'clock) must not be flipped.
42+
43+
Regression test: previously the condition ``angle_deg >= 270`` missed the
44+
[0, 90) range, incorrectly adding 180 degrees to those labels and setting
45+
ha='right', which caused them to point inward instead of outward.
46+
"""
47+
# 9 nodes → uniform angles: 0, 40, 80, 120, 160, 200, 240, 280, 320 degrees.
48+
# This guarantees coverage of all four quadrants, including the previously
49+
# broken 0–90 range (nodes n0 at 0°, n1 at 40°, and n2 at 80°).
50+
n_nodes = 9
51+
con = np.ones((n_nodes, n_nodes))
52+
con[::2, ::2] = 0 # add some zeros to avoid 0-div in normalization
53+
node_names = [f"n{i}" for i in range(n_nodes)]
54+
55+
fig, ax = _plot_connectivity_circle(con, node_names, show=False)
56+
57+
texts = [c for c in ax.get_children() if isinstance(c, matplotlib.text.Text)]
58+
label_texts = {t.get_text(): t for t in texts if t.get_text() in node_names}
59+
60+
# node_angles defaults to np.linspace(0, 2*pi, n_nodes, endpoint=False)
61+
angles_deg = np.linspace(0, 360, n_nodes, endpoint=False)
62+
63+
assert len(label_texts) == n_nodes, (
64+
f"Expected {n_nodes} label texts, found {len(label_texts)}"
65+
)
66+
67+
for angle, name in zip(angles_deg, node_names, strict=True):
68+
t = label_texts[name]
69+
ha = t.get_ha()
70+
71+
if angle >= 270 or angle < 90:
72+
# Right half of circle: text must extend outward to the right.
73+
# ha='left' anchors the left edge at the node, text goes rightward.
74+
assert ha == "left", (
75+
f"Node '{name}' at {angle:.1f}° (right half) should have "
76+
f"ha='left', got '{ha}'"
77+
)
78+
else:
79+
# Left half: text is flipped 180° so it stays upright; ha='right'
80+
# anchors the right edge at the node, text extends leftward/outward.
81+
assert ha == "right", (
82+
f"Node '{name}' at {angle:.1f}° (left half) should have "
83+
f"ha='right', got '{ha}'"
84+
)

0 commit comments

Comments
 (0)