I have the following function that draws a graph on plotly figure. I want the figure to restart x-axis on each domain starting position (stored in ‘domain’ attribute of the networkx graph) as in the matplotlib examples in the attached figure.
My code is
def draw_plotly_domains(G,title):
positions=nx.get_node_attributes(G,'pos')
domains=nx.get_node_attributes(G,'domain')
final_positions = {}
for pos, dom in zip(positions.items(), domains.items()):
label, (x, y) = pos
_, d = dom
idx_dom = int(d_to_idx[d])
final_positions[label] = [x + domain_starts[idx_dom-1], y]
edge_x = []
edge_y = []
for edge in G.edges():
x0, y0 = final_positions[edge[0]][0],final_positions[edge[0]][1]
x1, y1 = final_positions[edge[1]][0],final_positions[edge[1]][1]
edge_x.append(x0)
edge_x.append(x1)
edge_x.append(None)
edge_y.append(y0)
edge_y.append(y1)
edge_y.append(None)
edge_trace = go.Scatter(
x=edge_x, y=edge_y,
line=dict(width=0.5, color='#888'),
hoverinfo='none',
mode='lines')
node_x = [] # position
node_y = [] # copy number
node_id = [] # node id
node_chr = []
for node in G.nodes():
x, y = G.nodes[node]['pos']
node_x.append(x)
node_y.append(y)
node_id.append(node)
node_chr.append(int(df[df['Source']==node].Domain.values[0])) # item() returns numbers as str
unique_values = len(set(df.Domain.to_list()))
unique_values = len(set(node_chr))
color_bar_values = [val for val in np.linspace(0, 1, unique_values+1) for _ in range(2)]
discrete_colors = [val for val in px.colors.qualitative.Alphabet for _ in range(2)]
colorscale = [[value, color] for value, color in zip(color_bar_values, discrete_colors[1:])]
colorscale.pop(0)
colorscale.pop(-1)
### Compile hover text for each node
node_text = []
for n,node in enumerate(G.nodes()):
next_node='None' if n==len(G.nodes())-1 else ','.join(str(i) for i in df[df['Source']==node]['Sink'].to_list() if i!='loose')
prev_node='None' if n==0 else ','.join(str(i) for i in df[df['Sink']==node]['Source'].to_list())
node_text.append(f'Prev: {prev_node}<br><b>-Node:{node}-</b><br>Next: {next_node}<br>Domain: {node_chr[n]}<br>CN:
node_trace = go.Scatter(
x=node_x, y=node_y,
mode='markers',
hoverinfo='text',
text=node_text,
marker=dict(
showscale=True,
colorscale=colorscale,
reversescale=True,
color=node_chr,
size=10,
symbol=0,
colorbar=dict(
thickness=15,
title='Domain Number',
xanchor='left',
titleside='right'
),
line_width=2))
fig = go.Figure(data=[edge_trace, node_trace],
layout=go.Layout(
title=title,
titlefont_size=16,
showlegend=False,
hovermode='closest',
margin=dict(b=20,l=15,r=5,t=40),
annotations=[ dict(
text=f"Number of nodes: {len(node_y)}",
showarrow=False,
xref="paper", yref="paper",
x=0.1, y=1 ) ],
xaxis=dict(showgrid=True, zeroline=True, showticklabels=True,showline=True,title_text = "Start Point"),
yaxis=dict(showgrid=True, zeroline=True, showticklabels=True,showline=True,title_text = "Amplitude")
)
)
fig.show()
As you may notice, I created the position of each node with the dictionary final_positions
so that each node can be placed accordingly on the x-axis. So, domains contribute to the x-axis position but I don’t want to see this cumulative sum on the x-axis but the restart x-axis with each domain starting point. The contribution of each domain by their length is given in the following code block
domain_lengths = {'1': 250_000_000,
'2': 245_000_000,
'3': 200_000_000,
'4': 195_000_000,
'5': 185_000_000,
'6': 175_000_000,
'7': 160_000_000,
'8': 146_000_000,
'9': 142_000_000,
'10': 136_000_000,
'11': 136_000_000,
'12': 135_000_000,
'13': 116_000_000,
'14': 108_000_000,
'15': 103_000_000,
'16': 91_000_000,
'17': 82_000_000,
'18': 80_000_000,
'19': 60_000_000,
'20': 64_000_000,
'21': 48_000_000}
domain_starts = []
start = 0
domain_starts.append(start)
for cl in chr_lengths.values():
start += cl
domain_starts.append(start)
I’d appreciate any help. At the moment, x-axis is just one piece and node positions are not correct. For simple test case, you can use the following networkx graph (not the same graph in the picture I share, but should be helpful enough)
import networkx as nx
G = nx.DiGraph()
G.add_node(1534, pos=(22803603, 7), domain=1)
G.add_node(945, pos=(32494954, 5), domain=5)
G.add_node(946, pos=(32530403, 3), domain=6)
G.add_edge(1534, 945)
G.add_edge(945, 946)