99import matplotlib .pyplot as plt
1010
1111
12- def bullseye_plot (ax , data , vlim = None , segBold = [] ):
12+ def bullseye_plot (ax , data , segBold = [], cmap = None , norm = None ):
1313 """
1414 Bullseye representation for the left ventricle.
1515
@@ -18,8 +18,10 @@ def bullseye_plot(ax, data, vlim=None, segBold=[]):
1818 ax : axes
1919 data : list of int and float
2020 The intensity values for each of the 17 segments
21- vlim : [min, max] or None
22- Optional argument to set the Intensity range
21+ cmap : ColorMap or None
22+ Optional argument to set the disaried colormap
23+ norm : Normalize or None
24+ Optional argument to normalize data into the [0.0, 1.0] range
2325 segBold: list of int
2426 A list with the segments to highlight
2527
@@ -33,16 +35,19 @@ def bullseye_plot(ax, data, vlim=None, segBold=[]):
3335 ----------
3436 .. [1] M. D. Cerqueira, N. J. Weissman, V. Dilsizian, A. K. Jacobs,
3537 S. Kaul, W. K. Laskey, D. J. Pennell, J. A. Rumberger, T. Ryan,
36- and M. S. Verani, “ Standardized myocardial segmentation and nomenclature
37- for tomographic imaging of the heart,” Circulation, vol. 105, no. 4,
38- pp. 539– 542, 2002.
38+ and M. S. Verani, " Standardized myocardial segmentation and nomenclature
39+ for tomographic imaging of the heart", Circulation, vol. 105, no. 4,
40+ pp. 539- 542, 2002.
3941 """
4042
4143 linewidth = 2
4244 data = np .array (data ).ravel ()
4345
44- if vlim is None :
45- vlim = [data .min (), data .max ()]
46+ if cmap is None :
47+ cmap = plt .cm .jet
48+
49+ if norm is None :
50+ norm = mpl .colors .Normalize (vmin = data .min (), vmax = data .max ())
4651
4752 theta = np .linspace (0 , 2 * np .pi , 768 )
4853 r = np .linspace (0.2 , 1 , 4 )
@@ -69,7 +74,7 @@ def bullseye_plot(ax, data, vlim=None, segBold=[]):
6974 theta0 = theta [i * 128 :i * 128 + 128 ] + 60 * np .pi / 180
7075 theta0 = np .repeat (theta0 [:, np .newaxis ], 2 , axis = 1 )
7176 z = np .ones ((128 , 2 ))* data [i ]
72- ax .pcolormesh (theta0 , r0 , z , vmin = vlim [ 0 ], vmax = vlim [ 1 ] )
77+ ax .pcolormesh (theta0 , r0 , z , cmap = cmap , norm = norm )
7378 if i + 1 in segBold :
7479 ax .plot (theta0 , r0 , '-k' , lw = linewidth + 2 )
7580 ax .plot (theta0 [0 ], [r [2 ], r [3 ]], '-k' , lw = linewidth + 1 )
@@ -83,7 +88,7 @@ def bullseye_plot(ax, data, vlim=None, segBold=[]):
8388 theta0 = theta [i * 128 :i * 128 + 128 ] + 60 * np .pi / 180
8489 theta0 = np .repeat (theta0 [:, np .newaxis ], 2 , axis = 1 )
8590 z = np .ones ((128 , 2 ))* data [i + 6 ]
86- ax .pcolormesh (theta0 , r0 , z , vmin = vlim [ 0 ], vmax = vlim [ 1 ] )
91+ ax .pcolormesh (theta0 , r0 , z , cmap = cmap , norm = norm )
8792 if i + 7 in segBold :
8893 ax .plot (theta0 , r0 , '-k' , lw = linewidth + 2 )
8994 ax .plot (theta0 [0 ], [r [1 ], r [2 ]], '-k' , lw = linewidth + 1 )
@@ -97,7 +102,7 @@ def bullseye_plot(ax, data, vlim=None, segBold=[]):
97102 theta0 = theta [i * 192 :i * 192 + 192 ] + 45 * np .pi / 180
98103 theta0 = np .repeat (theta0 [:, np .newaxis ], 2 , axis = 1 )
99104 z = np .ones ((192 , 2 ))* data [i + 12 ]
100- ax .pcolormesh (theta0 , r0 , z , vmin = vlim [ 0 ], vmax = vlim [ 1 ] )
105+ ax .pcolormesh (theta0 , r0 , z , cmap = cmap , norm = norm )
101106 if i + 13 in segBold :
102107 ax .plot (theta0 , r0 , '-k' , lw = linewidth + 2 )
103108 ax .plot (theta0 [0 ], [r [0 ], r [1 ]], '-k' , lw = linewidth + 1 )
@@ -109,7 +114,7 @@ def bullseye_plot(ax, data, vlim=None, segBold=[]):
109114 r0 = np .repeat (r0 [:, np .newaxis ], theta .size , axis = 1 ).T
110115 theta0 = np .repeat (theta [:, np .newaxis ], 2 , axis = 1 )
111116 z = np .ones ((theta .size , 2 ))* data [16 ]
112- ax .pcolormesh (theta0 , r0 , z , vmin = vlim [ 0 ], vmax = vlim [ 1 ] )
117+ ax .pcolormesh (theta0 , r0 , z , cmap = cmap , norm = norm )
113118 if 17 in segBold :
114119 ax .plot (theta0 , r0 , '-k' , lw = linewidth + 2 )
115120
@@ -120,32 +125,80 @@ def bullseye_plot(ax, data, vlim=None, segBold=[]):
120125
121126# Create the fake data
122127data = np .array (range (17 )) + 1
123- vlim = [data .min (), data .max ()]
124128
125- fig , ax = plt .subplots (figsize = (12 , 8 ), nrows = 1 , ncols = 2 ,
129+
130+ # Make a figure and axes with dimensions as desired.
131+ fig , ax = plt .subplots (figsize = (12 , 8 ), nrows = 1 , ncols = 3 ,
126132 subplot_kw = dict (projection = 'polar' ))
127133fig .canvas .set_window_title ('Left Ventricle Bulls Eyes (AHA)' )
128134
129- bullseye_plot (ax [0 ], data , vlim = vlim )
135+ # Create the axis for the colorbars
136+ axl = fig .add_axes ([0.14 , 0.15 , 0.2 , 0.05 ])
137+ axl2 = fig .add_axes ([0.41 , 0.15 , 0.2 , 0.05 ])
138+ axl3 = fig .add_axes ([0.69 , 0.15 , 0.2 , 0.05 ])
139+
140+
141+ # Set the colormap and norm to correspond to the data for which
142+ # the colorbar will be used.
143+ cmap = mpl .cm .jet
144+ norm = mpl .colors .Normalize (vmin = 1 , vmax = 17 )
145+
146+ # ColorbarBase derives from ScalarMappable and puts a colorbar
147+ # in a specified axes, so it has everything needed for a
148+ # standalone colorbar. There are many more kwargs, but the
149+ # following gives a basic continuous colorbar with ticks
150+ # and labels.
151+ cb1 = mpl .colorbar .ColorbarBase (axl , cmap = cmap , norm = norm ,
152+ orientation = 'horizontal' )
153+ cb1 .set_label ('Some Units' )
154+
155+
156+ # Set the colormap and norm to correspond to the data for which
157+ # the colorbar will be used.
158+ cmap2 = mpl .cm .cool
159+ norm2 = mpl .colors .Normalize (vmin = 1 , vmax = 17 )
160+
161+ # ColorbarBase derives from ScalarMappable and puts a colorbar
162+ # in a specified axes, so it has everything needed for a
163+ # standalone colorbar. There are many more kwargs, but the
164+ # following gives a basic continuous colorbar with ticks
165+ # and labels.
166+ cb2 = mpl .colorbar .ColorbarBase (axl2 , cmap = cmap2 , norm = norm2 ,
167+ orientation = 'horizontal' )
168+ cb2 .set_label ('Some other units' )
169+
170+
171+ # The second example illustrates the use of a ListedColormap, a
172+ # BoundaryNorm, and extended ends to show the "over" and "under"
173+ # value colors.
174+ cmap3 = mpl .colors .ListedColormap (['r' , 'g' , 'b' , 'c' ])
175+ cmap3 .set_over ('0.35' )
176+ cmap3 .set_under ('0.75' )
177+
178+ # If a ListedColormap is used, the length of the bounds array must be
179+ # one greater than the length of the color list. The bounds must be
180+ # monotonically increasing.
181+ bounds = [2 , 3 , 7 , 9 , 15 ]
182+ norm3 = mpl .colors .BoundaryNorm (bounds , cmap3 .N )
183+ cb3 = mpl .colorbar .ColorbarBase (axl3 , cmap = cmap3 , norm = norm3 ,
184+ # to use 'extend', you must
185+ # specify two extra boundaries:
186+ boundaries = [0 ]+ bounds + [18 ],
187+ extend = 'both' ,
188+ ticks = bounds , # optional
189+ spacing = 'proportional' ,
190+ orientation = 'horizontal' )
191+ cb3 .set_label ('Discrete intervals, some other units' )
192+
193+
194+ # Create the 17 segment model
195+ bullseye_plot (ax [0 ], data , cmap = cmap , norm = norm )
130196ax [0 ].set_title ('Bulls Eye (AHA)' )
131197
132- bullseye_plot (ax [1 ], data , segBold = [3 , 5 , 6 , 11 , 12 , 16 ],
133- vlim = vlim )
134- ax [1 ].set_title ('Segments [3,5,6,11,12,16] in bold' )
135-
136-
137- #Add legend
138- cm = plt .cm .jet
139-
140- #define the bins and normalize
141- cNorm = mpl .colors .Normalize (vmin = vlim [0 ], vmax = vlim [1 ])
198+ bullseye_plot (ax [1 ], data , cmap = cmap2 , norm = norm2 )
199+ ax [1 ].set_title ('Bulls Eye (AHA)' )
142200
143- ticks = [vlim [0 ], 0 , vlim [1 ]]
144- ax [0 ] = fig .add_axes ([0.2 , 0.15 , 0.2 , 0.05 ])
145- cb = mpl .colorbar .ColorbarBase (ax [0 ], cmap = cm , norm = cNorm , ticks = ticks ,
146- orientation = 'horizontal' )
147- ax [1 ] = fig .add_axes ([0.62 , 0.15 , 0.2 , 0.05 ])
148- cb = mpl .colorbar .ColorbarBase (ax [1 ], cmap = cm , norm = cNorm , ticks = ticks ,
149- orientation = 'horizontal' )
201+ bullseye_plot (ax [2 ], data , segBold = [3 , 5 , 6 , 11 , 12 , 16 ], cmap = cmap3 , norm = norm3 )
202+ ax [2 ].set_title ('Segments [3,5,6,11,12,16] in bold' )
150203
151204plt .show ()
0 commit comments