Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 5259594

Browse filesBrowse files
committed
Merge pull request #4550 from tacaswell/doc_aha_bullseye
Doc: AHA bullseye example
2 parents b57e014 + 1b831cb commit 5259594
Copy full SHA for 5259594

File tree

Expand file treeCollapse file tree

2 files changed

+209
-0
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+209
-0
lines changed

‎.gitignore

Copy file name to clipboardExpand all lines: .gitignore
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,5 @@ examples/tests/*
6767
texput.log
6868
texput.aux
6969
result_images
70+
71+
*.swp
+207Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
#!/usr/bin/env python
2+
"""
3+
This example demonstrates how to create the 17 segment model for the left
4+
ventricle recommended by the American Heart Association (AHA).
5+
"""
6+
7+
import numpy as np
8+
import matplotlib as mpl
9+
import matplotlib.pyplot as plt
10+
11+
12+
def bullseye_plot(ax, data, segBold=None, cmap=None, norm=None):
13+
"""
14+
Bullseye representation for the left ventricle.
15+
16+
Parameters
17+
----------
18+
ax : axes
19+
data : list of int and float
20+
The intensity values for each of the 17 segments
21+
segBold: list of int, optional
22+
A list with the segments to highlight
23+
cmap : ColorMap or None, optional
24+
Optional argument to set the desired colormap
25+
norm : Normalize or None, optional
26+
Optional argument to normalize data into the [0.0, 1.0] range
27+
28+
29+
Notes
30+
-----
31+
This function create the 17 segment model for the left ventricle according
32+
to the American Heart Association (AHA) [1]_
33+
34+
References
35+
----------
36+
.. [1] M. D. Cerqueira, N. J. Weissman, V. Dilsizian, A. K. Jacobs,
37+
S. Kaul, W. K. Laskey, D. J. Pennell, J. A. Rumberger, T. Ryan,
38+
and M. S. Verani, "Standardized myocardial segmentation and
39+
nomenclature for tomographic imaging of the heart",
40+
Circulation, vol. 105, no. 4, pp. 539-542, 2002.
41+
"""
42+
if segBold is None:
43+
segBold = []
44+
45+
linewidth = 2
46+
data = np.array(data).ravel()
47+
48+
if cmap is None:
49+
cmap = plt.cm.jet
50+
51+
if norm is None:
52+
norm = mpl.colors.Normalize(vmin=data.min(), vmax=data.max())
53+
54+
theta = np.linspace(0, 2*np.pi, 768)
55+
r = np.linspace(0.2, 1, 4)
56+
57+
# Create the bound for the segment 17
58+
for i in range(r.shape[0]):
59+
ax.plot(theta, np.repeat(r[i], theta.shape), '-k', lw=linewidth)
60+
61+
# Create the bounds for the segments 1-12
62+
for i in range(6):
63+
theta_i = i*60*np.pi/180
64+
ax.plot([theta_i, theta_i], [r[1], 1], '-k', lw=linewidth)
65+
66+
# Create the bounds for the segmentss 13-16
67+
for i in range(4):
68+
theta_i = i*90*np.pi/180 - 45*np.pi/180
69+
ax.plot([theta_i, theta_i], [r[0], r[1]], '-k', lw=linewidth)
70+
71+
# Fill the segments 1-6
72+
r0 = r[2:4]
73+
r0 = np.repeat(r0[:, np.newaxis], 128, axis=1).T
74+
for i in range(6):
75+
# First segment start at 60 degrees
76+
theta0 = theta[i*128:i*128+128] + 60*np.pi/180
77+
theta0 = np.repeat(theta0[:, np.newaxis], 2, axis=1)
78+
z = np.ones((128, 2))*data[i]
79+
ax.pcolormesh(theta0, r0, z, cmap=cmap, norm=norm)
80+
if i+1 in segBold:
81+
ax.plot(theta0, r0, '-k', lw=linewidth+2)
82+
ax.plot(theta0[0], [r[2], r[3]], '-k', lw=linewidth+1)
83+
ax.plot(theta0[-1], [r[2], r[3]], '-k', lw=linewidth+1)
84+
85+
# Fill the segments 7-12
86+
r0 = r[1:3]
87+
r0 = np.repeat(r0[:, np.newaxis], 128, axis=1).T
88+
for i in range(6):
89+
# First segment start at 60 degrees
90+
theta0 = theta[i*128:i*128+128] + 60*np.pi/180
91+
theta0 = np.repeat(theta0[:, np.newaxis], 2, axis=1)
92+
z = np.ones((128, 2))*data[i+6]
93+
ax.pcolormesh(theta0, r0, z, cmap=cmap, norm=norm)
94+
if i+7 in segBold:
95+
ax.plot(theta0, r0, '-k', lw=linewidth+2)
96+
ax.plot(theta0[0], [r[1], r[2]], '-k', lw=linewidth+1)
97+
ax.plot(theta0[-1], [r[1], r[2]], '-k', lw=linewidth+1)
98+
99+
# Fill the segments 13-16
100+
r0 = r[0:2]
101+
r0 = np.repeat(r0[:, np.newaxis], 192, axis=1).T
102+
for i in range(4):
103+
# First segment start at 45 degrees
104+
theta0 = theta[i*192:i*192+192] + 45*np.pi/180
105+
theta0 = np.repeat(theta0[:, np.newaxis], 2, axis=1)
106+
z = np.ones((192, 2))*data[i+12]
107+
ax.pcolormesh(theta0, r0, z, cmap=cmap, norm=norm)
108+
if i+13 in segBold:
109+
ax.plot(theta0, r0, '-k', lw=linewidth+2)
110+
ax.plot(theta0[0], [r[0], r[1]], '-k', lw=linewidth+1)
111+
ax.plot(theta0[-1], [r[0], r[1]], '-k', lw=linewidth+1)
112+
113+
# Fill the segments 17
114+
if data.size == 17:
115+
r0 = np.array([0, r[0]])
116+
r0 = np.repeat(r0[:, np.newaxis], theta.size, axis=1).T
117+
theta0 = np.repeat(theta[:, np.newaxis], 2, axis=1)
118+
z = np.ones((theta.size, 2))*data[16]
119+
ax.pcolormesh(theta0, r0, z, cmap=cmap, norm=norm)
120+
if 17 in segBold:
121+
ax.plot(theta0, r0, '-k', lw=linewidth+2)
122+
123+
ax.set_ylim([0, 1])
124+
ax.set_yticklabels([])
125+
ax.set_xticklabels([])
126+
127+
128+
# Create the fake data
129+
data = np.array(range(17)) + 1
130+
131+
132+
# Make a figure and axes with dimensions as desired.
133+
fig, ax = plt.subplots(figsize=(12, 8), nrows=1, ncols=3,
134+
subplot_kw=dict(projection='polar'))
135+
fig.canvas.set_window_title('Left Ventricle Bulls Eyes (AHA)')
136+
137+
# Create the axis for the colorbars
138+
axl = fig.add_axes([0.14, 0.15, 0.2, 0.05])
139+
axl2 = fig.add_axes([0.41, 0.15, 0.2, 0.05])
140+
axl3 = fig.add_axes([0.69, 0.15, 0.2, 0.05])
141+
142+
143+
# Set the colormap and norm to correspond to the data for which
144+
# the colorbar will be used.
145+
cmap = mpl.cm.jet
146+
norm = mpl.colors.Normalize(vmin=1, vmax=17)
147+
148+
# ColorbarBase derives from ScalarMappable and puts a colorbar
149+
# in a specified axes, so it has everything needed for a
150+
# standalone colorbar. There are many more kwargs, but the
151+
# following gives a basic continuous colorbar with ticks
152+
# and labels.
153+
cb1 = mpl.colorbar.ColorbarBase(axl, cmap=cmap, norm=norm,
154+
orientation='horizontal')
155+
cb1.set_label('Some Units')
156+
157+
158+
# Set the colormap and norm to correspond to the data for which
159+
# the colorbar will be used.
160+
cmap2 = mpl.cm.cool
161+
norm2 = mpl.colors.Normalize(vmin=1, vmax=17)
162+
163+
# ColorbarBase derives from ScalarMappable and puts a colorbar
164+
# in a specified axes, so it has everything needed for a
165+
# standalone colorbar. There are many more kwargs, but the
166+
# following gives a basic continuous colorbar with ticks
167+
# and labels.
168+
cb2 = mpl.colorbar.ColorbarBase(axl2, cmap=cmap2, norm=norm2,
169+
orientation='horizontal')
170+
cb2.set_label('Some other units')
171+
172+
173+
# The second example illustrates the use of a ListedColormap, a
174+
# BoundaryNorm, and extended ends to show the "over" and "under"
175+
# value colors.
176+
cmap3 = mpl.colors.ListedColormap(['r', 'g', 'b', 'c'])
177+
cmap3.set_over('0.35')
178+
cmap3.set_under('0.75')
179+
180+
# If a ListedColormap is used, the length of the bounds array must be
181+
# one greater than the length of the color list. The bounds must be
182+
# monotonically increasing.
183+
bounds = [2, 3, 7, 9, 15]
184+
norm3 = mpl.colors.BoundaryNorm(bounds, cmap3.N)
185+
cb3 = mpl.colorbar.ColorbarBase(axl3, cmap=cmap3, norm=norm3,
186+
# to use 'extend', you must
187+
# specify two extra boundaries:
188+
boundaries=[0]+bounds+[18],
189+
extend='both',
190+
ticks=bounds, # optional
191+
spacing='proportional',
192+
orientation='horizontal')
193+
cb3.set_label('Discrete intervals, some other units')
194+
195+
196+
# Create the 17 segment model
197+
bullseye_plot(ax[0], data, cmap=cmap, norm=norm)
198+
ax[0].set_title('Bulls Eye (AHA)')
199+
200+
bullseye_plot(ax[1], data, cmap=cmap2, norm=norm2)
201+
ax[1].set_title('Bulls Eye (AHA)')
202+
203+
bullseye_plot(ax[2], data, segBold=[3, 5, 6, 11, 12, 16],
204+
cmap=cmap3, norm=norm3)
205+
ax[2].set_title('Segments [3,5,6,11,12,16] in bold')
206+
207+
plt.show()

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.