公牛眼图的形象

时间:2013-03-06 11:19:09

标签: python matplotlib

我想绘制图像的Bull's Eye图。我试过这些代码 Shade 'cells' in polar plot with matplotlib

对于Bull's Eye图,我想使用不同的颜色。有没有办法设置这种颜色?在color = choice(['navy','maroon','lightgreen'])中,颜色会按循环迭代重复。

有人知道matplotlib中是否有与matlab bullseye()相对应的函数?

2 个答案:

答案 0 :(得分:1)

我认为bullseye中没有特定的matplotlib方法,但是比较matlab函数的作用和此answer中的正确图,我认为你应该能够用半径坐标得到你想要的东西。例如。 (借鉴上述答案)

import numpy as np
import matplotlib.pyplot as plt

theta, r = np.mgrid[0:2*np.pi:20j, 0.2:1:10j]
z = np.random.random(theta.size).reshape(theta.shape)

fig, ax = plt.subplots(ncols=1, subplot_kw=dict(projection='polar'))

ax.pcolormesh(theta, r, z)
ax.set_yticklabels([])
ax.set_ylim([0, 1])

plt.show()

绘制this

我不明白你对颜色的问题究竟是什么意思。 ax.pcolormesh接受colormap或matplotlib color。如果你想要特定的颜色,你可以使用这两个参数和/或创建自己的色彩图。

答案 1 :(得分:0)

为了提供类似于你提到的matlab函数的东西,我起草了一些代码(在git hub上共享),用于创建每个径向细分具有任意数量扇区的bullseyes。颜色由颜色图和扇区下面的值给出。此外,这允许修改径向细分的居中。

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import pandas as pd
import matplotlib.ticker as ticker


def bulls_eye(ax, data, cmap=None, norm=None, raidal_subdivisions=(2, 8, 8, 11),
              centered=(True, False, False, True), add_nomenclatures=True, cell_resolution=128,
              pfi_where_to_save=None, colors_bound='-k'):
    """
    Clockwise, from smaller radius to bigger radius.
    :param ax:
    :param data:
    :param cmap:
    :param norm:
    :param raidal_subdivisions:
    :param centered:
    :param add_nomenclatures:
    :param cell_resolution:
    :param pfi_where_to_save:
    :return:
    """
    line_width = 1.5
    data = np.array(data).ravel()

    if cmap is None:
        cmap = plt.cm.viridis

    if norm is None:
        norm = mpl.colors.Normalize(vmin=data.min(), vmax=data.max())

    theta = np.linspace(0, 2*np.pi, 768)
    r = np.linspace(0, 1, len(raidal_subdivisions)+1)

    nomenclatures = []
    if isinstance(add_nomenclatures, bool):
        if add_nomenclatures:
            nomenclatures = range(1, sum(raidal_subdivisions)+1)
    elif isinstance(add_nomenclatures, list) or isinstance(add_nomenclatures, tuple):
        assert len(add_nomenclatures) == sum(raidal_subdivisions)
        nomenclatures = add_nomenclatures[:]
        add_nomenclatures = True


    # Create the circular bounds
    line_width_circular = line_width
    for i in range(r.shape[0]):
        if i == range(r.shape[0])[-1]:
            line_width_circular = int(line_width / 2.)
        ax.plot(theta, np.repeat(r[i], theta.shape), colors_bound, lw=line_width_circular)

    # iterate over cells divided by radial subdivision
    for rs_id, rs in enumerate(raidal_subdivisions):
        for i in range(rs):
            cell_id = sum(raidal_subdivisions[:rs_id]) + i
            theta_i = - i * 2 * np.pi / rs + np.pi / 2
            if not centered[rs_id]:
                theta_i += (2 * np.pi / rs) / 2
            theta_i_plus_one = theta_i - 2 * np.pi / rs  # clockwise
            # Create colour fillings for each cell:
            theta_interval = np.linspace(theta_i, theta_i_plus_one, cell_resolution)
            r_interval = np.array([r[rs_id], r[rs_id+1]])
            angle  = np.repeat(theta_interval[:, np.newaxis], 2, axis=1)
            radius = np.repeat(r_interval[:, np.newaxis], cell_resolution, axis=1).T
            z = np.ones((cell_resolution, 2)) * data[cell_id]
            ax.pcolormesh(angle, radius, z, cmap=cmap, norm=norm)

            # Create radial bounds
            if rs  > 1:
                ax.plot([theta_i, theta_i], [r[rs_id], r[rs_id+1]], colors_bound, lw=line_width)
            # Add centered nomenclatures if needed
            if add_nomenclatures:
                if rs == 1 and rs_id ==0:
                    cell_center = (0, 0)
                else:
                    cell_center = ((theta_i + theta_i_plus_one) / 2., r[rs_id] + .5 * r[1] )

                if isinstance(nomenclatures[0], (int, long, float, complex)):
                    ax.annotate(r"${:.3g}$".format(nomenclatures[cell_id]), xy=cell_center,
                                xytext=(cell_center[0], cell_center[1]),
                                horizontalalignment='center', verticalalignment='center', size=8)
                else:
                    ax.annotate(nomenclatures[cell_id], xy=cell_center,
                                xytext=(cell_center[0], cell_center[1]),
                                horizontalalignment='center', verticalalignment='center', size=12)

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

    if pfi_where_to_save is not None:
        plt.savefig(pfi_where_to_save, format='pdf', dpi=200)


def multi_bull_eyes(multi_data, cbar=None, cmaps=None, normalisations=None,
                    global_title=None, canvas_title='title', titles=None, units=None, raidal_subdivisions=(2, 8, 8, 11),
                    centered=(True, False, False, True), add_nomenclatures=(True, True, True, True),
                    pfi_where_to_save=None, show=True):
    plt.clf()
    n_fig = len(multi_data)
    if cbar is None:
        cbar = [True] * n_fig
    if cmaps is None:
        cmaps = [mpl.cm.viridis] * n_fig
    if normalisations is None:
        normalisations = [mpl.colors.Normalize(vmin=np.min(multi_data[i]), vmax=np.max(multi_data[i]))
                          for i in range(n_fig)]
    if titles is None:
        titles = ['Title {}'.format(i) for i in range(n_fig)]

    h_space = 0.15 / n_fig
    h_dim_fig = .8
    w_dim_fig = .8 / n_fig

    def fmt(x, pos):
        # a, b = '{:.2e}'.format(x).split('e')
        # b = int(b)
        # return r'${} \times 10^{{{}}}$'.format(a, b)
        return r"${:.4g}$".format(x)

    # Make a figure and axes with dimensions as desired.
    fig = plt.figure(figsize=(3 * n_fig, 4))
    fig.canvas.set_window_title(canvas_title)
    if global_title is not None:
        plt.suptitle(global_title)

    for n in range(n_fig):
        origin_fig = (h_space * (n + 1) + w_dim_fig * n, 0.15)
        ax = fig.add_axes([origin_fig[0], origin_fig[1], w_dim_fig, h_dim_fig], polar=True)
        bulls_eye(ax, multi_data[n], cmap=cmaps[n], norm=normalisations[n], raidal_subdivisions=raidal_subdivisions,
                  centered=centered, add_nomenclatures=add_nomenclatures[n])
        ax.set_title(titles[n], size=10)

        if cbar[n]:
            origin_cbar = (h_space * (n + 1) + w_dim_fig * n, .15)
            axl = fig.add_axes([origin_cbar[0], origin_cbar[1], w_dim_fig, .05])
            cb1 = mpl.colorbar.ColorbarBase(axl, cmap=cmaps[n], norm=normalisations[n], orientation='horizontal',
                                            format=ticker.FuncFormatter(fmt))
            cb1.ax.tick_params(labelsize=8)
            if units is not None:
                cb1.set_label(units[n])

    if pfi_where_to_save is not None:
        plt.savefig(pfi_where_to_save, format='pdf', dpi=330)
    if show:
        plt.show()

if __name__ == '__main__':

    # Very dummy data:
    data = np.array(range(29)) + 1

    # TEST bull-eye three-fold
    if True:

        fig, ax = plt.subplots(figsize=(12, 8), nrows=1, ncols=3,
                               subplot_kw=dict(projection='polar'))
        fig.canvas.set_window_title('Left Ventricle Bulls Eyes')

        # First one:
        cmap = mpl.cm.viridis
        norm = mpl.colors.Normalize(vmin=1, vmax=29)

        bulls_eye(ax[0], data, cmap=cmap, norm=norm)
        ax[0].set_title('Bulls Eye ')

        axl = fig.add_axes([0.14, 0.15, 0.2, 0.05])
        cb1 = mpl.colorbar.ColorbarBase(axl, cmap=cmap, norm=norm, orientation='horizontal')
        cb1.set_label('Some Units')

        # Second one
        cmap2 = mpl.cm.cool
        norm2 = mpl.colors.Normalize(vmin=1, vmax=29)

        bulls_eye(ax[1], data, cmap=cmap2, norm=norm2)
        ax[1].set_title('Bulls Eye ')

        axl2 = fig.add_axes([0.41, 0.15, 0.2, 0.05])
        cb2 = mpl.colorbar.ColorbarBase(axl2, cmap=cmap2, norm=norm2, orientation='horizontal')
        cb2.set_label('Some other units')

        # Third one
        cmap3 = mpl.cm.winter
        norm3 = mpl.colors.Normalize(vmin=1, vmax=29)

        bulls_eye(ax[2], data, cmap=cmap3, norm=norm3)
        ax[2].set_title('Bulls Eye third')

        axl3 = fig.add_axes([0.69, 0.15, 0.2, 0.05])
        cb3 = mpl.colorbar.ColorbarBase(axl3, cmap=cmap3, norm=norm3, orientation='horizontal')
        cb3.set_label('Some more units')

        plt.show()

    if True:
        fig = plt.figure(figsize=(5, 7))
        fig.canvas.set_window_title('Bulls Eyes - segmentation assessment')

        # First and only:
        cmap = mpl.cm.viridis
        norm = mpl.colors.Normalize(vmin=1, vmax=29)

        ax = fig.add_axes([0.1, 0.2, 0.8, 0.7], polar=True)
        bulls_eye(ax, data, cmap=cmap, norm=norm)
        ax.set_title('Bulls Eye')

        axl = fig.add_axes([0.1, 0.15, 0.8, 0.05])
        cb1 = mpl.colorbar.ColorbarBase(axl, cmap=cmap, norm=norm, orientation='horizontal')
        cb1.set_label('Some Units')

        plt.show()

    if True:

        multi_data = [range(1,17), list( 0.000000001 * np.array(range(1,17))), list( 0.001 * np.array(range(1,17)))]
        print multi_data
        multi_bull_eyes(multi_data, raidal_subdivisions=(3,3,4,6),
                  centered=(True, True, True, True), add_nomenclatures=[True]*3)

        plt.show(block=True)

我在github上的代码LabelsManager中建议您欢迎使用。

以下是raidal_subdivisions =(2,8,8,11)和居中=(True,False,False,True)的示例: enter image description here