Discontinous colors while drawing networkx graphs

Hello,

I am following this example showing how to draw networkx graphs with plotly: Network graphs in Python

All I want is to find a way to use discontinuous color bar and the result should be something like β€˜1’ is red, β€˜2’ is blue etc. with no interpolation between integers. The numbers are already integers here, but as it is noted in the documentation (Discrete colors in Python), if the input is an array of numbers, it will be treated as a continues color scale.

I tried adding a str() around each appended number as

node_adjacencies.append(str(len(adjacencies[1])))

but this returns this error

  raise ValueError(
ValueError: 
    Invalid element(s) received for the 'color' property of scatter.marker
        Invalid elements include: ['12', '12', '15', '12', '9', '8', '4', '6', '8', '10']

    The 'color' property is a color and may be specified as:
      - A hex string (e.g. '#ff0000')
      - An rgb/rgba string (e.g. 'rgb(255,0,0)')
      - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
      - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
      - A named CSS color:
            aliceblue, antiquewhite, aqua, aquamarine, azure,
            beige, bisque, black, blanchedalmond, blue,
            blueviolet, ...,
            yellow, yellowgreen
      - A number that will be interpreted as a color
        according to scatter.marker.colorscale
      - A list or array of any of the above

Any ideas how to fix this? Any alternative method to assign colors?

Thanks.

Hi @munal , welcome to the forums

EDIT:

You are searching for a discrete colorbar. Helpful topics:

Applying these two to the example from the docs you stated:

import plotly.graph_objects as go
import networkx as nx
import numpy

G = nx.random_geometric_graph(200, 0.125)

edge_x = []
edge_y = []
for edge in G.edges():
    x0, y0 = G.nodes[edge[0]]['pos']
    x1, y1 = G.nodes[edge[1]]['pos']
    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 = []
node_y = []
for node in G.nodes():
    x, y = G.nodes[node]['pos']
    node_x.append(x)
    node_y.append(y)

node_adjacencies = []
node_text = []
for node, adjacencies in enumerate(G.adjacency()):
    node_adjacencies.append(len(adjacencies[1]))
    node_text.append('# of connections: '+str(len(adjacencies[1])))

# ------ this is the part where the discrete color bar is created ------
# how many colors do we need?
unique_values = len(set(node_adjacencies))

# create spaced numbers between 0 and 1
# double the values, i.e. 0, 0, 1, 1, 2, 2 
color_bar_values = [val for val in np.linspace(0, 1, unique_values) for _ in range(2)]

# get some color values, you could also use a list of strings such as ['red', 'green'...] instead of px.colors.qualitative.Alphabet
# double the values, i.e. 'red', 'red', 'green', 'green'
discrete_colors = [val for val in px.colors.qualitative.Alphabet for _ in range(2)]

# combine values and colors, start colors at index 1
colorscale = [[value, color] for value, color in zip(color_bar_values, discrete_colors[1:])]

# delete first and last list item
colorscale.pop(0)
colorscale.pop(-1)

# ceate trace
node_trace = go.Scatter(
    x=node_x, y=node_y,
    mode='markers',
    hoverinfo='text',
    marker=dict(
        showscale=True,
        colorscale=colorscale,  # our discrete colorscale 
        color=node_adjacencies,
        cmin=min(node_adjacencies),               
        cmax=max(node_adjacencies),
        size=10,
        line_width=2,
        colorbar=dict(
            title='Month',
            tickvals= node_adjacencies, # custom tick vals and text
            ticktext= node_adjacencies
        )
    ),
    text=node_text
)

# create figure
fig = go.Figure(data=[edge_trace, node_trace],
             layout=go.Layout(
                title='<br>Network graph made with Python',
                titlefont_size=16,
                showlegend=False,
                hovermode='closest',
                margin=dict(b=20,l=5,r=5,t=40),
                annotations=[ dict(
                    text="Python code: <a href='https://plotly.com/ipython-notebooks/network-graphs/'> https://plotly.com/ipython-notebooks/network-graphs/</a>",
                    showarrow=False,
                    xref="paper", yref="paper",
                    x=0.005, y=-0.002 ) ],
                xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
                yaxis=dict(showgrid=False, zeroline=False, showticklabels=False))
                )
fig.show()

creates:


mrep colorscale

1 Like

thank you for the help. this works well,

1 Like