Facet_row_spacing 随着面行的增加而增加

问题描述 投票:0回答:1

我确信有一个简单的解决方案,但在研究了几个小时后,我似乎找不到答案。简而言之 - 我添加到一系列多面散点图中的行越多,行之间的间隙就越大(尽管尝试在所需的行间隙高度中进行硬编码)

我在 Dash 仪表板上有一个按钮,可以根据表中的数据生成散点图:

enter image description here

生成绘图的函数:

def generate_all_curves(unique_key_list):
    hit_curve_data_df = df_curves[df_curves['Unique_key'].isin(unique_key_list)]
    num_rows = math.ceil(len(unique_key_list)/2)
    print("Num rows: "+str(num_rows))
    facet_row_max_spacing = 1/num_rows
    if facet_row_max_spacing > 0.04:
        facet_row_max_spacing = 0.04
    print("Spacing: "+str(facet_row_max_spacing))
    all_curves_figure = px.scatter(hit_curve_data_df, x='Temps', y='Smooth Fluorescence', color='Subplot', color_discrete_sequence=['#FABF73','#F06D4E'],
                        hover_name='Well', hover_data={'Final_decision':False, 'Assay_Plate':False, 'Temps':False, 'Smooth Fluorescence':False, 'Error':True, 'Ctrl_Tm_z-score':True}, #Hover data (Tooltip in Spotfire)
                        facet_col='Unique_key', facet_col_wrap=2, facet_col_spacing=0.08,facet_row_spacing = facet_row_max_spacing,#Facet plots by plate and only allow 2 columns. Column spacing had to be adjusted to allow for individual y-axes
                        render_mode = 'auto', height = 200*num_rows) #Height of plots is equal to half the number of plates (coz 2 columns) with each plot 300px high. Width will have to be adjusted
    return all_curves_figure

然后回调根据数据表中存在的行生成图表:

@app.callback(
    Output('all_graphs_div', 'children'),
    [Input('generate', 'n_clicks'),
     Input('clear', 'n_clicks')],
    [State('results_table_datatable', 'data')])
def update_or_clear_graphs(generate_clicks, clear_clicks, current_table_data):
    ctx = callback_context
    if not ctx.triggered:
        raise PreventUpdate
    trigger_id = ctx.triggered[0]['prop_id'].split('.')[0]
    if trigger_id == 'generate':
        if generate_clicks > 0:
            key_list = [d['Unique_key'] for d in current_table_data]
            new_figure = generate_all_curves(key_list)
            new_figure.update_yaxes(matches=None)
            new_figure.for_each_yaxis(lambda yaxis: yaxis.update(showticklabels=True))
            new_figure.update_layout(height=200 * len(key_list)/2) #Each plot is 400px high (i.e. 200 is half of 400)
            graph_object = dcc.Graph(id='all_graphs_object', figure=new_figure, style={'font-family': 'Arial'})
            return graph_object
    elif trigger_id == 'clear':
        if clear_clicks > 0:
            return None
    raise PreventUpdate

最后,这些对象的布局(只是相关部分)

            #Child A: Data table 
            html.Div([
                    #Data table
                    html.Div([
                    dash_table.DataTable(
                        default_datatable.to_dict('records'), 
                        [{'name': i, 'id': i} for i in default_datatable.loc[:, ['Source_Plate','Well','Subplot','Compound','Fraction','Final_Tm','No. Std Dev','Relative_amplitude','Unique_key']]],
                        id = 'results_table_datatable',
                        hidden_columns=['Unique_key'],
                        css=[{'selector': '.show-hide', 'rule': 'display: none'},{'selector':'.export','rule': 'margin:5px'}],
                        row_deletable=True,
                        sort_action='native',
                        export_format='xlsx',
                        style_data_conditional=data_table_style_data_conditional, 
                        style_table = {'height':'400px','overflow-y':'scroll'},
                        style_as_list_view=True, style_cell={'fontSize':12, 'font-family':'Arial'}, style_header = {'backgroundColor': '#cce6ff','fontWeight': 'bold'}),#Styling of table
                    ], id = 'results_table'),
                    #Generate all hit graphs button
                    html.Div([html.Button('Generate all graphs', id='generate', n_clicks=None, style = {'margin-top':'20px', 'margin-right': '20px'})], style = {'display':'inline-block','vertical-align':'top'}),
                    #Clear all graphs button
                    html.Div([html.Button('Clear all graphs', id='clear', n_clicks=0, style = {'margin-top':'20px'})],style = {'display':'inline-block','vertical-align':'top'}),
                    #Div with the plots
                    html.Div([],id = 'all_graphs_div', style = {'height':'500px','overflow-y':'scroll'})
                    ], 
                id='left_panel',
                style = {'display':'inline-block','vertical-align':'top', 'width': '50%','overflow-y':'scroll','overflow-x':'scroll', 'height':'90%', 'padding':'10px','margin-top':'5px'}), #Styling of table container

如您所见,我尝试动态更改facet_row_spacing。当我只有少量绘图时,我会尝试将其保持在 0.04,因为这样看起来最美观。一旦低于该标记,我就会让它下降到工作所需的任何程度。

当我开始增加绘图数量时,麻烦就来了。尽管我尝试定义面行间距,但这个空间似乎随着面图数量的增加而增加。

例如以下是有 9 个图时的图(即分成两列 = 5 行,间距显然设置为 0.04): enter image description here

但是,当我将其增加到 18 个图(9 行,根据我的打印语句,间距显然仍设置为 0.04)时,但您会注意到每行图之间的间距增加了。

enter image description here

当我尝试将其增加到 56 行(112 个图)时,事情变得很奇怪,这些行(根据 print 语句)应该有 0.0178571429 的facet_row_spacing。然而,随着地块数量或地块行数的增加,行间距变得越来越大。

enter image description here

到底发生了什么事,我做错了什么才会出现这种奇怪的逆行为?是否有相当于 new_figure.update_layout(facet_row_spacing = x) 的东西可以放入回调中?

python plotly plotly-dash scatter-plot dashboard
1个回答
0
投票

发生这种情况是因为

facet_row_spacing
值以图形高度的分数形式指定,设置为
200*num_rows
,因此您需要将此值设置为
x/(200*num_rows)
以获得一致的间距,无论高度如何,而不仅仅是
x/num_rows

如果

0.04
看起来可以容纳 5 行,那么以下内容应该可以正常工作:

height = 200*num_rows
facet_row_max_spacing = 40/height 
© www.soinside.com 2019 - 2024. All rights reserved.