Beispiel #1
0
def plot_network(wn,
                 node_attribute=None,
                 link_attribute=None,
                 title=None,
                 node_size=20,
                 node_range=[None, None],
                 node_alpha=1,
                 node_cmap=None,
                 node_labels=False,
                 link_width=1,
                 link_range=[None, None],
                 link_alpha=1,
                 link_cmap=None,
                 link_labels=False,
                 add_colorbar=True,
                 node_colorbar_label='Node',
                 link_colorbar_label='Link',
                 directed=False,
                 ax=None,
                 filename=None):
    """
    Plot network graphic
	
    Parameters
    ----------
    wn : wntr WaterNetworkModel
        A WaterNetworkModel object
		
    node_attribute : None, str, list, pd.Series, or dict, optional
	
        - If node_attribute is a string, then a node attribute dictionary is
          created using node_attribute = wn.query_node_attribute(str)
        - If node_attribute is a list, then each node in the list is given a 
          value of 1.
        - If node_attribute is a pd.Series, then it should be in the format
          {nodeid: x} where nodeid is a string and x is a float. 
        - If node_attribute is a dict, then it should be in the format
          {nodeid: x} where nodeid is a string and x is a float
    
	link_attribute : None, str, list, pd.Series, or dict, optional
	
        - If link_attribute is a string, then a link attribute dictionary is
          created using edge_attribute = wn.query_link_attribute(str)
        - If link_attribute is a list, then each link in the list is given a 
          value of 1.
        - If link_attribute is a pd.Series, then it should be in the format
          {linkid: x} where linkid is a string and x is a float. 
        - If link_attribute is a dict, then it should be in the format
          {linkid: x} where linkid is a string and x is a float.
		  
    title: str, optional
        Plot title 

    node_size: int, optional
        Node size 

    node_range: list, optional
        Node range ([None,None] indicates autoscale)
        
    node_alpha: int, optional
        Node transparency
        
    node_cmap: matplotlib.pyplot.cm colormap or list of named colors, optional
        Node colormap 
        
    node_labels: bool, optional
        If True, the graph will include each node labelled with its name. 
        
    link_width: int, optional
        Link width
		
    link_range : list, optional
        Link range ([None,None] indicates autoscale)
		
    link_alpha : int, optional
        Link transparency
    
    link_cmap: matplotlib.pyplot.cm colormap or list of named colors, optional
        Link colormap
        
    link_labels: bool, optional
        If True, the graph will include each link labelled with its name.
        
    add_colorbar: bool, optional
        Add colorbar

    node_colorbar_label: str, optional
        Node colorbar label
        
    link_colorbar_label: str, optional
        Link colorbar label
        
    directed: bool, optional
        If True, plot the directed graph
    
    ax: matplotlib axes object, optional
        Axes for plotting (None indicates that a new figure with a single 
        axes will be used)
    
    filename : str, optional
        Filename used to save the figure
        
    Returns
    -------
    ax : matplotlib axes object  
    """

    if ax is None:  # create a new figure
        plt.figure(facecolor='w', edgecolor='k')
        ax = plt.gca()

    # Graph
    G = wn.get_graph()
    if not directed:
        G = G.to_undirected()

    # Position
    pos = nx.get_node_attributes(G, 'pos')
    if len(pos) == 0:
        pos = None

    # Define node properties
    add_node_colorbar = add_colorbar
    if node_attribute is not None:

        if isinstance(node_attribute, list):
            if node_cmap is None:
                node_cmap = ['red', 'red']
            add_node_colorbar = False

        if node_cmap is None:
            node_cmap = plt.get_cmap('Spectral_r')
        elif isinstance(node_cmap, list):
            if len(node_cmap) == 1:
                node_cmap = node_cmap * 2
            node_cmap = custom_colormap(len(node_cmap), node_cmap)

        node_attribute = _format_node_attribute(node_attribute, wn)
        nodelist, nodecolor = zip(*node_attribute.items())

    else:
        nodelist = None
        nodecolor = 'k'

    add_link_colorbar = add_colorbar
    if link_attribute is not None:

        if isinstance(link_attribute, list):
            if link_cmap is None:
                link_cmap = ['red', 'red']
            add_link_colorbar = False

        if link_cmap is None:
            link_cmap = plt.get_cmap('Spectral_r')
        elif isinstance(link_cmap, list):
            if len(link_cmap) == 1:
                link_cmap = link_cmap * 2
            link_cmap = custom_colormap(len(link_cmap), link_cmap)

        link_attribute = _format_link_attribute(link_attribute, wn)

        # Replace link_attribute dictionary defined as
        # {link_name: attr} with {(start_node, end_node, link_name): attr}
        attr = {}
        for link_name, value in link_attribute.items():
            link = wn.get_link(link_name)
            attr[(link.start_node_name, link.end_node_name, link_name)] = value
        link_attribute = attr

        linklist, linkcolor = zip(*link_attribute.items())
    else:
        linklist = None
        linkcolor = 'k'

    if title is not None:
        ax.set_title(title)

    edge_background = nx.draw_networkx_edges(G,
                                             pos,
                                             edge_color='grey',
                                             width=0.5,
                                             ax=ax)

    nodes = nx.draw_networkx_nodes(G,
                                   pos,
                                   nodelist=nodelist,
                                   node_color=nodecolor,
                                   node_size=node_size,
                                   alpha=node_alpha,
                                   cmap=node_cmap,
                                   vmin=node_range[0],
                                   vmax=node_range[1],
                                   linewidths=0,
                                   ax=ax)
    edges = nx.draw_networkx_edges(G,
                                   pos,
                                   edgelist=linklist,
                                   edge_color=linkcolor,
                                   width=link_width,
                                   alpha=link_alpha,
                                   edge_cmap=link_cmap,
                                   edge_vmin=link_range[0],
                                   edge_vmax=link_range[1],
                                   ax=ax)
    if node_labels:
        labels = dict(zip(wn.node_name_list, wn.node_name_list))
        nx.draw_networkx_labels(G, pos, labels, font_size=7, ax=ax)
    if link_labels:
        labels = {}
        for link_name in wn.link_name_list:
            link = wn.get_link(link_name)
            labels[(link.start_node_name, link.end_node_name)] = link_name
        nx.draw_networkx_edge_labels(G, pos, labels, font_size=7, ax=ax)
    if add_node_colorbar and node_attribute:
        clb = plt.colorbar(nodes, shrink=0.5, pad=0, ax=ax)
        clb.ax.set_title(node_colorbar_label, fontsize=10)
    if add_link_colorbar and link_attribute:
        if directed:
            vmin = min(map(abs, link_attribute.values()))
            vmax = max(map(abs, link_attribute.values()))
            sm = plt.cm.ScalarMappable(cmap=link_cmap,
                                       norm=plt.Normalize(vmin=vmin,
                                                          vmax=vmax))
            sm.set_array([])
            clb = plt.colorbar(sm, shrink=0.5, pad=0.05, ax=ax)
        else:
            clb = plt.colorbar(edges, shrink=0.5, pad=0.05, ax=ax)
        clb.ax.set_title(link_colorbar_label, fontsize=10)

    ax.axis('off')

    if filename:
        plt.savefig(filename)

    return ax
Beispiel #2
0
def plot_network(wn,
                 node_attribute=None,
                 link_attribute=None,
                 title=None,
                 node_size=20,
                 node_range=[None, None],
                 node_cmap=None,
                 node_labels=False,
                 link_width=1,
                 link_range=[None, None],
                 link_cmap=None,
                 link_labels=False,
                 add_colorbar=True,
                 directed=False,
                 ax=None):
    """
    Plot network graphic using networkx. 

    Parameters
    ----------
    wn : wntr WaterNetworkModel
        A WaterNetworkModel object

    node_attribute : str, list, pd.Series, or dict, optional
        (default = None)

        - If node_attribute is a string, then a node attribute dictionary is
          created using node_attribute = wn.query_node_attribute(str)
        - If node_attribute is a list, then each node in the list is given a 
          value of 1.
        - If node_attribute is a pd.Series, then it should be in the format
          {(nodeid,time): x} or {nodeid: x} where nodeid is a string and x is 
          a float. The time index is not used in the plot.
        - If node_attribute is a dict, then it should be in the format
          {nodeid: x} where nodeid is a string and x is a float

    link_attribute : str, list, pd.Series, or dict, optional
        (default = None)

        - If link_attribute is a string, then a link attribute dictionary is
          created using edge_attribute = wn.query_link_attribute(str)
        - If link_attribute is a list, then each link in the list is given a 
          value of 1.
        - If link_attribute is a pd.Series, then it should be in the format
          {(linkid,time): x} or {linkid: x} where linkid is a string and x is 
          a float. The time index is not used in the plot.
        - If link_attribute is a dict, then it should be in the format
          {linkid: x} where linkid is a string and x is a float.

    title : str, optional
        Plot title (default = None)

    node_size : int, optional
        Node size (default = 10)

    node_range : list, optional
        Node range (default = [None,None], autoscale)

    node_cmap : matplotlib.pyplot.cm colormap, optional
        Node colormap (default = jet)
        
    node_labels: bool, optional
        If True, the graph will include each node labelled with its name. 
        (default = False)
        
    link_width : int, optional
        Link width (default = 1)

    link_range : list, optional
        Link range (default = [None,None], autoscale)

    link_cmap : matplotlib.pyplot.cm colormap, optional
        Link colormap (default = jet)
        
    link_labels: bool, optional
        If True, the graph will include each link labelled with its name. 
        (default = False)
        
    add_colorbar : bool, optional
        Add colorbar (default = True)

    directed : bool, optional
        If True, plot the directed graph (default = False, converts the graph 
        to undirected)
    
    ax : matplotlib axes object, optional
        Axes for plotting (default = None, creates a new figure with a single 
        axes)
        
    Returns
    -------
    nodes, edges

    Notes
    -----
    For more network draw options, see nx.draw_networkx
    """

    if plt is None:
        raise ImportError('matplotlib is required')

    if node_cmap is None:
        node_cmap = plt.cm.Spectral_r
    if link_cmap is None:
        link_cmap = plt.cm.Spectral_r
    if ax is None:  # create a new figure
        plt.figure(facecolor='w', edgecolor='k')
        ax = plt.gca()

    # Graph
    G = wn.get_graph()
    if not directed:
        G = G.to_undirected()

    # Position
    pos = nx.get_node_attributes(G, 'pos')
    if len(pos) == 0:
        pos = None

    # Node attribute
    node_attr_from_list = False
    if isinstance(node_attribute, str):
        node_attribute = wn.query_node_attribute(node_attribute)
    if isinstance(node_attribute, list):
        node_attribute = dict(zip(node_attribute, [1] * len(node_attribute)))
        node_attr_from_list = True
    if isinstance(node_attribute, pd.Series):
        if node_attribute.index.nlevels == 2:  # (nodeid, time) index
            # drop time
            node_attribute.reset_index(level=1, drop=True, inplace=True)
        node_attribute = dict(node_attribute)

    # Define node list, color, and colormap
    if node_attribute is None:
        nodelist = None
        nodecolor = 'k'
    else:
        nodelist, nodecolor = zip(*node_attribute.items())
        if node_attr_from_list:
            nodecolor = 'r'
            add_colorbar = False

    # Link attribute
    link_attr_from_list = False
    if isinstance(link_attribute, str):
        link_attribute = wn.query_link_attribute(link_attribute)
    if isinstance(link_attribute, list):
        all_link_attribute = dict(
            zip(wn.link_name_list, [0] * len(wn.link_name_list)))
        for link in link_attribute:
            all_link_attribute[link] = 1
        link_attribute = all_link_attribute
        link_attr_from_list = True
    if isinstance(link_attribute, pd.Series):
        if link_attribute.index.nlevels == 2:  # (linkid, time) index
            # drop time
            link_attribute.reset_index(level=1, drop=True, inplace=True)
        link_attribute = dict(link_attribute)

    # Replace link_attribute dictionary defined as
    # {link_name: attr} with {(start_node, end_node, link_name): attr}
    if link_attribute is not None:
        attr = {}
        for link_name, value in link_attribute.items():
            link = wn.get_link(link_name)
            attr[(link.start_node_name, link.end_node_name, link_name)] = value
        link_attribute = attr
    if type(link_width) is dict:
        attr = {}
        for link_name, value in link_width.items():
            link = wn.get_link(link_name)
            attr[(link.start_node_name, link.end_node_name, link_name)] = value
        link_width = attr

    # Define link list, color, and colormap
    if link_attribute is None:
        linklist = None
        linkcolor = 'k'
    else:
        linklist, linkcolor = zip(*link_attribute.items())
        if link_attr_from_list:
            link_cmap = custom_colormap(2, ['black', 'red'])
            add_colorbar = False

    if type(link_width) is dict:
        linklist2, link_width = zip(*link_width.items())
        if not linklist == linklist2:
            logger.warning('Link color and width do not share the same \
                           indexes, link width changed to 1.')
            link_width = 1

    if title is not None:
        ax.set_title(title)

    nodes = nx.draw_networkx_nodes(G,
                                   pos,
                                   with_labels=False,
                                   nodelist=nodelist,
                                   node_color=nodecolor,
                                   node_size=node_size,
                                   cmap=node_cmap,
                                   vmin=node_range[0],
                                   vmax=node_range[1],
                                   linewidths=0,
                                   ax=ax)
    edges = nx.draw_networkx_edges(G,
                                   pos,
                                   edgelist=linklist,
                                   edge_color=linkcolor,
                                   width=link_width,
                                   edge_cmap=link_cmap,
                                   edge_vmin=link_range[0],
                                   edge_vmax=link_range[1],
                                   ax=ax)
    if node_labels:
        labels = dict(zip(wn.node_name_list, wn.node_name_list))
        nx.draw_networkx_labels(G, pos, labels, font_size=7, ax=ax)
    if link_labels:
        labels = {}
        for link_name in wn.link_name_list:
            link = wn.get_link(link_name)
            labels[(link.start_node_name, link.end_node_name)] = link_name
        nx.draw_networkx_edge_labels(G, pos, labels, font_size=7, ax=ax)
    if add_colorbar and node_attribute:
        plt.colorbar(nodes, shrink=0.5, pad=0, ax=ax)
    if add_colorbar and link_attribute:
        plt.colorbar(edges, shrink=0.5, pad=0.05, ax=ax)
    ax.axis('off')

    return nodes, edges
Beispiel #3
0
def plot_network(wn,
                 node_attribute=None,
                 link_attribute=None,
                 title=None,
                 node_size=20,
                 node_range=[None, None],
                 node_cmap=None,
                 node_labels=False,
                 link_width=1,
                 link_range=[None, None],
                 link_cmap=None,
                 link_labels=False,
                 add_colorbar=True,
                 directed=False,
                 ax=None):
    """
    Plot network graphic

    Parameters
    ----------
    wn : wntr WaterNetworkModel
        A WaterNetworkModel object

    node_attribute : None, str, list, pd.Series, or dict, optional

        - If node_attribute is a string, then a node attribute dictionary is
          created using node_attribute = wn.query_node_attribute(str)
        - If node_attribute is a list, then each node in the list is given a 
          value of 1.
        - If node_attribute is a pd.Series, then it should be in the format
          {nodeid: x} where nodeid is a string and x is a float. 
        - If node_attribute is a dict, then it should be in the format
          {nodeid: x} where nodeid is a string and x is a float

    link_attribute : None, str, list, pd.Series, or dict, optional

        - If link_attribute is a string, then a link attribute dictionary is
          created using edge_attribute = wn.query_link_attribute(str)
        - If link_attribute is a list, then each link in the list is given a 
          value of 1.
        - If link_attribute is a pd.Series, then it should be in the format
          {linkid: x} where linkid is a string and x is a float. 
        - If link_attribute is a dict, then it should be in the format
          {linkid: x} where linkid is a string and x is a float.

    title : str, optional
        Plot title 

    node_size : int, optional
        Node size 

    node_range : list, optional
        Node range ([None,None] indicates autoscale)

    node_cmap : matplotlib.pyplot.cm colormap, optional
        Node colormap 
        
    node_labels: bool, optional
        If True, the graph will include each node labelled with its name. 
        
    link_width : int, optional
        Link width

    link_range : list, optional
        Link range ([None,None] indicates autoscale)

    link_cmap : matplotlib.pyplot.cm colormap, optional
        Link colormap
        
    link_labels: bool, optional
        If True, the graph will include each link labelled with its name. 
        
    add_colorbar : bool, optional
        Add colorbar

    directed : bool, optional
        If True, plot the directed graph
    
    ax : matplotlib axes object, optional
        Axes for plotting (None indicates that a new figure with a single 
        axes will be used)
        
    Returns
    -------
    nodes, edges

    Notes
    -----
    For more network draw options, see nx.draw_networkx
    """

    if plt is None:
        raise ImportError('matplotlib is required')

    if node_cmap is None:
        node_cmap = plt.cm.Spectral_r
    if link_cmap is None:
        link_cmap = plt.cm.Spectral_r
    if ax is None:  # create a new figure
        plt.figure(facecolor='w', edgecolor='k')
        ax = plt.gca()

    # Graph
    G = wn.get_graph()
    if not directed:
        G = G.to_undirected()

    # Position
    pos = nx.get_node_attributes(G, 'pos')
    if len(pos) == 0:
        pos = None

    # Define node properties
    if node_attribute is not None:
        node_attribute_from_list = False
        if isinstance(node_attribute, list):
            node_attribute_from_list = True
            add_colorbar = False
        node_attribute = _format_node_attribute(node_attribute, wn)
        nodelist, nodecolor = zip(*node_attribute.items())
        if node_attribute_from_list:
            nodecolor = 'r'
    else:
        nodelist = None
        nodecolor = 'k'

    if link_attribute is not None:
        if isinstance(link_attribute, list):
            link_cmap = custom_colormap(2, ['red', 'black'])
            add_colorbar = False
        link_attribute = _format_link_attribute(link_attribute, wn)

        # Replace link_attribute dictionary defined as
        # {link_name: attr} with {(start_node, end_node, link_name): attr}
        attr = {}
        for link_name, value in link_attribute.items():
            link = wn.get_link(link_name)
            attr[(link.start_node_name, link.end_node_name, link_name)] = value
        link_attribute = attr

        linklist, linkcolor = zip(*link_attribute.items())
    else:
        linklist = None
        linkcolor = 'k'

    if title is not None:
        ax.set_title(title)

    edge_background = nx.draw_networkx_edges(G,
                                             pos,
                                             edge_color='grey',
                                             width=0.5,
                                             ax=ax)

    nodes = nx.draw_networkx_nodes(G,
                                   pos,
                                   with_labels=False,
                                   nodelist=nodelist,
                                   node_color=nodecolor,
                                   node_size=node_size,
                                   cmap=node_cmap,
                                   vmin=node_range[0],
                                   vmax=node_range[1],
                                   linewidths=0,
                                   ax=ax)
    edges = nx.draw_networkx_edges(G,
                                   pos,
                                   edgelist=linklist,
                                   edge_color=linkcolor,
                                   width=link_width,
                                   edge_cmap=link_cmap,
                                   edge_vmin=link_range[0],
                                   edge_vmax=link_range[1],
                                   ax=ax)
    if node_labels:
        labels = dict(zip(wn.node_name_list, wn.node_name_list))
        nx.draw_networkx_labels(G, pos, labels, font_size=7, ax=ax)
    if link_labels:
        labels = {}
        for link_name in wn.link_name_list:
            link = wn.get_link(link_name)
            labels[(link.start_node_name, link.end_node_name)] = link_name
        nx.draw_networkx_edge_labels(G, pos, labels, font_size=7, ax=ax)
    if add_colorbar and node_attribute:
        plt.colorbar(nodes, shrink=0.5, pad=0, ax=ax)
    if add_colorbar and link_attribute:
        plt.colorbar(edges, shrink=0.5, pad=0.05, ax=ax)
    ax.axis('off')

    return nodes, edges
Beispiel #4
0
def plot_network(wn, node_attribute=None, link_attribute=None, title=None,
               node_size=20, node_range=[None,None], node_alpha=1, node_cmap=None, node_labels=False,
               link_width=1, link_range=[None,None], link_alpha=1, link_cmap=None, link_labels=False,
               valve_layer=None, add_colorbar=True, node_colorbar_label='Node', link_colorbar_label='Link', 
               directed=False, ax=None, filename=None):
    """
    Plot network graphic

    Parameters
    ----------
    wn : wntr WaterNetworkModel
        A WaterNetworkModel object

    node_attribute : None, str, list, pd.Series, or dict, optional

        - If node_attribute is a string, then a node attribute dictionary is
          created using node_attribute = wn.query_node_attribute(str)
        - If node_attribute is a list, then each node in the list is given a 
          value of 1.
        - If node_attribute is a pd.Series, then it should be in the format
          {nodeid: x} where nodeid is a string and x is a float. 
        - If node_attribute is a dict, then it should be in the format
          {nodeid: x} where nodeid is a string and x is a float

    link_attribute : None, str, list, pd.Series, or dict, optional

        - If link_attribute is a string, then a link attribute dictionary is
          created using edge_attribute = wn.query_link_attribute(str)
        - If link_attribute is a list, then each link in the list is given a 
          value of 1.
        - If link_attribute is a pd.Series, then it should be in the format
          {linkid: x} where linkid is a string and x is a float. 
        - If link_attribute is a dict, then it should be in the format
          {linkid: x} where linkid is a string and x is a float.

    title : str, optional
        Plot title 

    node_size : int, optional
        Node size 

    node_range : list, optional
        Node range ([None,None] indicates autoscale)
        
    node_alpha : int, optional
        Node transparency
        
    node_cmap : matplotlib.pyplot.cm colormap or list of named colors, optional
        Node colormap 
        
    node_labels: bool, optional
        If True, the graph will include each node labelled with its name. 
        
    link_width : int, optional
        Link width

    link_range : list, optional
        Link range ([None,None] indicates autoscale)

    link_alpha : int, optional
        Link transparency
    
    link_cmap : matplotlib.pyplot.cm colormap or list of named colors, optional
        Link colormap
        
    link_labels: bool, optional
        If True, the graph will include each link labelled with its name. 
        
    add_colorbar : bool, optional
        Add colorbar

    node_colorbar_label: str, optional
        Node colorbar label
        
    link_colorbar_label: str, optional
        Link colorbar label
        
    directed : bool, optional
        If True, plot the directed graph
    
    ax : matplotlib axes object, optional
        Axes for plotting (None indicates that a new figure with a single 
        axes will be used)
        
    Returns
    -------
    nodes, edges : matplotlib objects for network nodes and edges

    Notes
    -----
    For more network draw options, see nx.draw_networkx
    """
    
    if plt is None:
        raise ImportError('matplotlib is required')

    if ax is None: # create a new figure
        plt.figure(facecolor='w', edgecolor='k')
        ax = plt.gca()
        
    # Graph
    G = wn.get_graph()
    if not directed:
        G = G.to_undirected()

    # Position
    pos = nx.get_node_attributes(G,'pos')
    if len(pos) == 0:
        pos = None

    # Define node properties
    add_node_colorbar = add_colorbar
    if node_attribute is not None:
        
        if isinstance(node_attribute, list):
            if node_cmap is None:
                node_cmap = ['red', 'red']
            add_node_colorbar = False
        
        if node_cmap is None:
            node_cmap = plt.cm.Spectral_r
        elif isinstance(node_cmap, list):
            if len(node_cmap) == 1:
                node_cmap = node_cmap*2
            node_cmap = custom_colormap(len(node_cmap), node_cmap)  
         
        node_attribute = _format_node_attribute(node_attribute, wn)
        nodelist,nodecolor = zip(*node_attribute.items())

    else:
        nodelist = None
        nodecolor = 'k'
    
    add_link_colorbar = add_colorbar
    if link_attribute is not None:
        
        if isinstance(link_attribute, list):
            if link_cmap is None:
                link_cmap = ['red', 'red']
            add_link_colorbar = False

        if link_cmap is None:
            link_cmap = plt.cm.Spectral_r
        elif isinstance(link_cmap, list):
            if len(link_cmap) == 1:
                link_cmap = link_cmap*2
            link_cmap = custom_colormap(len(link_cmap), link_cmap)  
            
        link_attribute = _format_link_attribute(link_attribute, wn)
        
        # Replace link_attribute dictionary defined as
        # {link_name: attr} with {(start_node, end_node, link_name): attr}
        attr = {}
        for link_name, value in link_attribute.items():
            link = wn.get_link(link_name)
            attr[(link.start_node_name, link.end_node_name, link_name)] = value
        link_attribute = attr
        
        linklist,linkcolor = zip(*link_attribute.items())
    else:
        linklist = None
        linkcolor = 'k'
    
    if title is not None:
        ax.set_title(title)
        
    edge_background = nx.draw_networkx_edges(G, pos, edge_color='grey', 
                                             width=0.5, ax=ax)
    
    nodes = nx.draw_networkx_nodes(G, pos, with_labels=False, 
            nodelist=nodelist, node_color=nodecolor, node_size=node_size, 
            alpha=node_alpha, cmap=node_cmap, vmin=node_range[0], vmax = node_range[1], 
            linewidths=0, ax=ax)
    edges = nx.draw_networkx_edges(G, pos, edgelist=linklist, 
            edge_color=linkcolor, width=link_width, alpha=link_alpha, edge_cmap=link_cmap, 
            edge_vmin=link_range[0], edge_vmax=link_range[1], ax=ax)
    if node_labels:
        labels = dict(zip(wn.node_name_list, wn.node_name_list))
        nx.draw_networkx_labels(G, pos, labels, font_size=7, ax=ax)
    if link_labels:
        labels = {}
        for link_name in wn.link_name_list:
            link = wn.get_link(link_name)
            labels[(link.start_node_name, link.end_node_name)] = link_name
        nx.draw_networkx_edge_labels(G, pos, labels, font_size=7, ax=ax)
    if add_node_colorbar and node_attribute:
        clb = plt.colorbar(nodes, shrink=0.5, pad=0, ax=ax)
        clb.ax.set_title(node_colorbar_label, fontsize=10)
    if add_link_colorbar and link_attribute:
        clb = plt.colorbar(edges, shrink=0.5, pad=0.05, ax=ax)
        clb.ax.set_title(link_colorbar_label, fontsize=10)
    ax.axis('off')
    
    if valve_layer is not None:
        for valve_name, (pipe_name, node_name) in valve_layer.iterrows():
            pipe = wn.get_link(pipe_name)
            if node_name == pipe.start_node_name:
                start_node = pipe.start_node
                end_node = pipe.end_node
            elif node_name == pipe.end_node_name:
                start_node = pipe.end_node
                end_node = pipe.start_node
            else:
                print("Not valid")
                continue
            x0 = start_node.coordinates[0]
            dx = end_node.coordinates[0] - x0
            y0 = start_node.coordinates[1]
            dy = end_node.coordinates[1] - y0
            valve_coordinates = (x0 + dx * 0.1,
                                     y0 + dy * 0.1)
            ax.scatter(valve_coordinates[0], valve_coordinates[1], 15, 'r', 'v')   
     
    if filename:
        plt.savefig(filename)
        
    return nodes, edges
Beispiel #5
0
def plot_network(wn,
                 node_attribute=None,
                 link_attribute=None,
                 title=None,
                 node_size=20,
                 node_range=[None, None],
                 node_alpha=1,
                 node_cmap=None,
                 node_labels=False,
                 link_width=1,
                 link_range=[None, None],
                 link_alpha=1,
                 link_cmap=None,
                 link_labels=False,
                 valve_layer=None,
                 add_colorbar=True,
                 node_colorbar_label='Node',
                 link_colorbar_label='Link',
                 directed=False,
                 ax=None,
                 filename=None,
                 plot_center=None,
                 plot_limits=None):
    """
    Plot network graphic

    Parameters
    ----------
    wn : wntr WaterNetworkModel
        A WaterNetworkModel object

    node_attribute : None, str, list, pd.Series, or dict, optional

        - If node_attribute is a string, then a node attribute dictionary is
          created using node_attribute = wn.query_node_attribute(str)
        - If node_attribute is a list, then each node in the list is given a 
          value of 1.
        - If node_attribute is a pd.Series, then it should be in the format
          {nodeid: x} where nodeid is a string and x is a float. 
        - If node_attribute is a dict, then it should be in the format
          {nodeid: x} where nodeid is a string and x is a float

    link_attribute : None, str, list, pd.Series, or dict, optional

        - If link_attribute is a string, then a link attribute dictionary is
          created using edge_attribute = wn.query_link_attribute(str)
        - If link_attribute is a list, then each link in the list is given a 
          value of 1.
        - If link_attribute is a pd.Series, then it should be in the format
          {linkid: x} where linkid is a string and x is a float. 
        - If link_attribute is a dict, then it should be in the format
          {linkid: x} where linkid is a string and x is a float.

    title : str, optional
        Plot title 

    node_size : int, optional
        Node size 

    node_range : list, optional
        Node range ([None,None] indicates autoscale)
        
    node_alpha : int, optional
        Node transparency
        
    node_cmap : matplotlib.pyplot.cm colormap or list of named colors, optional
        Node colormap 
        
    node_labels: bool, list optional
        If True, the graph will include each node labelled with its name. 
        If list, the graph will include only node labels in the list
        
    link_width : int, optional
        Link width

    link_range : list, optional
        Link range ([None,None] indicates autoscale)

    link_alpha : int, optional
        Link transparency
    
    link_cmap : matplotlib.pyplot.cm colormap or list of named colors, optional
        Link colormap
        
    link_labels: bool, list optional
        If True, the graph will include each link labelled with its name.
        If list, the graph will only include link labels in the list.
        
    add_colorbar : bool, optional
        Add colorbar

    node_colorbar_label: str, optional
        Node colorbar label
        
    link_colorbar_label: str, optional
        Link colorbar label
        
    directed : bool, optional
        If True, plot the directed graph
    
    ax : matplotlib axes object, optional
        Axes for plotting (None indicates that a new figure with a single 
        axes will be used)
        
    filename : str, optional
        Path and file name to a grahpics output png file of the axes plotted
        by this function (None indicates to not output a file).
        
    plot_center : str or 2-list/tuple, optional 
        str = name of link/node in the wn water network to center the plot about
        2-list/tuple = x-y coordinates 
        Either of these recenter the plot and change the viewed window.
        If a link and node share the same name, then the node will be the center.
                  
    plot_limits  : float, 2-list/tuple - window (horiz,vert) about plot_center  
        
    Returns
    -------
    nodes, edges : matplotlib objects for network nodes and edges

    Notes
    -----
    For more network draw options, see nx.draw_networkx
    """

    if ax is None:  # create a new figure
        plt.figure(facecolor='w', edgecolor='k')
        ax = plt.gca()

    # Graph
    G = wn.get_graph()
    if not directed:
        G = G.to_undirected()

    # Position
    pos = nx.get_node_attributes(G, 'pos')
    if len(pos) == 0:
        pos = None

    # Define node properties
    add_node_colorbar = add_colorbar
    if node_attribute is not None:

        if isinstance(node_attribute, list):
            if node_cmap is None:
                node_cmap = ['red', 'red']
            add_node_colorbar = False

        if node_cmap is None:
            node_cmap = plt.cm.Spectral_r
        elif isinstance(node_cmap, list):
            if len(node_cmap) == 1:
                node_cmap = node_cmap * 2
            node_cmap = custom_colormap(len(node_cmap), node_cmap)

        node_attribute = _format_node_attribute(node_attribute, wn)
        nodelist, nodecolor = zip(*node_attribute.items())

    else:
        nodelist = None
        nodecolor = 'k'

    add_link_colorbar = add_colorbar
    if link_attribute is not None:

        if isinstance(link_attribute, list):
            if link_cmap is None:
                link_cmap = ['red', 'red']
            add_link_colorbar = False

        if link_cmap is None:
            link_cmap = plt.cm.Spectral_r
        elif isinstance(link_cmap, list):
            if len(link_cmap) == 1:
                link_cmap = link_cmap * 2
            link_cmap = custom_colormap(len(link_cmap), link_cmap)

        link_attribute = _format_link_attribute(link_attribute, wn)

        # Replace link_attribute dictionary defined as
        # {link_name: attr} with {(start_node, end_node, link_name): attr}
        attr = {}
        for link_name, value in link_attribute.items():
            link = wn.get_link(link_name)
            attr[(link.start_node_name, link.end_node_name, link_name)] = value
        link_attribute = attr

        linklist, linkcolor = zip(*link_attribute.items())
    else:
        linklist = None
        linkcolor = 'k'

    if title is not None:
        ax.set_title(title)

    edge_background = nx.draw_networkx_edges(G,
                                             pos,
                                             edge_color='grey',
                                             width=0.5,
                                             ax=ax)

    nodes = nx.draw_networkx_nodes(G,
                                   pos,
                                   nodelist=nodelist,
                                   node_color=nodecolor,
                                   node_size=node_size,
                                   alpha=node_alpha,
                                   cmap=node_cmap,
                                   vmin=node_range[0],
                                   vmax=node_range[1],
                                   linewidths=0,
                                   ax=ax)
    edges = nx.draw_networkx_edges(G,
                                   pos,
                                   edgelist=linklist,
                                   edge_color=linkcolor,
                                   width=link_width,
                                   alpha=link_alpha,
                                   edge_cmap=link_cmap,
                                   edge_vmin=link_range[0],
                                   edge_vmax=link_range[1],
                                   ax=ax)
    if node_labels:
        if isinstance(node_labels, (list, tuple)):
            labels = dict(zip(node_labels, node_labels))
        else:
            labels = dict(zip(wn.node_name_list, wn.node_name_list))
        nx.draw_networkx_labels(G, pos, labels, font_size=7, ax=ax)
    if link_labels:
        if isinstance(link_labels, (list, tuple)):
            links = [wn.get_link(name) for name in link_labels]
            labels = dict(
                zip([(link.start_node_name, link.end_node_name)
                     for link in links],
                    [linkname for linkname in link_labels]))
        else:
            links = [wn.get_link(name) for name in wn.links]
            labels = dict(
                zip([(link.start_node_name, link.end_node_name)
                     for link in links], [name for name in wn.links]))


#        for link_name in wn.link_name_list:
#            link = wn.get_link(link_name)
#            labels[(link.start_node_name, link.end_node_name)] = link_name
        nx.draw_networkx_edge_labels(G, pos, labels, font_size=7, ax=ax)
    if add_node_colorbar and node_attribute:
        clb = plt.colorbar(nodes, shrink=0.5, pad=0, ax=ax)
        clb.ax.set_title(node_colorbar_label, fontsize=10)
    if add_link_colorbar and link_attribute:
        clb = plt.colorbar(edges, shrink=0.5, pad=0.05, ax=ax)
        clb.ax.set_title(link_colorbar_label, fontsize=10)
    ax.axis('off')

    if valve_layer is not None:
        for valve_name, (pipe_name, node_name) in valve_layer.iterrows():
            pipe = wn.get_link(pipe_name)
            if node_name == pipe.start_node_name:
                start_node = pipe.start_node
                end_node = pipe.end_node
            elif node_name == pipe.end_node_name:
                start_node = pipe.end_node
                end_node = pipe.start_node
            else:
                print("Not valid")
                continue
            x0 = start_node.coordinates[0]
            dx = end_node.coordinates[0] - x0
            y0 = start_node.coordinates[1]
            dy = end_node.coordinates[1] - y0
            valve_coordinates = (x0 + dx * 0.1, y0 + dy * 0.1)
            ax.scatter(valve_coordinates[0], valve_coordinates[1], 15, 'r',
                       'v')

    # provide a way to focus in on a single node/link or coordinate and to
    # zoom in
    if plot_center:
        # derive the length of x and y on the screen.
        incorrect_input_string = ("The '{0}' input must be a list or" +
                                  " tuple of length 2{1}")
        plot_center_string1 = (", a node name or a link" +
                               " name in the input water network model!")
        if not plot_limits:
            xlim = ax.get_xlim()
            len_x = xlim[1] - xlim[0]
            ylim = ax.get_ylim()
            len_y = ylim[1] - ylim[0]
        else:
            if isinstance(plot_limits, (list, tuple)):
                if len(plot_limits) == 1:
                    len_x = plot_limits[0]
                    len_y = plot_limits[1]
                elif len(plot_limits) == 2:
                    len_x = plot_limits[0]
                    len_y = plot_limits[1]
                else:
                    raise ValueError(
                        incorrect_input_string.format("plot_limits",
                                                      ", or a float."))
            elif isinstance(plot_limits, float):
                len_x = plot_limits
                len_y = plot_limits
            else:
                raise ValueError(
                    incorrect_input_string.format("plot_limits",
                                                  ", or a float."))

        if isinstance(plot_center, (list, tuple)):
            if len(plot_center) == 2:
                center = plot_center
            else:
                raise ValueError(
                    incorrect_input_string.format("plot_center",
                                                  plot_center_string1))
        else:
            if plot_center in wn.node_name_list:
                center_node = wn.get_node(plot_center)
                center = center_node.coordinates
            elif plot_center in wn.link_name_list:
                center_link = wn.get_link(plot_center)
                start_coord = center_link.start_node.coordinates
                end_coord = center_link.end_node.coordinates
                center = [(start_coord[0] + end_coord[0]) / 2.0,
                          (start_coord[1] + end_coord[1]) / 2.0]
            else:
                raise ValueError(
                    incorrect_input_string.format("plot_center",
                                                  plot_center_string1))

        ax.set_xlim((center[0] - len_x / 2, center[0] + len_x / 2))
        ax.set_ylim((center[1] - len_y / 2, center[1] + len_y / 2))

    else:
        if plot_limits:
            raise ValueError("The plot_limits input must be used in" +
                             " coordination with the plot_center input!")
    # end of plot_center code.

    if filename:
        plt.savefig(filename)

    return nodes, edges