我确信有一个简单的解决方案,但在研究了几个小时后,我似乎找不到答案。简而言之 - 我添加到一系列多面散点图中的行越多,行之间的间隙就越大(尽管尝试在所需的行间隙高度中进行硬编码)
我在 Dash 仪表板上有一个按钮,可以根据表中的数据生成散点图:
生成绘图的函数:
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):
但是,当我将其增加到 18 个图(9 行,根据我的打印语句,间距显然仍设置为 0.04)时,但您会注意到每行图之间的间距增加了。
当我尝试将其增加到 56 行(112 个图)时,事情变得很奇怪,这些行(根据 print 语句)应该有 0.0178571429 的facet_row_spacing。然而,随着地块数量或地块行数的增加,行间距变得越来越大。
到底发生了什么事,我做错了什么才会出现这种奇怪的逆行为?是否有相当于 new_figure.update_layout(facet_row_spacing = x) 的东西可以放入回调中?
发生这种情况是因为
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