You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Plotly中用条形图嵌入贝叶斯网络节点替代标记

Replace Bayesian Network Nodes with Edge Probability Bar Plots (Keep NetworkX Layout)

Got it, let's solve this problem! The goal is to swap out those default node markers with horizontal bar plots showing each node's edge probability distribution, while keeping NetworkX's automatic layout functionality (critical for large networks). Here's a complete, working solution with breakdowns:

Step 1: Define Edge Probabilities for Each Node

First, let's create a dictionary to store the edge probability data for each node—this makes it easy to expand later for larger networks:

node_probabilities = {
    'Rain': {'Yes': 0.3, 'No': 0.7},
    'Sprinkler': {'Yes': 0.2, 'No': 0.8},
    'Grass_Wet': {'Yes': 0.6, 'No': 0.4}
}

Step 2: Full Modified Code

This code replaces each node with a mini horizontal bar plot, positions them using NetworkX's spectral layout, and keeps all edges intact:

import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go
import networkx as nx

# Define Bayesian Network structure
G = nx.DiGraph([('Rain', 'Grass_Wet'), ('Sprinkler', 'Grass_Wet'), ('Rain', 'Sprinkler')])

# Edge probability distributions for each node
node_probabilities = {
    'Rain': {'Yes': 0.3, 'No': 0.7},
    'Sprinkler': {'Yes': 0.2, 'No': 0.8},
    'Grass_Wet': {'Yes': 0.6, 'No': 0.4}
}

app = dash.Dash(__name__)

def generate_network_with_bar_nodes(G, prob_dict):
    pos = nx.drawing.layout.spectral_layout(G)
    # Store node positions in the graph
    for node in G.nodes:
        G.nodes[node]['pos'] = list(pos[node])
    
    traceRecode = []
    # Add edge traces first
    for edge in G.edges:
        x0, y0 = G.nodes[edge[0]]['pos']
        x1, y1 = G.nodes[edge[1]]['pos']
        edge_trace = go.Scatter(
            x=[x0, x1, None], 
            y=[y0, y1, None], 
            mode='lines',
            line={'width': 2, 'color': '#888'}
        )
        traceRecode.append(edge_trace)
    
    # Add bar plot traces for each node
    bar_width = 0.15  # Adjust this to make bars wider/narrower
    bar_spacing = 0.08  # Space between "Yes" and "No" bars
    for node in G.nodes():
        x_node, y_node = G.nodes[node]['pos']
        probs = prob_dict[node]
        categories = list(probs.keys())
        values = list(probs.values())
        
        # Position bars vertically around the node's y-coordinate
        y_positions = [y_node + bar_spacing, y_node - bar_spacing]
        
        # Create bar traces for each category
        for cat, val, y in zip(categories, values, y_positions):
            bar_trace = go.Bar(
                x=[val],
                y=[y],
                orientation='h',
                width=bar_width,
                name=node,
                text=f"{cat}: {val:.2f}",
                textposition='auto',
                marker={'color': '#1f77b4' if cat == 'Yes' else '#ff7f0e'}
            )
            traceRecode.append(bar_trace)
        
        # Add node label above the bars
        label_trace = go.Scatter(
            x=[x_node],
            y=[y_node + bar_spacing + 0.1],
            mode='text',
            text=node,
            textfont={'size': 14, 'weight': 'bold'}
        )
        traceRecode.append(label_trace)
    
    # Layout configuration
    figure = {
        "data": traceRecode,
        "layout": go.Layout(
            title='Bayesian Network with Edge Probability Bars',
            showlegend=False,
            hovermode='closest',
            margin={'b': 40, 'l': 40, 'r': 40, 't': 40},
            xaxis={'showgrid': False, 'zeroline': False, 'showticklabels': False, 'range': [-0.1, 1.1]},
            yaxis={'showgrid': False, 'zeroline': False, 'showticklabels': False},
            height=600
        )
    }
    return figure

app.layout = html.Div(
    [
        html.Div(
            children=[dcc.Graph(id="bayesian-network", figure=generate_network_with_bar_nodes(G, node_probabilities))],
        )
    ]
)

if __name__ == '__main__':
    app.run_server(debug=True)

Key Modifications Explained

  • Node Positioning: We still use NetworkX's spectral_layout to get automatic positions for each node, then anchor each bar plot to those coordinates.
  • Bar Plot Placement: Each node gets two horizontal bars (for "Yes" and "No") stacked vertically around the node's y-position. Adjust bar_width and bar_spacing to tweak the size and spacing of the bars.
  • Node Labels: We add a text trace above each bar group to display the node name, so you still know which bar set corresponds to which node.
  • Edge Preservation: The original edge traces are added first, so bars appear on top of edges (you can reverse the order if you want edges on top).

Customization Tips

  • Adjust bar_width and bar_spacing to fit larger networks (smaller values for more nodes).
  • Change the marker colors in the bar trace to match your preferred color scheme.
  • Modify the xaxis.range if your probabilities go beyond 0-1 (unlikely for edge probabilities, but useful for other cases).
  • Add hover text by expanding the text parameter in the bar trace to include more details.

内容的提问来源于stack exchange,提问作者Mehtab Pathan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 17:23:09