44
55
66import matplotlib
7+ import numpy as np
78import pytest
89
910from 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