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 |