Коробка участка с делителем в Seaborn Python - PullRequest
0 голосов
/ 02 апреля 2020

Я пытаюсь скопировать этот коробочный сюжет с морским рожком. У меня будет sh, чтобы иметь деление, как на картинке. Я думал, что смогу создать другой Boxplot и объединение в одном изображении, но не очень хорошая идея для вычислений, создания множества изображений, использования слияния и удаления всех.

enter image description here

Я использовал Seaborn, чтобы таким образом поместить значение в поле

enter image description here

это моя функция:

def boxplot(df, name,prot,min,max):



    fig = plt.figure(figsize=(100, 20))
    plt.title(name+ " RMSE from  "+ str(min) +"h PSW to " + str(max) +"h PWS")
    plt.ylabel("RMSE")
    plt.xlabel("")



    box_plot = sns.boxplot(x="Interval" ,y="RMSE", data=df, palette="Set1", showfliers = False)


    ax = box_plot.axes
    lines = ax.get_lines()
    categories = ax.get_xticks()


    for cat in categories:
        # every 4th line at the interval of 6 is median line
        # 0 -> p25 1 -> p75 2 -> lower whisker 3 -> upper whisker 4 -> p50 5 -> upper extreme value
        y = round(lines[4+cat*5].get_ydata()[0],3) 

        ax.text(
            cat, 
            y, 
            f'{y}', 
            ha='center', 
            va='center', 
            fontweight='bold', 
            size=70,
            color='white',
            bbox=dict(facecolor='#445A64'))


    box_plot.figure.tight_layout()


    plt.savefig("output/"+str(prot)+ str(name)+".jpg")

    plt.close(fig)

Я также добавил этот код для каждого цвета (fooli sh), чтобы установить одинаковый цвет для всех одинаковых элементов в блоке. Пример объявления для значений "15" на оси X, я установил красный и т. Д. ...

для i в диапазоне (0, len (box_plot.artists), 12):

        mybox = ax.artists[i]
        mybox.set_facecolor('red')

    for i in range(1,len(box_plot.artists),12):

        mybox = ax.artists[i]
        mybox.set_facecolor('orange')

Я пытался использовать «оттенок» для категории в моем наборе данных (добавив строку 15,30 рядом с различными значениями), но при использовании оттенка боксплот примет такое большое расстояние между ними, как это, и мне действительно не нравится .

enter image description here

Я пытался использовать "заказ" как то же самое, но не получалось.

1 Ответ

1 голос
/ 03 апреля 2020

Этот тип графика называется «фасетирование», когда у вас есть график, который повторяется для разных уровней категориальной переменной. В seaborn вы можете создать FacetGrid или использовать catplot для таких действий. Немного доработав, вы получите результат, очень похожий на ваш желаемый результат

# dummy data
N=100
psws = [3,6,12,24,36]
times = [15,30,45,60]
df = pd.DataFrame(columns=pd.MultiIndex.from_product([psws,times], names=['PSW','Time']))
for psw in psws:
    for time in times:
        df[(psw,time)] = np.random.normal(loc=time, size=(N,))
# data need to be in "long-form"
df = df.melt()

g = sns.catplot(kind='box', data=df, x='Time', y='value', col='PSW', height=4, aspect=0.5, palette='Greys')
g.fig.subplots_adjust(wspace=0)
# remove the spines of the axes (except the leftmost one)
# and replace with dasehd line
for ax  in g.axes.flatten()[1:]:
    ax.spines['left'].set_visible(False)
    [tick.set_visible(False) for tick in ax.yaxis.get_major_ticks()]
    xmin,xmax = ax.get_xlim()
    ax.axvline(xmin, ls='--', color='k')

enter image description here

...