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