简体   繁体   中英

How to create a bar plot with shared x-axis using plotly.express with sub-titles on top?

I wonder how to correctly create a bar plot with shared x-axis in plotly? I created this bar plot and specified fig.update_xaxes(matches='x') which to my understanding is supposed to match the axes, but apparently this is not working. Does this look like a bug or am I doing something wrong? As you can see, it looks good except for one sub-figure, which is totally off. Sometimes, using facet_row instead of facet_col gives better results, but then the titles appear at the side of the plot. The titles are sometimes quite long and would not fit there. Therefore, I am using facet_col .

fig = px.bar(data_frame=df, x='RawFile', y=plot_column, 
             facet_col='Majority protein IDs', facet_col_wrap=1, color=color, 
             color_discrete_sequence=px.colors.qualitative.Dark24,
             color_continuous_scale=px.colors.sequential.Rainbow)

n_rows = len(df['Majority protein IDs'].drop_duplicates())

height = 300*(1+n_rows)

fig.update_layout(
        height=height,        
        margin=dict( l=50, r=10, b=200, t=50, pad=0 ),
        hovermode='closest')

fig.for_each_annotation(lambda a: a.update(text=a.text.split("=")[-1]))
fig.update(layout_showlegend=True)
fig.update_xaxes(matches='x')

在此处输入图像描述

Strangely the y-axes are shared, but the x-axes are not. That is quite the opposite of what I am looking for.

在此处输入图像描述

# django-plotly-dash        1.6.3
# plotly                    4.14.3

I guess one solution to this would be to use facet_row however, then then I would need to move the titles from the righthand side to the top.

My understanding is that you'd like all plot title to appear right on top of all subplots. There does not seem to be any built-in functionality to do this for plotly express. You always have the possility to adjust the elements of the figure, but it's a bit tricky in this case since you would have to adjust the heights of all subplots to make room for the titles. Here's my best attempt so far with a sample dataset:

在此处输入图像描述

If this is something you can use, we can take a closer look at the details.

Complete code:

import plotly.express as px
df = px.data.tips()
fig = px.scatter(df, x="total_bill", y="tip", color="smoker", facet_row="sex")
f = fig.full_figure_for_development(warn=False)

yrefs = []
for i, elem in enumerate(fig.layout):
    if elem[:5] == 'yaxis':
        yrefs.append(fig.layout[elem].domain[1])

for i, title in enumerate(fig.layout.annotations):
    title.textangle = 0
    title.y = yrefs[i] - 0.03
#     title.x = 0.5 - ((len(title.text)+1) / 100)
    title.x = 0.40
    title.align = 'center'
    title.bgcolor='rgba(0,0,0,0.25)'
    
fig.show()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM