plotly - наложение звездочек / аннотаций значимости на прямоугольные диаграммы - PullRequest
1 голос
/ 09 июля 2020

Я пытаюсь создать фасетную коробчатую диаграмму для результатов линейной модели с обработками по оси x. Обычный способ показать значимость - это добавить звездочки.

Я нахожу это на удивление сложным сделать графически.

Пример кода:


import numpy as np
import pandas as pd

# Data
n = 10
conditiona = ['left', 'right']
conditionb = ['top', 'middle', 'bottom']

N = n * len(conditiona) * len(conditionb)
trt = np.repeat(['a', 'b','c'], N)
eff = np.repeat([3, 2, 1], N)
noise = np.random.normal(size = 3* N, loc = 0, scale = 1)
pval = np.repeat(['**', '', ''], N)
col = np.tile( np.repeat( conditiona, n * len(conditionb)), 3)
row = np.tile( np.repeat( conditionb, n) , len(conditiona) *3)


df = pd.DataFrame( { 'y' : noise + eff, 'trt' : trt, 'p' : pval, 'column' : col,
                'row' : row})

## Plot
import plotly.graph_objects as go
from plotly.subplots import make_subplots


rows = df.row.unique().tolist()
cols = df.column.unique().tolist()
groups = df.trt.unique().tolist()
labs = [i + ' ' + j for j in rows for i in cols]
colors = ['red', 'green', 'blue']

fig = make_subplots(rows = len(rows), cols = len(cols),
                    shared_xaxes=True, subplot_titles = labs)

for group, dx in df.groupby(['row','column','trt']):
    r = rows.index( group[0] ) + 1 # 1-based numbering
    c = cols.index( group[1] ) + 1
    name = str(group[2])
    id = groups.index(group[2])
    tr = go.Box( y = dx['y'], boxpoints = 'all', name = name ,marker_color = colors[id], text = dx['p'])
    # tr2 = go.Scatter(x = 'x0', <- how do I get relative x coordinates of tr to put in here ? 
    #                  y = dx['y'].median(), text = dx['p'].unique())
    fig.add_trace( tr, row = r, col = c )

fig.show()

[желательно] Вывод: введите описание изображения здесь

Есть ли простой способ «извлечь» координаты x прямоугольной кривой, чтобы я мог наложить маркер? Похоже, это не должно быть сложно.

1 Ответ

0 голосов
/ 22 августа 2020

В конце концов разобрался. Очевидно, вам просто нужно знать, как сюжетно все настраивается заранее.

Вы можете использовать аннотации с xref и yref, ссылаясь на подзаголовки. Схема присвоения сбивает с толку (для меня) и плохо документирована.

y_ref увеличиваются последовательно снизу-слева, читая слева направо. Таким образом, на этом рисунке нижняя левая панель - это y1, нижняя правая панель - y2, средняя левая панель - y3, средняя правая панель - y4 и т. Д.

ncol = len(cols)

fig = make_subplots(rows = len(rows), cols = len(cols),
                    shared_xaxes=True, subplot_titles = labs)

for group, dx in df.groupby(['row','column','trt']):
    r = rows.index( group[0] ) + 1 # 1-based numbering
    c = cols.index( group[1] ) + 1
    name = str(group[2])
    id = groups.index(group[2])
    tr = go.Box( y = dx['y'], boxpoints = 'all', name = name ,marker_color = colors[id], text = dx['p'])
    fig.add_trace( tr, row = r, col = c )
    xref = 'x' + str(c) 
    yref = 'y' + str( (r-1)*ncol + c ) # yrefs added in strange pattern 
    fig.add_annotation(x = name, 
                       y = dx.y.median(), 
                       text = dx.p.unique()[0], 
                       ax = 0, ay = 0,showarrow = False,
                        xref = xref, yref = yref,
                       font= dict(size = 24))


fig.show()

введите описание изображения здесь

...