77ventricle recommended by the American Heart Association (AHA).
88
99.. redirect-from:: /gallery/specialty_plots/leftventricle_bulleye
10+
11+ See also the :doc:`/gallery/pie_and_polar_charts/nested_pie` example.
1012"""
1113
1214import numpy as np
1315import matplotlib as mpl
1416import matplotlib .pyplot as plt
1517
1618
17- def bullseye_plot (ax , data , seg_bold = None , cmap = None , norm = None ):
19+ def bullseye_plot (ax , data , seg_bold = None , cmap = "viridis" , norm = None ):
1820 """
1921 Bullseye representation for the left ventricle.
2022
2123 Parameters
2224 ----------
2325 ax : axes
24- data : list of int and float
25- The intensity values for each of the 17 segments
26- seg_bold : list of int, optional
27- A list with the segments to highlight
28- cmap : ColorMap or None, optional
29- Optional argument to set the desired colormap
26+ data : list[ float]
27+ The intensity values for each of the 17 segments.
28+ seg_bold : list[ int] , optional
29+ A list with the segments to highlight.
30+ cmap : colormap, default: "viridis"
31+ Colormap for the data.
3032 norm : Normalize or None, optional
31- Optional argument to normalize data into the [0.0, 1.0] range
33+ Normalizer for the data.
3234
3335 Notes
3436 -----
@@ -43,93 +45,49 @@ def bullseye_plot(ax, data, seg_bold=None, cmap=None, norm=None):
4345 nomenclature for tomographic imaging of the heart",
4446 Circulation, vol. 105, no. 4, pp. 539-542, 2002.
4547 """
46- if seg_bold is None :
47- seg_bold = []
4848
49- linewidth = 2
5049 data = np .ravel (data )
51-
52- if cmap is None :
53- cmap = plt .cm .viridis
54-
50+ if seg_bold is None :
51+ seg_bold = []
5552 if norm is None :
5653 norm = mpl .colors .Normalize (vmin = data .min (), vmax = data .max ())
5754
58- theta = np .linspace (0 , 2 * np .pi , 768 )
5955 r = np .linspace (0.2 , 1 , 4 )
6056
61- # Remove grid
62- ax .grid (False )
63-
64- # Create the bound for the segment 17
65- for i in range (r .shape [0 ]):
66- ax .plot (theta , np .repeat (r [i ], theta .shape ), '-k' , lw = linewidth )
67-
68- # Create the bounds for the segments 1-12
69- for i in range (6 ):
70- theta_i = np .deg2rad (i * 60 )
71- ax .plot ([theta_i , theta_i ], [r [1 ], 1 ], '-k' , lw = linewidth )
72-
73- # Create the bounds for the segments 13-16
74- for i in range (4 ):
75- theta_i = np .deg2rad (i * 90 - 45 )
76- ax .plot ([theta_i , theta_i ], [r [0 ], r [1 ]], '-k' , lw = linewidth )
77-
78- # Fill the segments 1-6
79- r0 = r [2 :4 ]
80- r0 = np .repeat (r0 [:, np .newaxis ], 128 , axis = 1 ).T
81- for i in range (6 ):
82- # First segment start at 60 degrees
83- theta0 = theta [i * 128 :i * 128 + 128 ] + np .deg2rad (60 )
84- theta0 = np .repeat (theta0 [:, np .newaxis ], 2 , axis = 1 )
85- z = np .ones ((128 - 1 , 2 - 1 )) * data [i ]
86- ax .pcolormesh (theta0 , r0 , z , cmap = cmap , norm = norm , shading = 'auto' )
87- if i + 1 in seg_bold :
88- ax .plot (theta0 , r0 , '-k' , lw = linewidth + 2 )
89- ax .plot (theta0 [0 ], [r [2 ], r [3 ]], '-k' , lw = linewidth + 1 )
90- ax .plot (theta0 [- 1 ], [r [2 ], r [3 ]], '-k' , lw = linewidth + 1 )
91-
92- # Fill the segments 7-12
93- r0 = r [1 :3 ]
94- r0 = np .repeat (r0 [:, np .newaxis ], 128 , axis = 1 ).T
95- for i in range (6 ):
96- # First segment start at 60 degrees
97- theta0 = theta [i * 128 :i * 128 + 128 ] + np .deg2rad (60 )
98- theta0 = np .repeat (theta0 [:, np .newaxis ], 2 , axis = 1 )
99- z = np .ones ((128 - 1 , 2 - 1 )) * data [i + 6 ]
100- ax .pcolormesh (theta0 , r0 , z , cmap = cmap , norm = norm , shading = 'auto' )
101- if i + 7 in seg_bold :
102- ax .plot (theta0 , r0 , '-k' , lw = linewidth + 2 )
103- ax .plot (theta0 [0 ], [r [1 ], r [2 ]], '-k' , lw = linewidth + 1 )
104- ax .plot (theta0 [- 1 ], [r [1 ], r [2 ]], '-k' , lw = linewidth + 1 )
105-
106- # Fill the segments 13-16
107- r0 = r [0 :2 ]
108- r0 = np .repeat (r0 [:, np .newaxis ], 192 , axis = 1 ).T
109- for i in range (4 ):
110- # First segment start at 45 degrees
111- theta0 = theta [i * 192 :i * 192 + 192 ] + np .deg2rad (45 )
112- theta0 = np .repeat (theta0 [:, np .newaxis ], 2 , axis = 1 )
113- z = np .ones ((192 - 1 , 2 - 1 )) * data [i + 12 ]
114- ax .pcolormesh (theta0 , r0 , z , cmap = cmap , norm = norm , shading = 'auto' )
115- if i + 13 in seg_bold :
116- ax .plot (theta0 , r0 , '-k' , lw = linewidth + 2 )
117- ax .plot (theta0 [0 ], [r [0 ], r [1 ]], '-k' , lw = linewidth + 1 )
118- ax .plot (theta0 [- 1 ], [r [0 ], r [1 ]], '-k' , lw = linewidth + 1 )
119-
120- # Fill the segments 17
121- if data .size == 17 :
122- r0 = np .array ([0 , r [0 ]])
123- r0 = np .repeat (r0 [:, np .newaxis ], theta .size , axis = 1 ).T
124- theta0 = np .repeat (theta [:, np .newaxis ], 2 , axis = 1 )
125- z = np .ones ((theta .size - 1 , 2 - 1 )) * data [16 ]
126- ax .pcolormesh (theta0 , r0 , z , cmap = cmap , norm = norm , shading = 'auto' )
127- if 17 in seg_bold :
128- ax .plot (theta0 , r0 , '-k' , lw = linewidth + 2 )
129-
130- ax .set_ylim ([0 , 1 ])
131- ax .set_yticklabels ([])
132- ax .set_xticklabels ([])
57+ ax .set (ylim = [0 , 1 ], xticklabels = [], yticklabels = [])
58+ ax .grid (False ) # Remove grid
59+
60+ # Fill segments 1-6, 7-12, 13-16.
61+ for start , stop , r_in , r_out in [
62+ (0 , 6 , r [2 ], r [3 ]),
63+ (6 , 12 , r [1 ], r [2 ]),
64+ (12 , 16 , r [0 ], r [1 ]),
65+ (16 , 17 , 0 , r [0 ]),
66+ ]:
67+ n = stop - start
68+ dtheta = 2 * np .pi / n
69+ ax .bar (np .arange (n ) * dtheta + np .pi / 2 , r_out - r_in , dtheta , r_in ,
70+ color = cmap (norm (data [start :stop ])))
71+
72+ # Now, draw the segment borders. In order for the outer bold borders not
73+ # to be covered by inner segments, the borders are all drawn separately
74+ # after the segments have all been filled. We also disable clipping, which
75+ # would otherwise affect the outermost segment edges.
76+ # Draw edges of segments 1-6, 7-12, 13-16.
77+ for start , stop , r_in , r_out in [
78+ (0 , 6 , r [2 ], r [3 ]),
79+ (6 , 12 , r [1 ], r [2 ]),
80+ (12 , 16 , r [0 ], r [1 ]),
81+ ]:
82+ n = stop - start
83+ dtheta = 2 * np .pi / n
84+ ax .bar (np .arange (n ) * dtheta + np .pi / 2 , r_out - r_in , dtheta , r_in ,
85+ clip_on = False , color = "none" , edgecolor = "k" , linewidth = [
86+ 4 if i + 1 in seg_bold else 2 for i in range (start , stop )])
87+ # Draw edge of segment 17 -- here; the edge needs to be drawn differently,
88+ # using plot().
89+ ax .plot (np .linspace (0 , 2 * np .pi ), np .linspace (r [0 ], r [0 ]), "k" ,
90+ linewidth = (4 if 17 in seg_bold else 2 ))
13391
13492
13593# Create the fake data
@@ -151,7 +109,7 @@ def bullseye_plot(ax, data, seg_bold=None, cmap=None, norm=None):
151109# The following gives a basic continuous colorbar with ticks and labels.
152110fig .colorbar (mpl .cm .ScalarMappable (cmap = cmap , norm = norm ),
153111 cax = axs [0 ].inset_axes ([0 , - .15 , 1 , .1 ]),
154- orientation = 'horizontal' , label = 'Some Units ' )
112+ orientation = 'horizontal' , label = 'Some units ' )
155113
156114
157115# And again for the second colorbar.
0 commit comments