1#    Copyright 2015-2017 ARM Limited
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14#
15
16"""
17This class sublclasses :mod:`trappy.plotter.StaticPlot.StaticPlot` to
18implement a line plot.
19"""
20
21from trappy.plotter import AttrConf
22from trappy.plotter.StaticPlot import StaticPlot
23
24class LinePlot(StaticPlot):
25    """
26    This class uses :mod:`trappy.plotter.Constraint.Constraint` to
27    represent different permutations of input parameters. These
28    constraints are generated by creating an instance of
29    :mod:`trappy.plotter.Constraint.ConstraintManager`.
30
31    :param traces: The input data
32    :type traces: a list of :mod:`trappy.trace.FTrace`,
33        :mod:`trappy.trace.SysTrace`, :mod:`trappy.trace.BareTrace`
34        or :mod:`pandas.DataFrame` or a single instance of them.
35
36    :param column: specifies the name of the column to
37           be plotted.
38    :type column: (str, list(str))
39
40    :param templates: TRAPpy events
41
42        .. note::
43
44                This is not required if a :mod:`pandas.DataFrame` is
45                used
46
47    :type templates: :mod:`trappy.base.Base`
48
49    :param filters: Filter the column to be plotted as per the
50        specified criteria. For Example:
51        ::
52
53            filters =
54                    {
55                        "pid": [ 3338 ],
56                        "cpu": [0, 2, 4],
57                    }
58    :type filters: dict
59
60    :param per_line: Used to control the number of graphs
61        in each graph subplot row
62    :type per_line: int
63
64    :param concat: Draw all the pivots on a single graph
65    :type concat: bool
66
67    :param fill: Fill the area under the plots
68    :type fill: bool
69
70    :param permute: Draw one plot for each of the traces specified
71    :type permute: bool
72
73    :param drawstyle: This argument is forwarded to the matplotlib
74        corresponding :func:`matplotlib.pyplot.plot` call
75
76        drawing style.
77
78        .. note::
79
80            step plots are not currently supported for filled
81            graphs
82
83    :param xlim: A tuple representing the upper and lower xlimits
84    :type xlim: tuple
85
86    :param ylim: A tuple representing the upper and lower ylimits
87    :type ylim: tuple
88
89    :param title: A title describing all the generated plots
90    :type title: str
91
92    :param style: Created pre-styled graphs loaded from
93        :mod:`trappy.plotter.AttrConf.MPL_STYLE`
94    :type style: bool
95
96    :param signals: A string of the type event_name:column to indicate
97        the value that needs to be plotted.  You can add an additional
98        parameter to specify the color of the lin in rgb:
99        "event_name:column:color".  The color is specified as a comma
100        separated list of rgb values, from 0 to 255 or from 0x0 to
101        0xff.  E.g. 0xff,0x0,0x0 is red and 100,40,32 is brown.
102
103        .. note::
104
105            - Only one of `signals` or both `templates` and
106              `columns` should be specified
107            - Signals format won't work for :mod:`pandas.DataFrame`
108              input
109
110    :type signals: str
111
112    """
113
114    def __init__(self, traces, templates=None, **kwargs):
115        # Default keys, each can be overridden in kwargs
116
117        super(LinePlot, self).__init__(
118            traces=traces,
119            templates=templates,
120            **kwargs)
121
122        self._check_add_scatter()
123
124    def set_defaults(self):
125        """Sets the default attrs"""
126        super(LinePlot, self).set_defaults()
127        self._attr["scatter"] = AttrConf.PLOT_SCATTER
128        self._attr["fill"] = AttrConf.FILL
129
130    def _check_add_scatter(self):
131        """Check if a scatter plot is needed
132        and augment the forwarded args accordingly"""
133
134        if self._attr["scatter"]:
135            self._attr["args_to_forward"]["linestyle"] = ""
136            self._attr["args_to_forward"]["marker"] = "o"
137            if "point_size" in self._attr:
138                self._attr["args_to_forward"]["markersize"] = \
139                    self._attr["point_size"]
140
141    def fill_line(self, axis, line_2d, cmap_index):
142        """Fill the area under a line"""
143        drawstyle = line_2d.get_drawstyle()
144        if drawstyle.startswith("steps"):
145            # This has been fixed in upstream matplotlib
146            raise UserWarning("matplotlib does not support fill for step plots")
147
148        xdat, ydat = line_2d.get_data(orig=False)
149        axis.fill_between(
150            xdat,
151            axis.get_ylim()[0],
152            ydat,
153            facecolor=self._cmap.cmap(cmap_index),
154            alpha=AttrConf.ALPHA)
155
156    def plot_axis(self, axis, series_list, permute, concat, args_to_forward):
157        """Internal Method called to plot data (series_list) on a given axis"""
158        for i, (constraint, pivot) in enumerate(series_list):
159            result = constraint.result
160            line_2d_list = axis.plot(
161                result[pivot].index,
162                result[pivot].values,
163                color=self._cmap.cmap(i),
164                **args_to_forward
165            )
166
167            if self._attr["fill"]:
168                self.fill_line(axis, line_2d_list[0], i)
169
170            axis.set_title(self.make_title(constraint, pivot, permute, concat))
171
172            self.add_to_legend(i, line_2d_list[0], constraint, pivot, concat, permute)
173