1

我想知道是否有人根据美国心脏协会使用 matplotlib 实现了左心室的靶心。我想要这样的东西:

plotBullEye(data) 其中 data 有 17 个值,每个值对应于牛眼的特定区域。

LV 牛眼 (AHA)

4

2 回答 2

2

最后,我使用极坐标投影实现了一个功能。此外,此函数接受要突出显示的区域列表。这是代码:

def bulleye_plot(data, ax=None, figsize=(12,8), vlim=None, segBold=[]):
    """
    Bull eye for the Left Ventricle according to the AHA representation
    Use Example:
        data = range(17)
        bulleye_plot(data)
    """
    data = np.array(data).ravel()

    if vlim is None:
        vlim = [data.min(), data.max()]

    axnone = False
    if ax is None:
        fig, ax = plt.subplots(figsize=figsize, subplot_kw=dict(projection='polar'))
        fig.canvas.set_window_title('Left Ventricle Bull Eyes (AHA) Plot')
        axnone = True


    theta = np.linspace(0, 2*np.pi, 768)
    r = np.linspace(0.2, 1, 4)


    # Armamos los bordes del circulo
    linewidth = 2
    for i in range(r.shape[0]):
        ax.plot(theta, np.repeat(r[i], theta.shape), '-k', lw=linewidth)

    # Armamos las lineas que separan las regiones 1-12
    for i in range(6):
        theta_i = i * 60 * np.pi/180
        ax.plot([theta_i, theta_i], [r[1], 1], '-k', lw=linewidth)

    # Armamos las lineas que separan las regiones 13-16
    for i in range(4):
        theta_i = i * 90 * np.pi/180 - 45*np.pi/180
        ax.plot([theta_i, theta_i], [r[0], r[1]], '-k', lw=linewidth)





    # Rellenamos las regiones 1-6
    r0 = r[2:4]
    r0 = np.repeat(r0[:,np.newaxis], 128, axis=1).T
    for i in range(6):
        theta0 = theta[i*128:i*128+128] + 60*np.pi/180 # sumamos 60 porque empieza en la reg 6
        theta0 = np.repeat(theta0[:,np.newaxis], 2, axis=1)
        z = np.ones((128,2)) * data[i]
        ax.pcolormesh(theta0, r0, z, vmin=vlim[0], vmax=vlim[1])
        if i+1 in segBold:
            ax.plot(theta0, r0, '-k', lw=linewidth+2)
            ax.plot(theta0[0], [r[2],r[3]], '-k', lw=linewidth+1)
            ax.plot(theta0[-1], [r[2],r[3]], '-k', lw=linewidth+1)

    # Rellenamos las regiones 7-12
    r0 = r[1:3]
    r0 = np.repeat(r0[:,np.newaxis], 128, axis=1).T
    for i in range(6):
        theta0 = theta[i*128:i*128+128] + 60*np.pi/180 # sumamos 60 porque empieza en la reg 6
        theta0 = np.repeat(theta0[:,np.newaxis], 2, axis=1)
        z = np.ones((128,2)) * data[i+6]
        ax.pcolormesh(theta0, r0, z, vmin=vlim[0], vmax=vlim[1])
        if i+7 in segBold:
            ax.plot(theta0, r0, '-k', lw=linewidth+2)
            ax.plot(theta0[0], [r[1],r[2]], '-k', lw=linewidth+1)
            ax.plot(theta0[-1], [r[1],r[2]], '-k', lw=linewidth+1)


    # Rellenamos las regiones 13-16
    r0 = r[0:2]
    r0 = np.repeat(r0[:,np.newaxis], 192, axis=1).T
    for i in range(4):
        theta0 = theta[i*192:i*192+192] + 45*np.pi/180 # sumamos 60 porque empieza en la reg 6
        theta0 = np.repeat(theta0[:,np.newaxis], 2, axis=1)
        z = np.ones((192,2)) * data[i+12]
        ax.pcolormesh(theta0, r0, z, vmin=vlim[0], vmax=vlim[1])
        if i+13 in segBold:
            ax.plot(theta0, r0, '-k', lw=linewidth+2)
            ax.plot(theta0[0], [r[0],r[1]], '-k', lw=linewidth+1)
            ax.plot(theta0[-1], [r[0],r[1]], '-k', lw=linewidth+1)

    #Rellenamos la region 17
    if data.size == 17:
        r0 = np.array([0, r[0]])
        r0 = np.repeat(r0[:,np.newaxis], theta.size, axis=1).T
        theta0 = np.repeat(theta[:,np.newaxis], 2, axis=1)
        z = np.ones((theta.size,2)) * data[16]
        ax.pcolormesh(theta0, r0, z, vmin=vlim[0], vmax=vlim[1])
        if 17 in segBold:
            ax.plot(theta0, r0, '-k', lw=linewidth+2)


    ax.set_ylim([0, 1])
    ax.set_yticklabels([])
    ax.set_xticklabels([])


    #Add legend
    if axnone:
        cm = plt.cm.jet

        #define the bins and normalize
        cNorm = mpl.colors.Normalize(vmin=vlim[0], vmax=vlim[1])

        ax = fig.add_axes([0.3, 0.04, 0.45, 0.05])
        ticks = [vlim[0], 0, vlim[1]]
        cb = mpl.colorbar.ColorbarBase(ax, cmap=cm, norm=cNorm,
                                       orientation='horizontal', ticks=ticks)

    plt.show()

    if axnone:
        return fig, ax

一些结果: 左心室

带段的 LV AHA = [5,6,11,12,16] 粗体

于 2014-09-11T11:27:47.277 回答
0

您也可以使用多边形点生成,如下所示。大多数代码重复都可以概括,为了理解细读,它保持原样。

def plotBull():
 import matplotlib.pyplot as plt
 plt.axes()

 # inner most region #
 points = stack3(50,0,180) 
 line = plt.Polygon(points, closed=True , fill=True ,fc = '#575757'  , edgecolor='#575757')
 plt.gca().add_patch(line) 
 plt.text(0,0,'17')

 points = stack3(50,-180,0) 
 line = plt.Polygon(points, closed=True , fill=True ,fc = '#575757'  , edgecolor='#575757')
 plt.gca().add_patch(line)


 # bottom up ############# 
 points = stack3(100,45,135) 
 line = plt.Polygon(points, closed=True , fill=True ,fc = 'm'  , edgecolor='k')
 plt.gca().add_patch(line)
 plt.text(0,75,'13')

 points = stack3(100,135,225) 
 line = plt.Polygon(points, closed=True , fill=True ,fc = 'g'  , edgecolor='k')
 plt.gca().add_patch(line)
 plt.text(-75,0,'14')

 points = stack3(100,225,315) 
 line = plt.Polygon(points, closed=True , fill=True ,fc = 'b'  , edgecolor='k')
 plt.gca().add_patch(line)
 plt.text(0,-75 ,'15')

 points = stack3(100,315,405) 
 line = plt.Polygon(points, closed=True , fill=True ,fc = 'y'  , edgecolor='k')
 plt.gca().add_patch(line)
 plt.text(75,0,'16') 

 #botton up1###############

 points = stack3(150,0,62)
 line = plt.Polygon(points, closed=True , fill=True ,fc = 'c'  , edgecolor='k')
 plt.gca().add_patch(line)
 plt.text(100,60,'12') 

 points = stack3(150,60,122)
 line = plt.Polygon(points, closed=True , fill=True ,fc = '#3358fc'  , edgecolor='k')
 plt.gca().add_patch(line)
 plt.text(0,115,'7') 

 points = stack3(150,120,182)
 line = plt.Polygon(points, closed=True , fill=True ,fc = '#245465'  , edgecolor='k')
 plt.gca().add_patch(line)
 plt.text(-100,60,'8') 

 points = stack3(150,180,242)
 line = plt.Polygon(points, closed=True , fill=True ,fc = '#D3E130'  , edgecolor='k')
 plt.gca().add_patch(line)
 plt.text(-100,-60,'9') 

 points = stack3(150,240,302)
 line = plt.Polygon(points, closed=True , fill=True ,fc = '#8928b1'  , edgecolor='k')
 plt.gca().add_patch(line)
 plt.text(0,-115,'10') 

 points = stack3(150,300,362)
 line = plt.Polygon(points, closed=True , fill=True ,fc = '#12ED89'  , edgecolor='k')
 plt.gca().add_patch(line)
 plt.text(100,-60,'11') 

 #botton up1###############

 points = stack3(200,0,62)
 line = plt.Polygon(points, closed=True , fill=True ,fc = '#FF2E34'  , edgecolor='k')
 plt.gca().add_patch(line)
 plt.text(150,80,'6')

 points = stack3(200,60,122)
 line = plt.Polygon(points, closed=True , fill=True ,fc = 'b'  , edgecolor='k')
 plt.gca().add_patch(line)
 plt.text(0,165,'1') 

 points = stack3(200,120,182)
 line = plt.Polygon(points, closed=True , fill=True ,fc = '#12D154'  , edgecolor='k')
 plt.gca().add_patch(line)
 plt.text(-150,80,'2') 

 points = stack3(200,180,242)
 line = plt.Polygon(points, closed=True , fill=True ,fc = '#D3FF65'  , edgecolor='k')
 plt.gca().add_patch(line)
 plt.text(-150,-80,'3') 

 points = stack3(200,240,302)
 line = plt.Polygon(points, closed=True , fill=True ,fc = '#54DBEF'  , edgecolor='k')
 plt.gca().add_patch(line)
 plt.text(0,-165,'4')

 points = stack3(200,300,362)
 line = plt.Polygon(points, closed=True , fill=True ,fc = '#C121EE'  , edgecolor='k')
 plt.gca().add_patch(line)
 plt.text(150,-80,'5') 

 plt.axis('scaled')
 plt.axis('off')

 plt.show()


def stack3(radius,startAngle,endAngle):
  import math
  startRadian = math.pi*startAngle/180
  endRadian = math.pi*endAngle/180

  import math
  mainList = []
  for idx in range(0,100):
    subList = []
    theta =  2*3.1415926 * float(idx) / float(100)

    theta += startRadian

    if theta > endRadian :      
      break 
    x =   radius* math.cos(theta)
    y =   radius* math.sin(theta)
    subList.append(x)
    subList.append(y)
    mainList.append(subList)  
  tempList = []
  for idx in range(0,100):
    subList = []
    theta =  2*3.1415926 * float(idx) / float(100)
    theta += startRadian
    if theta > endRadian :
      break 
    x =   (radius - 50) * math.cos(theta)
    y =   (radius - 50) * math.sin(theta)
    subList.append(x)
    subList.append(y)
    tempList.append(subList)
  tempList.reverse()
  for idx in range(0,len(tempList)):
    mainList.append(tempList[idx]) 
  return mainList
  pass 
于 2015-04-08T05:38:59.297 回答