Как выровнять текст слева на гистограмме (пример изображения приведен) [Plotly-Dash] - PullRequest
3 голосов
/ 28 марта 2019

Мне нужна помощь в добавлении текста на график.

Я пробовал text = 'y' и text-position = 'inside', но текст становится вертикальным или сдавливается для маленьких гистограмм, чтобы он мог поместиться внутри бара. Я просто хочу, чтобы это переписали.

Вот рабочий пример кода, который нужно исправить:

app = dash.Dash(__name__)
app.css.append_css({'external_url': 'https://codepen.io/amyoshino/pen/jzXypZ.css'})

    labels1 = ['0-7', '8-12', '13-15', '16-20', '21-25', '26+']
values1 = [10, 30, 10, 5, 6, 8]


labels2 = ['India', 'Scotland', 'Germany', 'NW England', 'N Ireland', 'Norway', 'NE England', 'Paris', 'North Africa', 'scandinavia']
values2 = [1, 0, 4, 9, 11, 18, 50, 7, 0, 2]

values3 = [10, 111, 75, 20]
labels4 = ['Safety Manager', 'Office Administrator', 'Internal Officer', 'Assistant Producer']

bar_color = ['#f6fbfc', '#eef7fa', '#e6f3f7', '#deeff5', '#d6ebf2', '#cde7f0', '#c5e3ed', '#bddfeb', '#b5dbe8', '#add8e6']
bar_color2 = ['#e6f3f7', '#deeff5', '#d6ebf2', '#cde7f0', '#c5e3ed', '#bddfeb', '#b5dbe8', '#add8e6']

app.layout = html.Div([
  html.Div([ 
    html.Div([
        dcc.Graph(id = 'age',
                          figure = {
                                    'data': [go.Bar(x = values1,
                                                    y = labels1,
                                                    orientation = 'h',
                                                    marker=dict(color = bar_color2),
                                                    text = labels1,
                                                    textposition = 'inside'
                                                    )
                                            ],
                                    'layout': go.Layout(title = 'Number of respondees per tenure',
                                                        yaxis=dict(
                                                                   zeroline=False,
                                                                   showline=False,
                                                                   showgrid = False,
                                                                   autorange="reversed",
                                                                   ),
                                                            xaxis=dict(
                                                                      zeroline=False,
                                                                      showline=False,
                                                                      showgrid = False
                                                                      )
                                                       )
                                  }
                         )
    ], className = 'four columns'),


    html.Div([
       dcc.Graph(id = 'location',
                                 figure = {
                                          'data': [go.Bar(x = values2,
                                                          y = labels2,
                                                          orientation = 'h',
                                                          marker=dict(color = bar_color),
                                                            text = labels2,
                                                            textposition = 'inside'
                                                         )
                                                  ],
                                          'layout': go.Layout(title = 'Number of respondees per region',
                                                                yaxis=dict(
                                                                          zeroline=False,
                                                                          showline=False,
                                                                          showgrid = False,
                                                                          autorange="reversed",
                                                                         ),
                                                                xaxis=dict(
                                                                          zeroline=False,
                                                                          showline=False,
                                                                          showgrid = False
                                                                         )                                                             ) 
                                        }
                                )
        ], className = 'four columns'),

    html.Div([
            dcc.Graph(id = 'job',
                                  figure = {
                                            'data': [go.Bar(x = values3,
                                                            y = labels4,
                                                            orientation = 'h',
                                                            marker=dict(color = bar_color2),
                                                            text = labels4,
                                                            textposition = 'inside'                                                            
                                                           )
                                                    ],
                                           'layout': go.Layout(title = 'Number of respondees per role',
                                                               yaxis=dict(
#                                                                         automargin=True,
                                                                          zeroline=False,
                                                                          showline=False,
                                                                          showgrid = False,
                                                                          autorange="reversed",
                                                                         ),
                                                                xaxis=dict(
                                                                          zeroline=False,
                                                                          showline=False,
                                                                          showgrid = False
                                                                         )
                                                              ) 
                                           }
                                )
        ], className = 'four columns')


  ], className = 'row')

])

if __name__ == '__main__':
app.run_server()

Вот вывод:

enter image description here

Вот пример того, как я хочу, чтобы мой текст выглядел: enter image description here

Мне нужна помощь с двумя вещами:

  1. Выровняйте текст по левому краю, а не по правому краю полосы.
  2. Если длина полосы короткая, я хочу, чтобы текст оставался видимым (даже если длина полосы равна нулю), а не сдавлен или выровнен по вертикали.

Если вы также можете дать объяснение того, как исправить обрезание оси Y на третьем графике, это было бы удивительно. На данный момент я должен изменить метки, чтобы заставить его соответствовать, что занимает много времени. Есть ли способ добавить отступ в контейнер или что-то еще?

Спасибо.

Ответы [ 2 ]

1 голос
/ 04 апреля 2019

Вы можете предотвратить срезание оси Y на третьем графике, изменив поля фигуры.Добавьте следующий код во внутреннюю часть вызова к go.Layout():

margin=go.layout.Margin(
        l=150, # left margin, in px
        r=80, # right margin, in px
        t=80, # top margin, in px
        b=80, # bottom margin, in px
        pad=0
        )

. Вы можете отрегулировать левое поле для разных меток оси Y или настроить его на автоматическое масштабирование с длинойсамая длинная этикетка.

Third plot without y-axis cutoff

1 голос
/ 30 марта 2019

Это не изящный обходной путь, но после того, как я просмотрел документальные документы Python, я не смог найти ничего, что могло бы сделать именно то, что вы просили, с предоставленными графическими атрибутами. Если вам нужно одноразовое быстрое исправление сейчас, попробуйте использовать yaxis=dict(showticklabels=False) и добавьте свои метки вручную в виде аннотаций, таких как:

layout = go.Layout(
    # Hide the y tick labels
        yaxis=dict(
        showticklabels=False),
    annotations=[
        dict(
        # I had to try different x values to get alignment
            x=0.8,
            y='giraffes',
            xref='x',
            yref='y',
            text='Giraffes',
            font=dict(
                family='Arial',
                size=24,
                color='rgba(255, 255, 255)'
            ),
            align='left',
        # Don't show any arrow
            showarrow=False,
        ), 

Вывод, который я получил, выглядел так: Plotly Horizontal Bar with Annotations for Labels

Вы можете проверить документацию Plotly Аннотации и Атрибуты диаграммы , чтобы увидеть, есть ли что-то, что лучше соответствует вашим потребностям.

Редактировать: Я начал публиковать этот ответ, прежде чем код был добавлен к вопросу. Вот пример того, как можно сделать аннотации для первых двух меток y первого графа в рассматриваемом коде:

app.layout = html.Div([
  html.Div([ 
    html.Div([
        dcc.Graph(id = 'age',
                          figure = {
                                    'data': [go.Bar(x = values1,
                                                    y = labels1,
                                                    orientation = 'h',
                                                    marker=dict(color = bar_color2),
                                                    text = labels1,
                                                    textposition = 'inside'
                                                    )
                                            ],
                                    'layout': go.Layout(title = 'Number of respondees per tenure',
                                                        yaxis=dict(
                                                                   zeroline=False,
                                                                   showline=False,
                                                                   showgrid = False,
                                                                   showticklabels=False
                                                                   autorange="reversed",
                                                                   ),
                                                            xaxis=dict(
                                                                      zeroline=False,
                                                                      showline=False,
                                                                      showgrid = False
                                                                      )
                                                                   ),
                                                            annotations=[dict(
                                                                        x=0.8,
                                                                        y=labels1[0],
                                                                        xref='x',
                                                                        yref='y',
                                                                        text=labels1[0],
                                                                        font=dict(
                                                                            family='Arial',
                                                                            size=24,
                                                                            color='rgba(255, 255, 255)'
                                                                        ),
                                                                        align='left',
                                                                        showarrow=False,
                                                                    ), 
                                                                    dict(
                                                                        x=1.2,
                                                                        y=labels1[1],
                                                                        xref='x',
                                                                        yref='y',
                                                                        text=labels1[1],
                                                                        font=dict(
                                                                            family='Arial',
                                                                            size=24,
                                                                            color='rgba(255, 255, 255)'
                                                                        ),
                                                                        align='left',
                                                                        showarrow=False,
                                                                    ),

Редактировать 2: @ user8322222, чтобы ответить на вопрос в своем комментарии, вы можете использовать понимание списка, чтобы сделать свой словарь аннотаций следующим образом:

 annotations1 = [dict(x=(len(labels1[i])*0.15), y=labels1[i], xref='x', yref='y', 
text=labels1[i], font=dict(family='Arial', size=24, color='rgba(255, 255, 255)'),
      align='left', showarrow=False) for i in range(len(labels1))]

Однако я не думаю, что будет константа, которую вы могли бы умножить на длину текста в символах (как я использовал для x в примере), чтобы получить идеальное выравнивание. Вы можете использовать длину в пикселях или другие меры для строки, как в этой записи , чтобы разработать более точный способ определения x , чтобы правильно выровнять ее. Надеюсь, это поможет.

...