上一篇介绍了 AHA 的 左心室17段分割模型的定义,和用 axes.pie()
绘制该模型图的方法。
还可以用 matplotlib 的 axes.bar() + polar
绘制该模型图,这种方法相对于 axes.pie()
方法更加灵活适用。
模型的元数据、完整的代码、高清成图请到资源中下载:
https://download.csdn.net/download/sinat_32570141/15196030
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots(subplot_kw=dict(polar=True))
size = 0.3
vals = np.array([[60., 32.], [37., 40.], [29., 10.]])
#normalize vals to 2 pi
valsnorm = vals/np.sum(vals)*2*np.pi
#obtain the ordinates of the bar edges
valsleft = np.cumsum(np.append(0, valsnorm.flatten()[:-1])).reshape(vals.shape)
cmap = plt.get_cmap("tab20c")
outer_colors = cmap(np.arange(3)*4)
inner_colors = cmap([1, 2, 5, 6, 9, 10])
ax.bar(x=valsleft[:, 0],
width=valsnorm.sum(axis=1), bottom=1-size, height=size,
color=outer_colors, edgecolor='w', linewidth=1, align="edge")
ax.bar(x=valsleft.flatten(),
width=valsnorm.flatten(), bottom=1-2*size, height=size,
color=inner_colors, edgecolor='w', linewidth=1, align="edge")
ax.set(title="Pie plot with `ax.bar` and polar coordinates")
ax.set_axis_off()
plt.savefig("assets/bar_pie.png",facecolor='w',dpi=150)
plt.show()
bar
转换为圆环图的原理Axes.bar(self, x,
height, width=0.8,
bottom=None, *,
align='center', data=None,
**kwargs)
上面的圆环图还原成 bar
图如下:
bar
转换为 圆环图的过程实际就是将 bar
弯曲成环状。首先要将 bar
在笛卡尔坐标系中的坐标、尺寸映射到 polar
坐标系。
bar + polar
绘制心肌模型图import numpy as np
import pandas as pd
MS_df = pd.read_csv('17-Segment.csv')
数据格式如下:
MS_N | MS_FullName | MS | Part | Seg_Nu | CA_Color | CA | Angle | |
---|---|---|---|---|---|---|---|---|
0 | 1 | basal anterior (segment 1) | basal | anterior | segment 1 | (66,148, 247) | LAD | 60 |
1 | 2 | basal anteroseptal (segment 2) | basal | anteroseptal | segment 2 | (66,148, 247) | LAD | 60 |
2 | 3 | basal inferoseptal (segment 3) | basal | inferoseptal | segment 3 | (254, 252, 82) | RCA | 60 |
# 将[0,255]整数表示的RGB颜色值转化为[0,1]浮点数表示的RGB值元组
def make_color(df_col):
ca_rgb = []
for i in df_col:
temp = i.replace('(','').replace(')','')
temp_rgb = tuple([(int(j)/255) for j in temp.split(',')])
ca_rgb.append(temp_rgb)
return ca_rgb
ms = ('basal','mid','apical','apex')
ca = ('LAD','RCA','LCX')
x_basal = MS_df[MS_df['MS']=='basal']['Angle'].values.tolist()
x_mid = MS_df[MS_df['MS']=='mid']['Angle'].values.tolist()
x_apical = MS_df[MS_df['MS']=='apical']['Angle'].values.tolist()
x_apex = MS_df[MS_df['MS']=='apex']['Angle'].values.tolist()
c_basal = make_color(MS_df[MS_df['MS']=='basal']['CA_Color'])
c_mid = make_color(MS_df[MS_df['MS']=='mid']['CA_Color'])
c_apical = make_color(MS_df[MS_df['MS']=='apical']['CA_Color'])
c_apex = make_color(MS_df[MS_df['MS']=='apex']['CA_Color'])
l_basal = MS_df[MS_df['MS']=='basal']['MS_N'].values.tolist()
l_mid = MS_df[MS_df['MS']=='mid']['MS_N'].values.tolist()
l_apical = MS_df[MS_df['MS']=='apical']['MS_N'].values.tolist()
l_apex = MS_df[MS_df['MS']=='apex']['MS_N'].values.tolist()
bar
数据映射到 polar 坐标系笛卡尔坐标数据到 polar 坐标系的映射
# 生成绘制 bar 需要的 x, width
# x 是 bar 的位置,需要映射到 `[0, 2*np.pi]`区间
# width 是每个 bar 的宽度,sum(width) = 2*np.pi
# AHA 的 17-segment 模型图,环形从非 0 开始,所以需要一个偏移
# 偏移类似 axes.pie() 函数的 startangle 参数
def make_x_w(xdata, offset=60):
bar_x = []
bar_w = []
for i, v in enumerate(xdata):
......
......
return bar_x, bar_w
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
fig = plt.figure(figsize=(6.4,4.8),
facecolor='w',
constrained_layout=False)
ax = plt.axes((0.125,0.15,0.75,0.775),polar=True)
axc = fig.add_axes([0.255, 0.11, 0.5, 0.04])
ax.set_axis_off()
size = 0.25 # rings 环极径差
# bars_basal 环
bars_basal = ax.bar(x=make_x_w(x_basal,60)[0],
width=make_x_w(x_basal)[1],
bottom=1-size,
height=size,
color=c_basal,
edgecolor='k',
linewidth=0.5,
align="edge"
)
#bars_mid 环
.....
#bars_apical 环
....
#apex 段也可以通过 Circle 实现
circle = plt.Circle((0.0, 0.0), size,
transform=ax.transData._b,
fc=c_apex[0],
ec='k',
linewidth=0.5)
ax.add_artist(circle)
# 标记 17 段的函数
def autolabel(rects,l_seg):
for i, rect in enumerate(rects):
height = rect.get_height()
ax.annotate('{}'.format(l_seg[i]),
xy=(rect.get_x() + rect.get_width() / 2,
rects[i]._y0+0.125),
ha='center', va='center')
.....
ax.set(title="Draw AHA17-S module by bar + polar coordinates ")
plt.savefig('assets/bar_polar_bullseye.png',facecolor='w',dpi=200)
plt.show()
上面的心肌模型图对应的 axes.bar
图如下:
有任何问题,欢迎到 python草堂QQ群:457079928 讨论交流。