| Conditions | 11 |
| Total Lines | 120 |
| Code Lines | 31 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 0 | ||
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like network.graph.create_nx_graph() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
| 1 | # -*- coding: utf-8 -*- |
||
| 18 | def create_nx_graph( |
||
| 19 | energy_system=None, |
||
| 20 | remove_nodes=None, |
||
| 21 | filename=None, |
||
| 22 | remove_nodes_with_substrings=None, |
||
| 23 | remove_edges=None, |
||
| 24 | ): |
||
| 25 | """ |
||
| 26 | Create a `networkx.DiGraph` for the passed energy system and plot it. |
||
| 27 | See http://networkx.readthedocs.io/en/latest/ for more information. |
||
| 28 | |||
| 29 | Parameters |
||
| 30 | ---------- |
||
| 31 | energy_system : `oemof.solph.network.EnergySystem` |
||
| 32 | |||
| 33 | filename : str |
||
| 34 | Absolute filename (with path) to write your graph in the graphml |
||
| 35 | format. If no filename is given no file will be written. |
||
| 36 | |||
| 37 | remove_nodes: list of strings |
||
| 38 | Nodes to be removed e.g. ['node1', node2')] |
||
| 39 | |||
| 40 | remove_nodes_with_substrings: list of strings |
||
| 41 | Nodes that contain substrings to be removed e.g. ['elec', 'heat')] |
||
| 42 | |||
| 43 | remove_edges: list of string tuples |
||
| 44 | Edges to be removed e.g. [('resource_gas', 'gas_balance')] |
||
| 45 | |||
| 46 | Examples |
||
| 47 | -------- |
||
| 48 | >>> import os |
||
| 49 | >>> import pandas as pd |
||
| 50 | >>> from oemof.network.network import Bus, Sink, Transformer |
||
| 51 | >>> from oemof.network.energy_system import EnergySystem |
||
| 52 | >>> import oemof.network.graph as grph |
||
| 53 | >>> datetimeindex = pd.date_range('1/1/2017', periods=3, freq='H') |
||
| 54 | >>> es = EnergySystem(timeindex=datetimeindex) |
||
| 55 | >>> b_gas = Bus(label='b_gas', balanced=False) |
||
| 56 | >>> bel1 = Bus(label='bel1') |
||
| 57 | >>> bel2 = Bus(label='bel2') |
||
| 58 | >>> demand_el = Sink(label='demand_el', inputs = [bel1]) |
||
| 59 | >>> pp_gas = Transformer(label=('pp', 'gas'), |
||
| 60 | ... inputs=[b_gas], |
||
| 61 | ... outputs=[bel1], |
||
| 62 | ... conversion_factors={bel1: 0.5}) |
||
| 63 | >>> line_to2 = Transformer(label='line_to2', inputs=[bel1], outputs=[bel2]) |
||
| 64 | >>> line_from2 = Transformer(label='line_from2', |
||
| 65 | ... inputs=[bel2], outputs=[bel1]) |
||
| 66 | >>> es.add(b_gas, bel1, demand_el, pp_gas, bel2, line_to2, line_from2) |
||
| 67 | >>> my_graph = grph.create_nx_graph(es) |
||
| 68 | >>> # export graph as .graphml for programs like Yed where it can be |
||
| 69 | >>> # sorted and customized. this is especially helpful for large graphs |
||
| 70 | >>> # grph.create_nx_graph(es, filename="my_graph.graphml") |
||
| 71 | >>> [my_graph.has_node(n) |
||
| 72 | ... for n in ['b_gas', 'bel1', "('pp', 'gas')", 'demand_el', 'tester']] |
||
| 73 | [True, True, True, True, False] |
||
| 74 | >>> list(nx.attracting_components(my_graph)) |
||
| 75 | [{'demand_el'}] |
||
| 76 | >>> sorted(list(nx.strongly_connected_components(my_graph))[1]) |
||
| 77 | ['bel1', 'bel2', 'line_from2', 'line_to2'] |
||
| 78 | >>> new_graph = grph.create_nx_graph(energy_system=es, |
||
| 79 | ... remove_nodes_with_substrings=['b_'], |
||
| 80 | ... remove_nodes=["('pp', 'gas')"], |
||
| 81 | ... remove_edges=[('bel2', 'line_from2')], |
||
| 82 | ... filename='test_graph') |
||
| 83 | >>> [new_graph.has_node(n) |
||
| 84 | ... for n in ['b_gas', 'bel1', "('pp', 'gas')", 'demand_el', 'tester']] |
||
| 85 | [False, True, False, True, False] |
||
| 86 | >>> my_graph.has_edge("('pp', 'gas')", 'bel1') |
||
| 87 | True |
||
| 88 | >>> new_graph.has_edge('bel2', 'line_from2') |
||
| 89 | False |
||
| 90 | >>> os.remove('test_graph.graphml') |
||
| 91 | |||
| 92 | Notes |
||
| 93 | ----- |
||
| 94 | Needs graphviz and networkx (>= v.1.11) to work properly. |
||
| 95 | Tested on Ubuntu 16.04 x64 and solydxk (debian 9). |
||
| 96 | """ |
||
| 97 | # construct graph from nodes and flows |
||
| 98 | grph = nx.DiGraph() |
||
| 99 | |||
| 100 | # add nodes |
||
| 101 | for n in energy_system.nodes: |
||
| 102 | grph.add_node(str(n.label), label=str(n.label)) |
||
| 103 | |||
| 104 | # add labeled flows on directed edge if an optimization_model has been |
||
| 105 | # passed or undirected edge otherwise |
||
| 106 | for n in energy_system.nodes: |
||
| 107 | for i in n.inputs.keys(): |
||
| 108 | weight = getattr( |
||
| 109 | energy_system.flows()[(i, n)], "nominal_value", None |
||
| 110 | ) |
||
| 111 | if weight is None: |
||
| 112 | grph.add_edge(str(i.label), str(n.label)) |
||
| 113 | else: |
||
| 114 | grph.add_edge( |
||
| 115 | str(i.label), str(n.label), weigth=format(weight, ".2f") |
||
| 116 | ) |
||
| 117 | |||
| 118 | # remove nodes and edges based on precise labels |
||
| 119 | if remove_nodes is not None: |
||
| 120 | grph.remove_nodes_from(remove_nodes) |
||
| 121 | if remove_edges is not None: |
||
| 122 | grph.remove_edges_from(remove_edges) |
||
| 123 | |||
| 124 | # remove nodes based on substrings |
||
| 125 | if remove_nodes_with_substrings is not None: |
||
| 126 | for i in remove_nodes_with_substrings: |
||
| 127 | remove_nodes = [ |
||
| 128 | str(v.label) for v in energy_system.nodes if i in str(v.label) |
||
| 129 | ] |
||
| 130 | grph.remove_nodes_from(remove_nodes) |
||
| 131 | |||
| 132 | if filename is not None: |
||
| 133 | if filename[-8:] != ".graphml": |
||
| 134 | filename = filename + ".graphml" |
||
| 135 | nx.write_graphml(grph, filename) |
||
| 136 | |||
| 137 | return grph |
||
| 138 |