-
Notifications
You must be signed in to change notification settings - Fork 40
/
plotting.py
130 lines (109 loc) · 3.82 KB
/
plotting.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
"""Plotting methods"""
from collections import Counter
import plotly.graph_objects as go
import matplotlib.pyplot as plt
import numpy as np
from .plot_sweep import assign_axes
from .. import GPCOLORS
def compare(models, sweeps, posys, tol=0.001):
"""Compares the values of posys over a sweep of several models.
If posys is of the same length as models, this will plot different
variables from different models.
Currently only supports a single sweepvar.
Example Usage:
compare([aec, fbc], {"R": (160, 300)},
["cost", ("W_{\\rm batt}", "W_{\\rm fuel}")], tol=0.001)
"""
sols = [m.autosweep(sweeps, tol, verbosity=0) for m in models]
posys, axes = assign_axes(sols[0].bst.sweptvar, posys, None)
for posy, ax in zip(posys, axes):
for i, sol in enumerate(sols):
if hasattr(posy, "__len__") and len(posy) == len(sols):
p = posy[i]
else:
p = posy
color = GPCOLORS[i % len(GPCOLORS)]
if sol._is_cost(p): # pylint: disable=protected-access
ax.fill_between(sol.sampled_at,
sol.cost_lb(), sol.cost_ub(),
facecolor=color, edgecolor=color,
linewidth=0.75)
else:
ax.plot(sol.sampled_at, sol(p), color=color)
def plot_convergence(model):
"""Plots the convergence of a signomial programming model
Arguments
---------
model: Model
Signomial programming model that has already been solved
Returns
-------
matplotlib.pyplot Figure
Plot of cost as functions of SP iteration #
"""
fig, ax = plt.subplots()
it = np.array([])
cost = np.array([])
for n, gp in enumerate(model.program.gps):
try:
cost = np.append(cost, gp.result['cost'])
it = np.append(it, n+1)
except TypeError:
pass
ax.plot(it, cost, '-o')
ax.set_xlabel('Iteration')
ax.set_ylabel('Cost')
ax.set_xticks(range(1, len(model.program.gps)+1))
return fig, ax
def treemap(model, itemize="variables", sizebycount=False):
"""Plots model structure as Plotly TreeMap
Arguments
---------
model: Model
GPkit model object
itemize (optional): string, either "variables" or "constraints"
Specify whether to iterate over the model varkeys or constraints
sizebycount (optional): bool
Whether to size blocks by number of variables/constraints or use
default sizing
Returns
-------
plotly.graph_objects.Figure
Plot of model hierarchy
"""
modelnames = []
parents = []
sizes = []
if itemize == "variables":
lineagestrs = [l.lineagestr() or "Model" for l in model.varkeys]
elif itemize == "constraints":
lineagestrs = [l.lineagestr() or "Model" for l in model.flat()]
modelcount = Counter(lineagestrs)
for modelname, count in modelcount.items():
modelnames.append(modelname)
if "." in modelname:
parent = modelname.rsplit(".", 1)[0]
elif modelname != "Model":
parent = "Model"
else:
parent = ""
parents.append(parent)
sizes.append(count)
for parent in parents:
if parent not in modelnames:
modelnames.append(parent)
if "." in parent:
grandparent = parent.rsplit(".", 1)[0]
elif parent != "Model":
grandparent = "Model"
else:
grandparent = ""
parents.append(grandparent)
sizes.append(0)
fig = go.Figure(go.Treemap(
ids=modelnames,
labels=[modelname.split(".")[-1] for modelname in modelnames],
parents=parents,
values=sizes if sizebycount else None,
))
return fig