Установить числовые интервалы в качестве входных данных для функции построения графиков в Matplotlib - PullRequest
0 голосов
/ 25 сентября 2019

Я строю эту фигуру, но я хотел бы поиграть с интервалами.Однако я не хочу изменять имена столбцов legend, DataFrame и другие переменные каждый раз вручную.в идеале я бы отправил диапазоны "<", "<=", ">=" в качестве входных аргументов.Возможно ли это в Python?

Код:

def plotHistDistances(pat_name, lesion_id, rootdir, distanceMap, num_voxels, title, ablation_date):
    # PLOT THE HISTOGRAM FOR THE MAUERER EUCLIDIAN DISTANCES
    lesion_id_str = str(lesion_id)
    lesion_id = lesion_id_str.split('.')[0]
    figName_hist = 'Pat_' + str(pat_name) + '_Lesion' + str(lesion_id) + '_AblationDate_' + ablation_date + '_histogram'
    min_val = int(np.floor(min(distanceMap)))
    max_val = int(np.ceil(max(distanceMap)))
    fig, ax = plt.subplots(figsize=(18, 16))

    col_height, bins, patches = ax.hist(distanceMap, ec='darkgrey', bins=range(min_val - 1, max_val + 1))

    voxels_nonablated = []
    voxels_insuffablated = []
    voxels_ablated = []

    for b, p, col_val in zip(bins, patches, col_height):
        if b < 0:
            voxels_nonablated.append(col_val)
        elif 0 <= b <= 5:
            voxels_insuffablated.append(col_val)
        elif b > 5:
            voxels_ablated.append(col_val)
    # %%
    '''calculate the total percentage of surface for ablated, non-ablated, insufficiently ablated'''

    voxels_nonablated = np.asarray(voxels_nonablated)
    voxels_insuffablated = np.asarray(voxels_insuffablated)
    voxels_ablated = np.asarray(voxels_ablated)

    sum_perc_nonablated = ((voxels_nonablated / num_voxels) * 100).sum()
    sum_perc_insuffablated = ((voxels_insuffablated / num_voxels) * 100).sum()
    sum_perc_ablated = ((voxels_ablated / num_voxels) * 100).sum()
    # %%
    '''iterate through the bins to change the colors of the patches bases on the range [mm]'''
    for b, p, col_val in zip(bins, patches, col_height):
        if b < 0:
            plt.setp(p, label='Ablation Surface Margin ' + r'$x < 0$' + 'mm :' + " %.2f" % sum_perc_nonablated + '%')
        elif 0 <= b <= 5:
            plt.setp(p, 'facecolor', 'orange',
                     label='Ablation Surface Margin ' + r'$0 \leq  x \leq 5$' + 'mm: ' + "%.2f" % sum_perc_insuffablated + '%')
        elif b > 5:
            plt.setp(p, 'facecolor', 'darkgreen',
                     label='Ablation Surface Margin ' + r'$x > 5$' + 'mm: ' + " %.2f" % sum_perc_ablated + '%')
    # %%
    '''edit the axes limits and labels'''
    plt.xlabel('Euclidean Distances [mm]', fontsize=30, color='black')
    plt.tick_params(labelsize=28, color='black')
    ax.tick_params(colors='black', labelsize=28)
    plt.grid(True)
    # TODO: set equal axis limits
    ax.set_xlim([-15, 15])

    # edit the y-ticks: change to percentage of surface
    yticks, locs = plt.yticks()
    percent = (yticks / num_voxels) * 100
    percentage_surface_rounded = np.round(percent)
    yticks_percent = [str(x) + '%' for x in percentage_surface_rounded]
    new_yticks = (percentage_surface_rounded * yticks) / percent
    new_yticks[0] = 0
    plt.yticks(new_yticks, yticks_percent)
    #    plt.yticks(yticks,yticks_percent)
    plt.ylabel('Percentage of tumor surface voxels', fontsize=30, color='black')

    handles, labels = plt.gca().get_legend_handles_labels()
    by_label = OrderedDict(zip(labels, handles))
    plt.legend(by_label.values(), by_label.keys(), fontsize=30, loc='best')

    plt.title(title + '. Patient ' + str(pat_name) + '. Lesion ' + str(lesion_id), fontsize=30)

Цифра: histogram with labels interval limits

Поэтому я хотел бы отправить интервалыВы видите в legend здесь:

def plotHistDistances(pat_name, lesion_id, rootdir, distanceMap,
                      num_voxels, title, ablation_date, interval_limits):

1 Ответ

1 голос
/ 25 сентября 2019

Идея состоит в параметризации элемента диапазона (т. Е. 0 и 5 в вашем примере кода) в interval_limits.Для этого я предположил, что параметр interval_limits будет представлять собой список из 2 значений в следующей форме: [min_value, max_value] или конкретно для вашего образца, interval_limits должен представлять собой список из 0, 5, как показано ниже:

interval_limits = [0, 5]

Исходя из предположения, я немного изменил ваш код.Обратите внимание на новый блок, в котором я назначаю первый элемент interval_limits в новую переменную min_limit и 2-й элемент interval_limits в другую новую переменную max_limit, а затем я изменил строку метки, используя '%Формат .2f (не стесняйтесь переходить на любой другой формат)

Вот код:

def plotHistDistances(pat_name, lesion_id, rootdir, distanceMap, num_voxels, title, ablation_date, interval_limits):
    ##########################################
    # NEW COODE SECTION
    ##########################################
    # Check if interval_limits contains all the limits
    if len(interval_limits) != 2:
        raise ValueError("2 limits are expected, got {} instead.".format(len(interval_limits)))
    # Assign the limits
    min_limit = interval_limits[0]
    max_limit = interval_limits[1]
    ##########################################
    # END OF NEW CODE SECTION
    ##########################################

    # PLOT THE HISTOGRAM FOR THE MAUERER EUCLIDIAN DISTANCES
    lesion_id_str = str(lesion_id)
    lesion_id = lesion_id_str.split('.')[0]
    figName_hist = 'Pat_' + str(pat_name) + '_Lesion' + str(lesion_id) + '_AblationDate_' + ablation_date + '_histogram'
    min_val = int(np.floor(min(distanceMap)))
    max_val = int(np.ceil(max(distanceMap)))
    fig, ax = plt.subplots(figsize=(18, 16))

    col_height, bins, patches = ax.hist(distanceMap, ec='darkgrey', bins=range(min_val - 1, max_val + 1))

    voxels_nonablated = []
    voxels_insuffablated = []
    voxels_ablated = []

    for b, p, col_val in zip(bins, patches, col_height):
        if b < min_limit:
            voxels_nonablated.append(col_val)
        elif min_limit <= b <= max_limit:
            voxels_insuffablated.append(col_val)
        elif b > max_limit:
            voxels_ablated.append(col_val)
    # %%
    '''calculate the total percentage of surface for ablated, non-ablated, insufficiently ablated'''

    voxels_nonablated = np.asarray(voxels_nonablated)
    voxels_insuffablated = np.asarray(voxels_insuffablated)
    voxels_ablated = np.asarray(voxels_ablated)

    sum_perc_nonablated = ((voxels_nonablated / num_voxels) * 100).sum()
    sum_perc_insuffablated = ((voxels_insuffablated / num_voxels) * 100).sum()
    sum_perc_ablated = ((voxels_ablated / num_voxels) * 100).sum()
    # %%
    '''iterate through the bins to change the colors of the patches bases on the range [mm]'''
    for b, p, col_val in zip(bins, patches, col_height):
        if b < min_limit:
            plt.setp(p, label='Ablation Surface Margin ' + r'$x < %.2f$' % min_limit + 'mm :' + " %.2f" % sum_perc_nonablated + '%')
        elif min_limit <= b <= max_limit:
            plt.setp(p, 'facecolor', 'orange',
                     label='Ablation Surface Margin ' + r'$%.2f \leq  x \leq %.2f$' % (min_limit, max_limit) + 'mm: ' + "%.2f" % sum_perc_insuffablated + '%')
        elif b > max_limit:
            plt.setp(p, 'facecolor', 'darkgreen',
                     label='Ablation Surface Margin ' + r'$x > %.2f$' % max_limit + 'mm: ' + " %.2f" % sum_perc_ablated + '%')
    # %%
    '''edit the axes limits and labels'''
    plt.xlabel('Euclidean Distances [mm]', fontsize=30, color='black')
    plt.tick_params(labelsize=28, color='black')
    ax.tick_params(colors='black', labelsize=28)
    plt.grid(True)
    # TODO: set equal axis limits
    ax.set_xlim([-15, 15])

    # edit the y-ticks: change to percentage of surface
    yticks, locs = plt.yticks()
    percent = (yticks / num_voxels) * 100
    percentage_surface_rounded = np.round(percent)
    yticks_percent = [str(x) + '%' for x in percentage_surface_rounded]
    new_yticks = (percentage_surface_rounded * yticks) / percent
    new_yticks[0] = 0
    plt.yticks(new_yticks, yticks_percent)
    #    plt.yticks(yticks,yticks_percent)
    plt.ylabel('Percentage of tumor surface voxels', fontsize=30, color='black')

    handles, labels = plt.gca().get_legend_handles_labels()
    by_label = OrderedDict(zip(labels, handles))
    plt.legend(by_label.values(), by_label.keys(), fontsize=30, loc='best')

    plt.title(title + '. Patient ' + str(pat_name) + '. Lesion ' + str(lesion_id), fontsize=30)

Отказ от ответственности : я не проверял этот код, так как я делаюне иметь полного набора параметров для воспроизведения результата, но это должно работать.Если вы не стесняетесь предоставить мне набор параметров, которые вы используете, и я посмотрю, как я могу исправить проблему

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...