2013-03-06 62 views
1

我想繪製圖像的公牛眼圖。我試過這些代碼 Shade 'cells' in polar plot with matplotlib圖像的公牛眼圖

對於Bull's Eye圖,我想使用不同的顏色。有什麼方法可以設置這種顏色?在color = choice(['navy','maroon','lightgreen'])顏色重複循環迭代。

有誰知道,如果在matplotlib中有一個函數對應matlab bullseye()

+0

可以更好地解釋你想達到什麼,也許你會如何實現它? – 2013-03-06 11:30:53

+1

我有θ,半徑和寬度值的數組。根據這個theta和半徑我必須給部門上色。 – aparasanana 2013-03-06 11:38:26

+0

你會介意編輯你的問題添加這些細節,並可能提供一些模擬數據和可能的基本實現,以便人們可以剪切,粘貼和運行? – 2013-03-06 12:07:27

回答

1

我不認爲存在matplotlib特定bullseye方法,但比較一下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。如果你想要特定的顏色,你可以使用這兩個參數來玩和/或創建你自己的色彩地圖。

0

爲了提供與您提到的matlab函數類似的東西,我草擬了一些代碼(在git hub上共享),以便爲每個徑向細分創建任意數量的扇區。顏色由顏色映射和扇區下方的值給出。此外,這允許修改徑向細分的對中。

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)和居中=(真,假,假,真): enter image description here