1e81fdcb135d0325e3bc22fae0583555d20aae280Brendan Jackman# Copyright 2016-2017 ARM Limited 2d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock# 3d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock# Licensed under the Apache License, Version 2.0 (the "License"); 4d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock# you may not use this file except in compliance with the License. 5d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock# You may obtain a copy of the License at 6d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock# 7d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock# http://www.apache.org/licenses/LICENSE-2.0 8d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock# 9d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock# Unless required by applicable law or agreed to in writing, software 10d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock# distributed under the License is distributed on an "AS IS" BASIS, 11d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock# See the License for the specific language governing permissions and 13d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock# limitations under the License. 14d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock# 15d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock"""Base matplotlib plotter module""" 16d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocockfrom abc import abstractmethod, ABCMeta 1766d4e90b9b9fa5db544e4154505e97f8db562aa2John Pocockfrom collections import defaultdict as ddict 18d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocockimport matplotlib.pyplot as plt 19d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocockfrom trappy.plotter import AttrConf 20d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocockfrom trappy.plotter.Constraint import ConstraintManager 21d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocockfrom trappy.plotter.PlotLayout import PlotLayout 22d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocockfrom trappy.plotter.AbstractDataPlotter import AbstractDataPlotter 23d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocockfrom trappy.plotter.ColorMap import ColorMap 24d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 25d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 26d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 27d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocockclass StaticPlot(AbstractDataPlotter): 28d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock """ 29d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock This class uses :mod:`trappy.plotter.Constraint.Constraint` to 30d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock represent different permutations of input parameters. These 31d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock constraints are generated by creating an instance of 32d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock :mod:`trappy.plotter.Constraint.ConstraintManager`. 33d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 34b8d89134b5ea7157b5b77f7907f569dff955fa1bJavi Merino :param traces: The input data 354f4b18adce159f73b112ab789d695918ba45ef2fJavi Merino :type traces: a list of :mod:`trappy.trace.FTrace`, 364f4b18adce159f73b112ab789d695918ba45ef2fJavi Merino :mod:`trappy.trace.SysTrace`, :mod:`trappy.trace.BareTrace` 374f4b18adce159f73b112ab789d695918ba45ef2fJavi Merino or :mod:`pandas.DataFrame` or a single instance of them. 38d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 39d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock :param column: specifies the name of the column to 40d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock be plotted. 41d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock :type column: (str, list(str)) 42d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 43d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock :param templates: TRAPpy events 44d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 45d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock .. note:: 46d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 47d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock This is not required if a :mod:`pandas.DataFrame` is 48d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock used 49d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 50d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock :type templates: :mod:`trappy.base.Base` 51d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 52d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock :param filters: Filter the column to be plotted as per the 53d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock specified criteria. For Example: 54d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock :: 55d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 56d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock filters = 57d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock { 58d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock "pid": [ 3338 ], 59d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock "cpu": [0, 2, 4], 60d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock } 61d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock :type filters: dict 62d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 63d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock :param per_line: Used to control the number of graphs 64d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock in each graph subplot row 65d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock :type per_line: int 66d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 67d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock :param concat: Draw all the pivots on a single graph 68d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock :type concat: bool 69d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 70d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock :param permute: Draw one plot for each of the traces specified 71d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock :type permute: bool 72d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 73d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock :param drawstyle: This argument is forwarded to the matplotlib 74d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock corresponding :func:`matplotlib.pyplot.plot` call 75d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 76d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock drawing style. 77d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 78d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock .. note:: 79d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 80d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock step plots are not currently supported for filled 81d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock graphs 82d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 83d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock :param xlim: A tuple representing the upper and lower xlimits 84d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock :type xlim: tuple 85d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 86d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock :param ylim: A tuple representing the upper and lower ylimits 87d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock :type ylim: tuple 88d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 89d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock :param title: A title describing all the generated plots 90d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock :type title: str 91d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 92d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock :param style: Created pre-styled graphs loaded from 93d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock :mod:`trappy.plotter.AttrConf.MPL_STYLE` 94d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock :type style: bool 95d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 96d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock :param signals: A string of the type event_name:column 97d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock to indicate the value that needs to be plotted 98d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 99d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock .. note:: 100d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 101d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock - Only one of `signals` or both `templates` and 102d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock `columns` should be specified 103d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock - Signals format won't work for :mod:`pandas.DataFrame` 104d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock input 105d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 106d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock :type signals: str 107d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 1089b4898aa3ea40f2af85157af65ab491e8aaa9b4cMichele Di Giorgio :param legend_ncol: A positive integer that represents the 1099b4898aa3ea40f2af85157af65ab491e8aaa9b4cMichele Di Giorgio number of columns in the legend 1109b4898aa3ea40f2af85157af65ab491e8aaa9b4cMichele Di Giorgio :type legend_ncol: int 111d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock """ 112d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock __metaclass__ = ABCMeta 113d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 114f4dbd1a60d428b70ea8fc1f05f59343d1db4900cJohn Pocock def __init__(self, traces, templates, **kwargs): 115d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock self._fig = None 116d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock self._layout = None 117d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock super(StaticPlot, self).__init__(traces=traces, 118d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock templates=templates) 119d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 120d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock self.set_defaults() 121d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 122d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock for key in kwargs: 123d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock if key in AttrConf.ARGS_TO_FORWARD: 124d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock self._attr["args_to_forward"][key] = kwargs[key] 125d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock else: 126d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock self._attr[key] = kwargs[key] 127d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 128d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock if "signals" in self._attr: 129d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock self._describe_signals() 130d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 131d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock self._check_data() 132d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 133d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock if "column" not in self._attr: 134d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock raise RuntimeError("Value Column not specified") 135d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 136d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock zip_constraints = not self._attr["permute"] 137d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock self.c_mgr = ConstraintManager(traces, self._attr["column"], 138d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock self.templates, self._attr["pivot"], 139e6274bd2296229dae5303df8b4226601cc4abdb6Javi Merino self._attr["filters"], 140e6274bd2296229dae5303df8b4226601cc4abdb6Javi Merino zip_constraints=zip_constraints) 141d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 142d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock def savefig(self, *args, **kwargs): 143d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock """Save the plot as a PNG fill. This calls into 144d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock :mod:`matplotlib.figure.savefig` 145d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock """ 146d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 147d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock if self._fig is None: 148d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock self.view() 149d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock self._fig.savefig(*args, **kwargs) 150d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 151d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock @abstractmethod 152d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock def set_defaults(self): 153d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock """Sets the default attrs""" 154d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock self._attr["width"] = AttrConf.WIDTH 155d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock self._attr["length"] = AttrConf.LENGTH 156d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock self._attr["per_line"] = AttrConf.PER_LINE 157d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock self._attr["concat"] = AttrConf.CONCAT 158d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock self._attr["filters"] = {} 159d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock self._attr["style"] = True 160d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock self._attr["permute"] = False 161d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock self._attr["pivot"] = AttrConf.PIVOT 162d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock self._attr["xlim"] = AttrConf.XLIM 1630121e7156c2f9cc25637b206a6c2827a24ea782bMichele Di Giorgio self._attr["ylim"] = AttrConf.YLIM 164d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock self._attr["title"] = AttrConf.TITLE 165d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock self._attr["args_to_forward"] = {} 166d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock self._attr["map_label"] = {} 16766d4e90b9b9fa5db544e4154505e97f8db562aa2John Pocock self._attr["_legend_handles"] = [] 16866d4e90b9b9fa5db544e4154505e97f8db562aa2John Pocock self._attr["_legend_labels"] = [] 1699b4898aa3ea40f2af85157af65ab491e8aaa9b4cMichele Di Giorgio self._attr["legend_ncol"] = AttrConf.LEGEND_NCOL 170d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 171d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock def view(self, test=False): 172d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock """Displays the graph""" 173d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 174d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock if test: 175d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock self._attr["style"] = True 176d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock AttrConf.MPL_STYLE["interactive"] = False 177d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 178287241040f9f8c58399f97412383efb36324c63dJohn Pocock permute = self._attr["permute"] and not self._attr["concat"] 179287241040f9f8c58399f97412383efb36324c63dJohn Pocock if self._attr["style"]: 180287241040f9f8c58399f97412383efb36324c63dJohn Pocock with plt.rc_context(AttrConf.MPL_STYLE): 181287241040f9f8c58399f97412383efb36324c63dJohn Pocock self._resolve(permute, self._attr["concat"]) 182d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock else: 183287241040f9f8c58399f97412383efb36324c63dJohn Pocock self._resolve(permute, self._attr["concat"]) 184d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 1855d35796164c77d1350b7dc26329fb0d0abc549b5John Pocock def make_title(self, constraint, pivot, permute, concat): 1865d35796164c77d1350b7dc26329fb0d0abc549b5John Pocock """Generates a title string for an axis""" 1875d35796164c77d1350b7dc26329fb0d0abc549b5John Pocock if concat: 1885d35796164c77d1350b7dc26329fb0d0abc549b5John Pocock return str(constraint) 189b24eed7a902022c014c61f7c8c3061adf53f4eacMichele Di Giorgio 1902c3ca82c4b1c8ee6d6e37718696c4b422fe824c4John Pocock if permute: 19129a12bb53910915378e5fa9b3c1cf35fbe8cfec7Michele Di Giorgio return constraint.get_data_name() 192b24eed7a902022c014c61f7c8c3061adf53f4eacMichele Di Giorgio elif pivot != AttrConf.PIVOT_VAL: 193b24eed7a902022c014c61f7c8c3061adf53f4eacMichele Di Giorgio return "{0}: {1}".format(self._attr["pivot"], self._attr["map_label"].get(pivot, pivot)) 1942c3ca82c4b1c8ee6d6e37718696c4b422fe824c4John Pocock else: 195b24eed7a902022c014c61f7c8c3061adf53f4eacMichele Di Giorgio return "" 1962c3ca82c4b1c8ee6d6e37718696c4b422fe824c4John Pocock 1979b4898aa3ea40f2af85157af65ab491e8aaa9b4cMichele Di Giorgio def add_to_legend(self, series_index, handle, constraint, pivot, concat, permute): 1985d35796164c77d1350b7dc26329fb0d0abc549b5John Pocock """ 1995d35796164c77d1350b7dc26329fb0d0abc549b5John Pocock Add series handles and names to the legend 2005d35796164c77d1350b7dc26329fb0d0abc549b5John Pocock A handle is returned from a plot on an axis 2015d35796164c77d1350b7dc26329fb0d0abc549b5John Pocock e.g. Line2D from axis.plot() 2025d35796164c77d1350b7dc26329fb0d0abc549b5John Pocock """ 2035d35796164c77d1350b7dc26329fb0d0abc549b5John Pocock self._attr["_legend_handles"][series_index] = handle 2045d35796164c77d1350b7dc26329fb0d0abc549b5John Pocock legend_labels = self._attr["_legend_labels"] 2055d35796164c77d1350b7dc26329fb0d0abc549b5John Pocock 2065d35796164c77d1350b7dc26329fb0d0abc549b5John Pocock if concat and pivot == AttrConf.PIVOT_VAL: 2075d35796164c77d1350b7dc26329fb0d0abc549b5John Pocock legend_labels[series_index] = self._attr["column"] 2085d35796164c77d1350b7dc26329fb0d0abc549b5John Pocock elif concat: 2095d35796164c77d1350b7dc26329fb0d0abc549b5John Pocock legend_labels[series_index] = "{0}: {1}".format( 2105d35796164c77d1350b7dc26329fb0d0abc549b5John Pocock self._attr["pivot"], 2115d35796164c77d1350b7dc26329fb0d0abc549b5John Pocock self._attr["map_label"].get(pivot, pivot) 2125d35796164c77d1350b7dc26329fb0d0abc549b5John Pocock ) 2139b4898aa3ea40f2af85157af65ab491e8aaa9b4cMichele Di Giorgio elif permute: 21429a12bb53910915378e5fa9b3c1cf35fbe8cfec7Michele Di Giorgio legend_labels[series_index] = constraint._template.name + ":" + constraint.column 2155d35796164c77d1350b7dc26329fb0d0abc549b5John Pocock else: 2165d35796164c77d1350b7dc26329fb0d0abc549b5John Pocock legend_labels[series_index] = str(constraint) 21766d4e90b9b9fa5db544e4154505e97f8db562aa2John Pocock 218287241040f9f8c58399f97412383efb36324c63dJohn Pocock def _resolve(self, permute, concat): 219287241040f9f8c58399f97412383efb36324c63dJohn Pocock """Determine what data to plot on which axis""" 220d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock pivot_vals, len_pivots = self.c_mgr.generate_pivots(permute) 2212c3ca82c4b1c8ee6d6e37718696c4b422fe824c4John Pocock pivot_vals = list(pivot_vals) 222d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 223287241040f9f8c58399f97412383efb36324c63dJohn Pocock num_of_axes = len(self.c_mgr) if concat else len_pivots 224287241040f9f8c58399f97412383efb36324c63dJohn Pocock 225d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock # Create a 2D Layout 226d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock self._layout = PlotLayout( 227d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock self._attr["per_line"], 228287241040f9f8c58399f97412383efb36324c63dJohn Pocock num_of_axes, 229d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock width=self._attr["width"], 230d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock length=self._attr["length"], 231d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock title=self._attr['title']) 232d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 233d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock self._fig = self._layout.get_fig() 234d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock 2356b7add538125171d58e9569025062c21dc4d2923Michele Di Giorgio # Determine what constraint to plot and the corresponding pivot value 236d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock if permute: 23766d4e90b9b9fa5db544e4154505e97f8db562aa2John Pocock legend_len = self.c_mgr._max_len 2382c3ca82c4b1c8ee6d6e37718696c4b422fe824c4John Pocock pivots = [y for _, y in pivot_vals] 23999afffa3870fcc68ac895fa58ff99e8043ff34dbMichele Di Giorgio c_dict = {c : str(c) for c in self.c_mgr} 24099afffa3870fcc68ac895fa58ff99e8043ff34dbMichele Di Giorgio c_list = sorted(c_dict.items(), key=lambda x: (x[1].split(":")[-1], x[1].split(":")[0])) 24199afffa3870fcc68ac895fa58ff99e8043ff34dbMichele Di Giorgio constraints = [c[0] for c in c_list] 24299afffa3870fcc68ac895fa58ff99e8043ff34dbMichele Di Giorgio cp_pairs = [(c, p) for c in constraints for p in sorted(set(pivots))] 243d098bd5d11b3305a66c13c705aba65879e7f3adcJohn Pocock else: 244287241040f9f8c58399f97412383efb36324c63dJohn Pocock legend_len = len_pivots if concat else len(self.c_mgr) 2452c3ca82c4b1c8ee6d6e37718696c4b422fe824c4John Pocock pivots = pivot_vals 24666d4e90b9b9fa5db544e4154505e97f8db562aa2John Pocock cp_pairs = [(c, p) for c in self.c_mgr for p in pivots if p in c.result] 2472c3ca82c4b1c8ee6d6e37718696c4b422fe824c4John Pocock 2486b7add538125171d58e9569025062c21dc4d2923Michele Di Giorgio # Initialise legend data and colormap 24966d4e90b9b9fa5db544e4154505e97f8db562aa2John Pocock self._attr["_legend_handles"] = [None] * legend_len 25066d4e90b9b9fa5db544e4154505e97f8db562aa2John Pocock self._attr["_legend_labels"] = [None] * legend_len 25135e40457aa97167d333835c796d77b7404014b83John Pocock 25235e40457aa97167d333835c796d77b7404014b83John Pocock if "colors" in self._attr: 25335e40457aa97167d333835c796d77b7404014b83John Pocock self._cmap = ColorMap.rgb_cmap(self._attr["colors"]) 25435e40457aa97167d333835c796d77b7404014b83John Pocock else: 25535e40457aa97167d333835c796d77b7404014b83John Pocock self._cmap = ColorMap(legend_len) 2562c3ca82c4b1c8ee6d6e37718696c4b422fe824c4John Pocock 2576b7add538125171d58e9569025062c21dc4d2923Michele Di Giorgio # Group constraints/series with the axis they are to be plotted on 25866d4e90b9b9fa5db544e4154505e97f8db562aa2John Pocock figure_data = ddict(list) 25966d4e90b9b9fa5db544e4154505e97f8db562aa2John Pocock for i, (constraint, pivot) in enumerate(cp_pairs): 260287241040f9f8c58399f97412383efb36324c63dJohn Pocock axis = self._layout.get_axis(constraint.trace_index if concat else i) 2615d35796164c77d1350b7dc26329fb0d0abc549b5John Pocock figure_data[axis].append((constraint, pivot)) 2622c3ca82c4b1c8ee6d6e37718696c4b422fe824c4John Pocock 2636b7add538125171d58e9569025062c21dc4d2923Michele Di Giorgio # Plot each axis 2645d35796164c77d1350b7dc26329fb0d0abc549b5John Pocock for axis, series_list in figure_data.iteritems(): 26566d4e90b9b9fa5db544e4154505e97f8db562aa2John Pocock self.plot_axis( 26666d4e90b9b9fa5db544e4154505e97f8db562aa2John Pocock axis, 26766d4e90b9b9fa5db544e4154505e97f8db562aa2John Pocock series_list, 26866d4e90b9b9fa5db544e4154505e97f8db562aa2John Pocock permute, 2695d35796164c77d1350b7dc26329fb0d0abc549b5John Pocock self._attr["concat"], 2705d35796164c77d1350b7dc26329fb0d0abc549b5John Pocock self._attr["args_to_forward"] 2715d35796164c77d1350b7dc26329fb0d0abc549b5John Pocock ) 2720121e7156c2f9cc25637b206a6c2827a24ea782bMichele Di Giorgio if self._attr["xlim"]: 2730121e7156c2f9cc25637b206a6c2827a24ea782bMichele Di Giorgio axis.set_xlim(self._attr["xlim"]) 2740121e7156c2f9cc25637b206a6c2827a24ea782bMichele Di Giorgio if self._attr["ylim"]: 2750121e7156c2f9cc25637b206a6c2827a24ea782bMichele Di Giorgio axis.set_ylim(self._attr["ylim"]) 2765d35796164c77d1350b7dc26329fb0d0abc549b5John Pocock 2776b7add538125171d58e9569025062c21dc4d2923Michele Di Giorgio # Show legend 2786b7add538125171d58e9569025062c21dc4d2923Michele Di Giorgio legend = self._fig.legend(self._attr["_legend_handles"], 2799b4898aa3ea40f2af85157af65ab491e8aaa9b4cMichele Di Giorgio self._attr["_legend_labels"], 2809b4898aa3ea40f2af85157af65ab491e8aaa9b4cMichele Di Giorgio loc='lower center', 2819b4898aa3ea40f2af85157af65ab491e8aaa9b4cMichele Di Giorgio ncol=self._attr["legend_ncol"], 2829b4898aa3ea40f2af85157af65ab491e8aaa9b4cMichele Di Giorgio borderaxespad=0.) 2836b7add538125171d58e9569025062c21dc4d2923Michele Di Giorgio legend.get_frame().set_facecolor('#F4F4F4') 284287241040f9f8c58399f97412383efb36324c63dJohn Pocock 285287241040f9f8c58399f97412383efb36324c63dJohn Pocock self._layout.finish(num_of_axes) 28666d4e90b9b9fa5db544e4154505e97f8db562aa2John Pocock 2875d35796164c77d1350b7dc26329fb0d0abc549b5John Pocock def plot_axis(self, axis, series_list, permute, concat, args_to_forward): 2885d35796164c77d1350b7dc26329fb0d0abc549b5John Pocock """Internal Method called to plot data (series_list) on a given axis""" 28966d4e90b9b9fa5db544e4154505e97f8db562aa2John Pocock raise NotImplementedError("Method Not Implemented") 290