Skip to content

Commit

Permalink
fix sankey diagrams
Browse files Browse the repository at this point in the history
  • Loading branch information
bqpd committed Aug 7, 2020
1 parent fe9c591 commit b123856
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 188 deletions.
6 changes: 6 additions & 0 deletions docs/source/examples/performance_modeling.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,3 +255,9 @@ def setup(self):
M.append(MISSION.fs.aircraftp.Wburn >= 0.2*MISSION.fs.aircraftp.wing_aero.D)
sol = M.solve(verbosity=0)
print(sol.diff("solution.pkl", showvars=vars_of_interest, sortbymodel=False))

# this will only make an image when run in jupyter notebook
from gpkit.interactive.sankey import Sankey
sankey = Sankey(sol, M).diagram(left=40, width=950, right=150)
sankey.auto_save_svg("performance_modeling.svg")
sankey
7 changes: 6 additions & 1 deletion docs/source/modelbuilding.rst
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,13 @@ In the example below, the models ``Aircraft`` and ``Wing`` have a ``.dynamic()``

This means that when an aircraft is being optimized for a mission, you can create the aircraft (``AC`` in this example) and then pass it to a ``Mission`` model which can create vectorized aircraft performance models for each flight segment and/or flight condition.

The :ref:`sensitivity diagram <sankey>` which this code outputs shows how it is organized:

.. figure:: figures/sankey/performance_modeling.svg
:width: 700 px

.. literalinclude:: examples/performance_modeling.py

Note that the output table can be filtered with a list of variables to show.
Note that the output table has been filtered above to show only variables of interest.

.. literalinclude:: examples/performance_modeling_output.txt
28 changes: 6 additions & 22 deletions docs/source/visint.rst
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
Visualization and Interaction
*****************************

Sankey Diagrams
===============
.. _sankey:
Sensitivity Diagrams
====================

Requirements
------------
Expand Down Expand Up @@ -31,13 +32,13 @@ Code in this section uses the `CE solar model <https://github.com/convexengineer
::

(objective) adds +1 to the sensitivity of Wtotal_Aircraft
(objective) is Wtotal_Aircraft [lbf]
(objective) is Wtotal_Aircraft [lbf]

Ⓐ adds +0.0075 to the overall sensitivity of Wtotal_Aircraft
Ⓐ is Wtotal_Aircraft <= 0.5*CL_Mission/Climb/AircraftDrag/WingAero_(0,)*S_Aircraft/Wing/Planform.2*V_Mission/Climb_(0, 0)**2*rho_Mission/Climb_(0, 0)
Ⓐ is Wtotal_Aircraft <= 0.5*CL_Mission/Climb/AircraftDrag/WingAero_(0,)*S_Aircraft/Wing/Planform.2*V_Mission/Climb_(0, 0)**2*rho_Mission/Climb_(0, 0)

Ⓑ adds +0.0117 to the overall sensitivity of Wtotal_Aircraft
Ⓑ is Wtotal_Aircraft <= 0.5*CL_Mission/Climb/AircraftDrag/WingAero_(1,)*S_Aircraft/Wing/Planform.2*V_Mission/Climb_(0, 1)**2*rho_Mission/Climb_(0, 1)
Ⓑ is Wtotal_Aircraft <= 0.5*CL_Mission/Climb/AircraftDrag/WingAero_(1,)*S_Aircraft/Wing/Planform.2*V_Mission/Climb_(0, 1)**2*rho_Mission/Climb_(0, 1)


Explanation
Expand Down Expand Up @@ -95,23 +96,6 @@ Sankey(M).diagram(M['vgust'])
:width: 700 px


Equivalent Variables
^^^^^^^^^^^^^^^^^^^^

If any variables are equal to the diagram's variable (modulo some
constant factor; e.g. ``2*x == y`` counts for this, as does ``2*x <= y``
if the constraint is sensitive), they are found and plotted
at the same time, and all shown on the left. The constraints responsible
for this are shown next to their labels.

.. code:: python
Sankey(M).sorted_by('constraints', 11)
.. figure:: figures/sankey/solar_tmin.svg
:width: 700 px


Models
~~~~~~

Expand Down
13 changes: 8 additions & 5 deletions gpkit/constraints/costed.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import numpy as np
from .set import ConstraintSet
from ..small_scripts import maybe_flatten
from ..repr_conventions import lineagestr


class CostedConstraintSet(ConstraintSet):
Expand Down Expand Up @@ -33,12 +34,14 @@ def constrained_varkeys(self):

def _rootlines(self, excluded=()):
"String showing cost, to be used when this is the top constraint"
description = ["", "Cost", "----",
" %s" % self.cost.str_without(excluded),
"", "Constraints", "-----------"]
if self.cost.varkeys:
description = ["", "Cost", "----",
" %s" % self.cost.str_without(excluded),
"", "Constraints", "-----------"]
else:
description = ["", "Constraints", "-----------"]
if self.lineage:
name, num = self.lineage[-1] # pylint: disable=unsubscriptable-object
fullname = "%s" % (name if not num else name + str(num))
fullname = lineagestr(self)
description = [fullname, "="*len(fullname)] + description
return description

Expand Down
3 changes: 2 additions & 1 deletion gpkit/constraints/set.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"Implements ConstraintSet"
import sys
from collections import defaultdict, OrderedDict
from itertools import chain
import numpy as np
Expand Down Expand Up @@ -36,7 +37,7 @@ def _sort_constraints(item):

def sort_constraints_dict(iterable):
"Sort a dictionary of {k: constraint} and return its keys and values"
if isinstance(iterable, OrderedDict):
if sys.version_info >= (3, 7) or isinstance(iterable, OrderedDict):
return iterable.keys(), iterable.values()
items = sorted(list(iterable.items()), key=_sort_constraints)
return (item[0] for item in items), (item[1] for item in items)
Expand Down
Loading

0 comments on commit b123856

Please sign in to comment.