我在做以下事情時(shí)遇到了很大的困難。我有一個(gè)由 css 格式化的破折號(hào)應(yīng)用程序,以顯示在不同的容器中。標(biāo)記為“hexgrid-1-container”的容器是最大的容器,而其他容器較小,並圍繞該容器組織。我想更新我的破折號(hào)應(yīng)用程序,以便每當(dāng)單擊另一個(gè)容器中的圖形/圖形時(shí),它都會(huì)出現(xiàn)在“hexgrid-1-container”中,而之前位於“hexgrid-1-container”中的圖形會(huì)出現(xiàn)在較小的容器中容器。
我有一個(gè)破折號(hào)應(yīng)用程序,如下所示:
導(dǎo)入破折號(hào) 將 dash_core_components 導(dǎo)入為 dcc 將 dash_html_components 導(dǎo)入為 html 從 dash.dependencies 導(dǎo)入輸入、輸出、狀態(tài) 從 jupyter_dash 導(dǎo)入 JupyterDash 將plotly.express導(dǎo)入為px 導(dǎo)入plotly.graph_objects作為go 將 pandas 導(dǎo)入為 pd 導(dǎo)入sqlite3 導(dǎo)入語(yǔ)言環(huán)境 將 numpy 導(dǎo)入為 np 將plotly.figure_factory匯入為ff 將plotly.express導(dǎo)入為px # 設(shè)定格式化的區(qū)域設(shè)置 locale.setlocale(locale.LC_ALL, '') 應(yīng)用程式 = dash.Dash(__name__) app.layout = html.Div(className='容器玻璃',children=[ html.Div(className='hexgrid-1-container', style={'border': '1px 純黑'}, Children=[ dcc.Graph(id='hexgrid-1', style={"height": "75%", "width": "100%"}, className='hexgrid1') ]), html.Div(className='hexgrid-2-container', style={'border': '1px 純黑'}, Children=[ dcc.Graph(id='hexgrid-2', style={"height": "100%", "width": "100%"}, className='hexgrid2') ]), html.Div(className='base-plot-container', style={'border': '1px 純黑'}, Children=[ dcc.Graph(id='base-plot', style={"height": "100%", "width": "100%"}) ]), html.Div(className='us-map-container', style={'border': '1px 純黑'}, Children=[ dcc.Graph(id='us-map-graph', style={"height": "100%", "width": "100%"}) ]), html.Div(className='第五容器', style={'border': '1px 純黑'}, Children=[ # dcc.Graph(id='us-map-graph', style={"height": "100%", "width": "100%"}) #html.H2("第五個(gè)容器") ]), html.Div(className='第六個(gè)容器', style={'border': '1px 純黑'}, Children=[ # dcc.Graph(id='us-map-graph', style={"height": "100%", "width": "100%"}) #html.H2("第6個(gè)容器") ]) ]) @app.callback( 輸出('hexgrid-1','數(shù)字'), 輸入('hexgrid-1','id') ) def render_hexgrid_1(_): # 開(kāi)啟一個(gè)新的資料庫(kù)連接 conn = sqlite3.connect(r"C:\Users\HituJani\Downloads\txns.db") # 取得交易表中的所有欄位 查詢=''' PRAGMA table_info(交易) ''' # 取得數(shù)據(jù) 資料 = pd.read_sql_query(查詢, conn) # 過(guò)濾掉相關(guān)列,如果想要所有列可以跳過(guò)這一步驟。 related_columns = data[data['name'].isin(['TranType', 'MessageTypeIdentifier', 'MerchantType', 'IResponseCode'])] # 使用列名建立十六進(jìn)位網(wǎng)格 plot_data = go.Scatter(x=relevant_columns.index, y=relevant_columns['name'], text=relevant_columns['name'], 標(biāo)記=dict(符號(hào)='六邊形',大小=30),模式='標(biāo)記文字') 版面 = go.Layout(title="選擇類(lèi)別") 返回 go.Figure(data=[plot_data],layout=layout) @app.callback( 輸出('hexgrid-2','圖'), 輸出('hexgrid-2','樣式'), 輸入('hexgrid-1','clickData') ) def render_hexgrid_2(clickData): # 開(kāi)啟一個(gè)新的資料庫(kù)連接 conn = sqlite3.connect(r"C:\Users\HituJani\Downloads\txns.db") 如果 clickData 為 None: 返回 go.Figure(), {"display": "none"}別的: 類(lèi)別 = clickData['點(diǎn)'][0]['文字'] # 取得交易表中的所有欄位 查詢=''' PRAGMA table_info(交易) ''' # 取得數(shù)據(jù) 資料 = pd.read_sql_query(查詢, conn) # 過(guò)濾掉相關(guān)數(shù)值特徵列 related_columns = data[data['name'].isin(['TransactionAmount', 'OutstandingAmount', 'CurrentBalance', 'TotalOutStgAuthAmt'])] # 在球體表面產(chǎn)生隨機(jī)點(diǎn) phi = np.random.uniform(0, np.pi, len(relevant_columns)) theta = np.random.uniform(0, 2*np.pi, len(relevant_columns)) x = np.cos(theta) * np.sin(phi) y = np.sin(theta) * np.sin(phi) z = np.cos(phi) # 使用球體標(biāo)記建立 3D 散佈圖 分散 = go.Scatter3d( x=x, y=y, z=z, mode='標(biāo)記文字', 標(biāo)記=字典( 大小=12, 顏色=np.arange(len(relevant_columns)), colorscale='Viridis', 符號(hào)='圓圈', 不透明度=0.8 ), 文本=relevant_columns['名稱'], 懸停訊息='文字' ) # 使用網(wǎng)格建立線框球體 u = np.linspace(0, 2 * np.pi, 100) v = np.linspace(0, np.pi, 100) x_sphere = np.outer(np.cos(u), np.sin(v)) y_sphere = np.outer(np.sin(u), np.sin(v)) z_sphere = np.outer(np.ones(np.size(u)), np.cos(v)) 球體 = go.Mesh3d(x=x_sphere.ravel(), y=y_sphere.ravel(), z=z_sphere.ravel(), 不透明度=0.1, 顏色='青色') # 將散佈圖和線框圖合併為一個(gè)圖形 Fig = go.Figure(data=[散點(diǎn)圖, 球體]) 圖.update_layout( 邊距=dict(l=0, r=0, b=0, t=0), 場(chǎng)景=字典( xaxis=dict(標(biāo)題=無(wú),可見(jiàn)=假), yaxis=dict(標(biāo)題=無(wú),可見(jiàn)=假), zaxis=dict(標(biāo)題=無(wú),可見(jiàn)=假), ), 模板='plotly_dark' ) 返回?zé)o花果,{“高度”:“50vh”,“寬度”:“100%”,“顯示”:“內(nèi)聯(lián)塊”} # 定義將更新繪圖、反白球體並啟用向下鑽取的回呼函數(shù) @app.callback( 輸出('基本圖','圖'), 輸入('hexgrid-2','clickData'), 狀態(tài)('hexgrid-1','clickData') ) def update_base_plot(clickData_hexgrid_2, clickData_hexgrid_1): 嘗試: # 開(kāi)啟一個(gè)新的資料庫(kù)連接 conn = sqlite3.connect(r"C:\Users\HituJani\Downloads\txns.db") 類(lèi)別 = clickData_hexgrid_1['點(diǎn)'][0]['文字'] numeric_feature = clickData_hexgrid_2['點(diǎn)'][0]['文字'] # SQL 查詢根據(jù)選定的類(lèi)別和數(shù)值特徵檢索聚合數(shù)據(jù) 查詢 = f''' SELECT {category}, WeekOfMonth, SUM({numerical_feature}) AS 總計(jì)金額 來(lái)自交易 按{類(lèi)別}分組, 每月一周 以總金額 DESC 排序 ''' # 從資料庫(kù)取得數(shù)據(jù) df_base = pd.read_sql(查詢, conn) # 關(guān)閉資料庫(kù)連接 conn.close() # 設(shè)定總計(jì)列的格式 df_base['TotalAmount'] = df_base['TotalAmount'].apply(lambda x: locale.currency(x, grouping=True)) # 使用球體標(biāo)記建立 3D 散佈圖 圖 = go.Figure() # 定義 WeekOfMonth 值的色階 色階 = [ [0, '藍(lán)色'], # 第 1 週:藍(lán)色 [0.25, '紫色'], # 第 2 週:紫色 [0.5, 'darkorange'], # 第 3 週:深橙色 [0.75, '黃色'], # 第 4 週:黃色 [1, '粉紅色'] # 第 5 週:粉紅色 ] # 新增散點(diǎn)圖軌跡 圖.add_trace( 去.Scatter3d( x=df_base[類(lèi)別], y=df_base['WeekOfMonth'].astype(int), z=df_base['總金額'], mode='標(biāo)記文字', 標(biāo)記=字典( size=5, # 調(diào)整標(biāo)記的大小,使其變小 symbol='circle', # 使用 'circle' 符號(hào)表示球體 顏色=df_base['WeekOfMonth'], 色標(biāo)=色標(biāo), ), textposition='頂部中心', 懸停模板=( f"<b>{類(lèi)別}</b>: %{{x}}<br>" “<b>總金額</b>:%{z}<br>” “<b>每月週</b>:%{y}<br>” ) ) ) # 動(dòng)態(tài)設(shè)定y軸範(fàn)圍 y_max = df_base['WeekOfMonth'].max() 圖.update_layout( 場(chǎng)景=字典( x軸=字典( 標(biāo)題=類(lèi)別, title_font = dict(大小= 14,顏色='暗橙色'), visible=False # 隱藏x軸 ), y軸=字典( title='一個(gè)月中的第幾週', title_font = dict(大小= 14,顏色='紫色'), 勾選模式='數(shù)組', 刻度值=[0.5, 1.5, 2.5, 3.5, 4.5, 5.5], ticktext=['1', '2', '3', '4', '5'], # 將刻度標(biāo)籤顯示為 1, 2, 3, 4, 5], visible=False # 隱藏 y 軸 ), z軸=字典( title=f'總計(jì){numerical_feature} ($)', title_font = dict(大小= 14,顏色='黃色'), 自動(dòng)範(fàn)圍='反轉(zhuǎn)', visible=False # 隱藏 z 軸 ), ), x軸=字典( 型態(tài)='類(lèi)別', 刻度模式='線性', 刻度角=45, 自動(dòng)保證金=真, visible=False # 隱藏x軸標(biāo)籤 ), margin=dict(l=10, r=10, t=10, b=10), # 增加b值以放大檢視窗口 模板='plotly_dark', ) 返回?zé)o花果 除了異常 e: 列印(f“錯(cuò)誤:{e}”) 返回 go.Figure() @app.callback( 輸出('美國(guó)地圖圖','圖'), 輸出('我們地圖圖','風(fēng)格'), 輸入('基本圖','clickData'), 狀態(tài)('hexgrid-1','clickData'), 狀態(tài)('hexgrid-2','clickData') ) def display_transaction_amount(base_plot_click_data, hexgrid_1_clickData, hexgrid_2_clickData): 嘗試: # 檢查hexgrid-1和hexgrid-2的資料是否可用 如果 hexgrid_1_clickData 為 None 或 hexgrid_2_clickData 為 None: # 傳回一個(gè)空?qǐng)D形並隱藏地圖 返回 go.Figure(), {"display": "none"} # 從hexgrid-1中取得選定的類(lèi)別,從hexgrid-2中取得數(shù)值特徵 selected_category = hexgrid_1_clickData['點(diǎn)'][0]['文字'] numeric_feature = hexgrid_2_clickData['點(diǎn)'][0]['文字'] # 從base_plot_click_data取得選定的子類(lèi)別 選定的子類(lèi)別=無(wú) 如果 base_plot_click_data 不是 None: selected_subcategory = base_plot_click_data['點(diǎn)'][0]['x'] # 開(kāi)啟一個(gè)新的資料庫(kù)連接 conn = sqlite3.connect(r"C:\Users\HituJani\Downloads\txns.db") # SQL 查詢會(huì)依狀態(tài)擷取所選類(lèi)別、子類(lèi)別和數(shù)字特徵的交易數(shù)據(jù) 查詢 = f''' SELECT StateCode, {selected_category}, SUM({numerical_feature}) AS TotalTransactionAmount 來(lái)自交易 哪裡 {selected_category} = ? 按州代碼分組,{selected_category} ''' # 執(zhí)行查詢並將結(jié)果擷取到DataFrame中 state_data = pd.read_sql(query, conn, params=(selected_subcategory,)) # 關(guān)閉資料庫(kù)連接 conn.close() # 使用過(guò)濾後的資料建立 Choropleth 地圖 無(wú)花果 = px.choropleth( 數(shù)據(jù)幀=狀態(tài)數(shù)據(jù), locationmode='美國(guó)各州', 位置='州代碼', 範(fàn)圍='美國(guó)', color='總交易金額', hide_data={'StateCode': True, 'TotalTransactionAmount': ':$,f'}, color_continuous_scale='紅色', labels={'TotalTransactionAmount': '交易總金額'}, 模板='plotly_dark' ) 圖.update_traces( hidetemplate="<b>%{customdata[0]}</b><br>" "<b>總交易金額</b>: $%{customdata[1]:,.2f}<br>", customdata=list(zip(state_data['StateCode'], state_data['TotalTransactionAmount'])) ) 圖.update_layout( title_text=f'類(lèi)別:{selected_category}、子類(lèi)別:{selected_subcategory}的州總交易金額', title_xanchor='中心', title_font=dict(大小=12), 標(biāo)題_x=0.5, 地理=字典(範(fàn)圍='美國(guó)'), ) # 返回圖形並設(shè)定顯示樣式為block(可見(jiàn)) 返回?zé)o花果,{“顯示”:“塊”} 除了異常 e: 列?。╢“錯(cuò)誤:{e}”) 返回 go.Figure(), {"display": "none"} 如果 __name__ == '__main__': app.run_server(debug=True, use_reloader=False)
另外,我還有這個(gè)整理網(wǎng)頁(yè)的css檔:
/* styles.css */ 。容器 { 顯示:網(wǎng)格; 網(wǎng)格模板行:1fr 1fr 1fr; 網(wǎng)格模板列:1fr 1fr 1fr; 網(wǎng)格列間隙:15px; 網(wǎng)格行間距:15px; 背景圖像: url("https://plainbackground.com/plain1024/383c3d.png"); 背景大?。?00%; 背景位置:網(wǎng)格-ce; } .hexgrid-1-container { /* 網(wǎng)格區(qū)域: 1/1/3/3; */ 網(wǎng)格行:跨度2; 網(wǎng)格列:跨度 2; 內(nèi)邊距:2 像素 2 像素 2 像素 2 像素; 邊框:1px 實(shí)心 hsl(176, 87%, 7%, 0.6); 邊框半徑:10px; 框陰影: rgba(250, 118, 3, 0.4) -5px 5px, rgba(250, 118, 3, 0.3) -10px 10px, rgba(250, 118, 3, 0.2) -15px 背景:hsla(0, 7%, 11%, 0.9); 位置:相對(duì); } .hexgrid-2-container { 網(wǎng)格面積:1/3/2/4; 填充:3rem 4rem 4rem; 寬度:70%; 邊框:1px 實(shí)心 hsl(176, 87%, 7%, 0.6); 邊框半徑:10px; 框陰影: rgba(250, 118, 3, 0.4) -5px 5px, rgba(250, 118, 3, 0.3) -10px 10px, rgba(250, 118, 3, 0.2) -15px 背景:hsl(0, 7%, 11%, 0.9); 位置:相對(duì); } .base-plot-container { /* 在此新增基本圖容器的自訂樣式 */ 網(wǎng)格面積:2/3/3/4; 填充:3rem 4rem 4rem; 寬度:70%; 邊框:1px 實(shí)心 hsl(176, 87%, 7%, 0.6); 邊框半徑:10px; 框陰影: rgba(250, 118, 3, 0.4) -5px 5px, rgba(250, 118, 3, 0.3) -10px 10px, rgba(250, 118, 3, 0.2) -15px 背景:hsl(0, 7%, 11%, 0.9); 位置:相對(duì); } .us-map-container { 網(wǎng)格面積:3/3/4/4; 填充:3rem 4rem 4rem; 寬度:70%; /* 位置:固定; */ 邊框:1px 實(shí)心 hsl(176, 87%, 7%, 0.6); 邊框半徑:10px; 框陰影: rgba(250, 118, 3, 0.4) -5px 5px, rgba(250, 118, 3, 0.3) -10px 10px, rgba(250, 118, 3, 0.2) -15px 背景:hsl(0, 7%, 11%, 0.9); 位置:相對(duì); } .第五容器{ 網(wǎng)格面積:3/2/4/3; 邊框:1px 實(shí)心 hsl(176, 87%, 7%, 0.6); 邊框半徑:10px; 框陰影: rgba(250, 118, 3, 0.4) -5px 5px, rgba(250, 118, 3, 0.3) -10px 10px, rgba(250, 118, 3, 0.2) -15px 背景:hsl(0, 7%, 11%, 0.9); 位置:相對(duì); } .第六個(gè)容器{ 網(wǎng)格面積:3/1/4/2; 邊框:1px 實(shí)心 hsl(176, 87%, 7%, 0.6); 邊框半徑:10px; 框陰影: rgba(250, 118, 3, 0.4) -5px 5px, rgba(250, 118, 3, 0.3) -10px 10px, rgba(250, 118, 3, 0.2) -15px 背景:hsl(0, 7%, 11%, 0.9); 位置:相對(duì); }
我嘗試更新回調(diào)函數(shù),但進(jìn)展不大,而且似乎我做錯(cuò)了很多事情。實(shí)現(xiàn)此功能的最直接方法是什麼?先謝謝您。
您可以進(jìn)行回呼來(lái)偵聽(tīng)點(diǎn)擊事件,交換圖形位置,然後將圖形回到更新的位置。您需要根據(jù)您的用例設(shè)定點(diǎn)擊邏輯。你可以實(shí)現(xiàn)這樣的東西:
@app.callback( Output('hexgrid-1-container', 'children'), Output('hexgrid-2-container', 'children'), Input('hexgrid-2', 'clickData'), State('hexgrid-1-container', 'children'), State('hexgrid-2-container', 'children') ) def swap_graphs(clickData, hexgrid_1_children, hexgrid_2_children): clicked_graph_id = 1 # Assuming hexgrid-2 was clicked, you can change this logic based on your use case if clicked_graph_id == 1: # Swap graph between hexgrid-1 and hexgrid-2 return hexgrid_2_children, hexgrid_1_children return hexgrid_1_children, hexgrid_2_children#