Как визуализировать горизонтальную гистограмму без сортировки баров? - PullRequest
0 голосов
/ 28 января 2020

Я хочу построить горизонтальную гистограмму, что я делаю так:

import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.ticker import MaxNLocator

def plot_results(title, freq, labels):
    #  create the figure
    matplotlib.rcParams.update({'font.size': 15})
    fig, ax1 = plt.subplots(figsize=(9, 4))
    fig.subplots_adjust(left=0.115, right=0.88)

    pos = np.arange(len(labels))
    rects = ax1.barh(pos, freq, align='center', height=0.8, tick_label = labels)

    ax1.set_title(title)

    ax1.set_xlim([0, 1])
    ax1.xaxis.set_major_locator(MaxNLocator(11))
    ax1.xaxis.grid(True, linestyle='--', which='major', color='grey', alpha=.25)

    rect_labels = []
    # Lastly, write in the ranking inside each bar to aid in interpretation
    for i in range(0, len(rects)):
        # Rectangle widths are already integer-valued but are floating
        # type, so it helps to remove the trailing decimal point and 0 by
        # converting width to int type
        rect = rects[i]
        width = freq[i]
        rankStr = labels[i]

        # The bars aren't wide enough to print the ranking inside
        if width < 40:
            # Shift the text to the right side of the right edge
            xloc = 5
            # Black against white background
            clr = 'black'
            align = 'left'
        else:
            # Shift the text to the left side of the right edge
            xloc = -5
            # White on magenta
            clr = 'white'
            align = 'right'

        # Center the text vertically in the bar
        yloc = rect.get_y() + rect.get_height() / 2
        label = ax1.annotate(rankStr + " (" + str(freq[i]) + ")", xy=(width, yloc), xytext=(xloc, 0),
                            textcoords="offset points",
                            ha=align, va='center',
                            color=clr, weight='bold', clip_on=True)
    plt.show()

После ввода некоторых параметров:

freq = [0.48, 0.40, 0.07, 0.05]
labels = ['Label 1', 'Label 2', 'Label 3', 'Label 4']
plot_results("Plot title", freq, labels)

я получаю следующий результат:

enter image description here

Кажется, что столбцы сортируются автоматически. Я хочу, чтобы столбцы отображались в точном порядке, в котором метки находятся в списке (начиная с «Метка 1» вверху и заканчивая «Метка 4» внизу). Как отключить эту автоматическую c сортировку?

1 Ответ

1 голос
/ 28 января 2020

Данные не "отсортированы", хитрость в том, что столбцы рисуются снизу вверх.

Чтобы исправить это, либо измените порядок своих данных, либо проще, измените направление на y ось:

freq = [0.48, 0.40, 0.07, 0.05]
labels = ['Label 1', 'Label 2', 'Label 3', 'Label 4']

fig, ax = plt.subplots()
ax.barh(labels, freq)
ax.invert_yaxis()

enter image description here

...