Встраивание отдельной метки в гистограмму с графическим выражением

#plotly #histogram #plotly-python #plotly-express

Вопрос:

Я хотел бы встроить отдельные метки в каждый столбец гистограммы plotly express.

В качестве примера:

 import plotly.express as px
import pandas as pd
    
df = pd.DataFrame({'name':['label1', 'label2','label3', 'label4', 'label1'],
                   'val1':[1,2,1,2,1]})

px.histogram(df, x='val1', nbins=3)
 

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

Возможно ли ['label1', 'label3'] , ['label2', 'label4'] чтобы они отображались в 1-м и 2-м столбцах графика гистограммы соответственно?

Ответ №1:

  • также обрабатывайте данные в панд
  • добавьте дополнительную информацию на рисунок в виде аннотаций
 import plotly.express as px
import pandas as pd
    
df = pd.DataFrame({'name':['label1', 'label2','label3', 'label4', 'label1'],
                   'val1':[1,2,1,2,1]})

fig = px.histogram(df, x='val1', nbins=3)

# work out bins in pandas...
df2 = (
    df.groupby(pd.cut(df["val1"], bins=3))
    .agg(
        count=("name", "size"),
        labels=("name", lambda s: ",".join(s.drop_duplicates().tolist())),
    )
    .assign(
        l=lambda d: [i.left for i in d.index.values],
        r=lambda d: [i.right for i in d.index.values],
        x=lambda d: [(i.left i.right)/2 for i in d.index.values],
        count=lambda d: d["count"].astype(float)
    )
).fillna("")

# add text to histogram
for r in df2.iterrows():
    fig.add_annotation(text=r[1]["labels"], x=(r[1]["l"] r[1]["r"])/2, y=r[1]["count"] .2, showarrow=False)

fig
 

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

Комментарии:

1. Большое спасибо за ваше решение, Роб. Очень признателен! Однако я упростил проблему, так как в моем наборе данных есть еще много классов в Val1 , а также много длинных описаний отдельных меток в каждом классе. Поэтому, если быть более точным, я хотел посмотреть, будут ли, например, 10 лучших меток отображаться в интерактивном режиме при наведении курсора мыши на каждую панель.

2. довольно просто — всего 5 этикеток: labels=("name", lambda s: ",".join(s.drop_duplicates().tolist()[0:5]))

3. если вы хотите строить как при наведении, я бы предпочел перейти на px.bar , а не на гистограмму. У вас есть все, что вам нужно в df2 , чтобы сгенерировать простую линейчатую фигуру