如何对齐 plotly 条形图上的文本(包含示例图像)[Plotly-Dash]
How to align text left on a plotly bar chart (example image contained) [Plotly-Dash]
我需要帮助向我的图表添加文本。
我已经尝试过 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()
这是输出:
下面是我希望文本显示的示例:
我需要两件事的帮助:
- 使文本向左对齐而不是向右对齐。
- 如果条形长度较短,我希望文本仍然可见(即使条形长度为零)并且不被压扁或垂直对齐。
如果你也能解释一下如何修复第三张图表中被切断的 y 轴,那就太棒了。现在,我必须更改标签以使其适合,这很耗时。有没有办法给容器添加填充之类的东西?
谢谢。
这是一个不优雅的解决方法,但是在搜索了 plotly python 文档之后,我找不到任何可以完全按照您所要求的提供的 plotly 属性的内容。如果您现在需要一次性快速修复,请尝试使用 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 Annotations and Chart Attributes 文档,看看是否有更适合您需求的内容。
编辑: 在将代码添加到问题之前,我开始发布此回复。下面是一个示例,说明如何为相关代码中第一个图表的前两个 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 的常数)以获得完美结盟。您可以使用 this post 中的像素长度或其他字符串度量来设计一种更准确的方法来确定 x 以使其正确对齐。希望对您有所帮助。
您可以通过更改图的边距来防止第三张图表中的 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 轴标签的左边距,或者您可以将其设置为根据最长标签的长度自动缩放。
您可以将 text
传递给 go.Bar()
,您可以在其中设置 textposition="inside"
和 insidetextanchor="start"
,这应该可以解决此问题。
fig = go.Figure(go.Bar(
x=[20, 14, 23],
y=['giraffes', 'orangutans', 'monkeys'],
orientation='h',
# define the annotations
text=['giraffes', 'orangutans', 'monkeys'],
# position, "auto", "inside" or "outside"
textposition="auto",
# anchor could be "start" or "end"
insidetextanchor="start",
insidetextfont=dict(family='Times', size=13, color='white'),
outsidetextfont=dict(family='Times', size=13, color='white')))
fig.update_layout(
yaxis=dict(
showticklabels=False,
))
fig.show()
我需要帮助向我的图表添加文本。
我已经尝试过 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()
这是输出:
下面是我希望文本显示的示例:
我需要两件事的帮助:
- 使文本向左对齐而不是向右对齐。
- 如果条形长度较短,我希望文本仍然可见(即使条形长度为零)并且不被压扁或垂直对齐。
如果你也能解释一下如何修复第三张图表中被切断的 y 轴,那就太棒了。现在,我必须更改标签以使其适合,这很耗时。有没有办法给容器添加填充之类的东西?
谢谢。
这是一个不优雅的解决方法,但是在搜索了 plotly python 文档之后,我找不到任何可以完全按照您所要求的提供的 plotly 属性的内容。如果您现在需要一次性快速修复,请尝试使用 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 Annotations and Chart Attributes 文档,看看是否有更适合您需求的内容。
编辑: 在将代码添加到问题之前,我开始发布此回复。下面是一个示例,说明如何为相关代码中第一个图表的前两个 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 的常数)以获得完美结盟。您可以使用 this post 中的像素长度或其他字符串度量来设计一种更准确的方法来确定 x 以使其正确对齐。希望对您有所帮助。
您可以通过更改图的边距来防止第三张图表中的 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 轴标签的左边距,或者您可以将其设置为根据最长标签的长度自动缩放。
您可以将 text
传递给 go.Bar()
,您可以在其中设置 textposition="inside"
和 insidetextanchor="start"
,这应该可以解决此问题。
fig = go.Figure(go.Bar(
x=[20, 14, 23],
y=['giraffes', 'orangutans', 'monkeys'],
orientation='h',
# define the annotations
text=['giraffes', 'orangutans', 'monkeys'],
# position, "auto", "inside" or "outside"
textposition="auto",
# anchor could be "start" or "end"
insidetextanchor="start",
insidetextfont=dict(family='Times', size=13, color='white'),
outsidetextfont=dict(family='Times', size=13, color='white')))
fig.update_layout(
yaxis=dict(
showticklabels=False,
))
fig.show()