1
# pylint: disable=no-member,invalid-name,redefined-outer-name
2 6
"""ArviZ plotting backends."""
3 6
import re
4

5 6
import numpy as np
6 6
from pandas import DataFrame
7

8 6
from ...rcparams import rcParams
9

10 6
__all__ = [
11
    "to_cds",
12
    "output_notebook",
13
    "output_file",
14
    "ColumnDataSource",
15
    "create_layout",
16
    "show_layout",
17
]
18

19

20 6
def to_cds(
21
    data,
22
    var_names=None,
23
    groups=None,
24
    dimensions=None,
25
    group_info=True,
26
    var_name_format=None,
27
    index_origin=None,
28
):
29
    """Transform data to ColumnDataSource (CDS) compatible with Bokeh.
30

31
    Uses `_ARVIZ_GROUP_` and `_ARVIZ_CDS_SELECTION_` to separate var_name
32
    from group and dimensions in CDS columns.
33

34
    Parameters
35
    ----------
36
    data : obj
37
        Any object that can be converted to an az.InferenceData object
38
        Refer to documentation of az.convert_to_inference_data for details
39
    var_names : str or list of str, optional
40
        Variables to be processed, if None all variables are processed.
41
    groups : str or list of str, optional
42
        Select groups for CDS. Default groups are {"posterior_groups", "prior_groups",
43
        "posterior_groups_warmup"}
44

45
        - posterior_groups: posterior, posterior_predictive, sample_stats
46
        - prior_groups: prior, prior_predictive, sample_stats_prior
47
        - posterior_groups_warmup: warmup_posterior, warmup_posterior_predictive,
48
          warmup_sample_stats
49

50
    ignore_groups : str or list of str, optional
51
        Ignore specific groups from CDS.
52
    dimension : str, or list of str, optional
53
        Select dimensions along to slice the data. By default uses ("chain", "draw").
54
    group_info : bool
55
        Add group info for `var_name_format`
56
    var_name_format : str or tuple of tuple of string, optional
57
        Select column name format for non-scalar input.
58
        Predefined options are {"brackets", "underscore", "cds"}
59

60
            "brackets":
61
                - add_group_info == False: ``theta[0,0]``
62
                - add_group_info == True: ``theta_posterior[0,0]``
63
            "underscore":
64
                - add_group_info == False: ``theta_0_0``
65
                - add_group_info == True: ``theta_posterior_0_0_``
66
            "cds":
67
                - add_group_info == False: ``theta_ARVIZ_CDS_SELECTION_0_0``
68
                - add_group_info == True: ``theta_ARVIZ_GROUP_posterior__ARVIZ_CDS_SELECTION_0_0``
69
            tuple:
70
                Structure:
71

72
                    - tuple: (dim_info, group_info)
73

74
                        - dim_info: (str: `.join` separator,
75
                          str: dim_separator_start,
76
                          str: dim_separator_end)
77
                        - group_info: (str: group separator start, str: group separator end)
78

79
                Example: ((",", "[", "]"), ("_", ""))
80

81
                    - add_group_info == False: ``theta[0,0]``
82
                    - add_group_info == True: ``theta_posterior[0,0]``
83

84
    index_origin : int, optional
85
        Start parameter indices from `index_origin`. Either 0 or 1.
86

87
    Returns
88
    -------
89
    bokeh.models.ColumnDataSource object
90
    """
91 0
    from ...utils import flatten_inference_data_to_dict
92

93 0
    if var_name_format is None:
94 0
        var_name_format = "cds"
95

96 0
    cds_dict = flatten_inference_data_to_dict(
97
        data=data,
98
        var_names=var_names,
99
        groups=groups,
100
        dimensions=dimensions,
101
        group_info=group_info,
102
        index_origin=index_origin,
103
        var_name_format=var_name_format,
104
    )
105 0
    cds_data = ColumnDataSource(DataFrame.from_dict(cds_dict, orient="columns"))
106 0
    return cds_data
107

108

109 6
def output_notebook(*args, **kwargs):
110
    """Wrap bokeh.plotting.output_notebook."""
111 0
    import bokeh.plotting as bkp
112

113 0
    return bkp.output_notebook(*args, **kwargs)
114

115

116 6
def output_file(*args, **kwargs):
117
    """Wrap bokeh.plotting.output_file."""
118 0
    import bokeh.plotting as bkp
119

120 0
    return bkp.output_file(*args, **kwargs)
121

122

123 6
def ColumnDataSource(*args, **kwargs):
124
    """Wrap bokeh.models.ColumnDataSource."""
125 0
    from bokeh.models import ColumnDataSource
126

127 0
    return ColumnDataSource(*args, **kwargs)
128

129

130 6
def create_layout(ax, force_layout=False):
131
    """Transform bokeh array of figures to layout."""
132 0
    ax = np.atleast_2d(ax)
133 0
    subplot_order = rcParams["plot.bokeh.layout.order"]
134 0
    if force_layout:
135 0
        from bokeh.layouts import gridplot as layout
136

137 0
        ax = ax.tolist()
138 0
        layout_args = {
139
            "sizing_mode": rcParams["plot.bokeh.layout.sizing_mode"],
140
            "toolbar_location": rcParams["plot.bokeh.layout.toolbar_location"],
141
        }
142 0
    elif any(item in subplot_order for item in ("row", "column")):
143
        # check number of rows
144 0
        match = re.match(r"(\d*)(row|column)", subplot_order)
145 0
        n = int(match.group(1)) if match.group(1) is not None else 1
146 0
        subplot_order = match.group(2)
147
        # set up 1D list of axes
148 0
        ax = [item for item in ax.ravel().tolist() if item is not None]
149 0
        layout_args = {"sizing_mode": rcParams["plot.bokeh.layout.sizing_mode"]}
150 0
        if subplot_order == "row" and n == 1:
151 0
            from bokeh.layouts import row as layout
152 0
        elif subplot_order == "column" and n == 1:
153 0
            from bokeh.layouts import column as layout
154
        else:
155 0
            from bokeh.layouts import layout
156

157 0
        if n != 1:
158 0
            ax = np.array(ax + [None for _ in range(int(np.ceil(len(ax) / n)) - len(ax))])
159 0
            if subplot_order == "row":
160 0
                ax = ax.reshape(n, -1)
161
            else:
162 0
                ax = ax.reshape(-1, n)
163 0
            ax = ax.tolist()
164
    else:
165 0
        if subplot_order in ("square", "square_trimmed"):
166 0
            ax = [item for item in ax.ravel().tolist() if item is not None]
167 0
            n = int(np.ceil(len(ax) ** 0.5))
168 0
            ax = ax + [None for _ in range(n ** 2 - len(ax))]
169 0
            ax = np.array(ax).reshape(n, n)
170 0
        ax = ax.tolist()
171 0
        if (subplot_order == "square_trimmed") and any(
172
            all(item is None for item in row) for row in ax
173
        ):
174 0
            from bokeh.layouts import layout
175

176 0
            ax = [row for row in ax if not all(item is None for item in row)]
177 0
            layout_args = {"sizing_mode": rcParams["plot.bokeh.layout.sizing_mode"]}
178
        else:
179 0
            from bokeh.layouts import gridplot as layout
180

181 0
            layout_args = {
182
                "sizing_mode": rcParams["plot.bokeh.layout.sizing_mode"],
183
                "toolbar_location": rcParams["plot.bokeh.layout.toolbar_location"],
184
            }
185
    # ignore "fixed" sizing_mode without explicit width and height
186 0
    if layout_args.get("sizing_mode", "") == "fixed":
187 0
        layout_args.pop("sizing_mode")
188 0
    return layout(ax, **layout_args)
189

190

191 6
def show_layout(ax, show=True, force_layout=False):
192
    """Create a layout and call bokeh show."""
193 4
    if show is None:
194 0
        show = rcParams["plot.bokeh.show"]
195 4
    if show:
196 0
        import bokeh.plotting as bkp
197

198 0
        layout = create_layout(ax, force_layout=force_layout)
199 0
        bkp.show(layout)
200

201

202 6
def _copy_docstring(lib, function):
203
    """Extract docstring from function."""
204 6
    import importlib
205

206 6
    try:
207 6
        module = importlib.import_module(lib)
208 6
        func = getattr(module, function)
209 6
        doc = func.__doc__
210 0
    except ImportError:
211 0
        doc = "Failed to import function {} from {}".format(function, lib)
212

213 6
    if not isinstance(doc, str):
214 0
        doc = ""
215 6
    return doc
216

217

218 6
output_notebook.__doc__ += "\n\n" + _copy_docstring("bokeh.plotting", "output_notebook")
219 6
output_file.__doc__ += "\n\n" + _copy_docstring("bokeh.plotting", "output_file")
220 6
ColumnDataSource.__doc__ += "\n\n" + _copy_docstring("bokeh.models", "ColumnDataSource")

Read our documentation on viewing source code .

Loading