Exemplo n.º 1
0
    def _update_page_per_zr(selections: dict, page_selected: str) -> list:
        if page_selected != "per_zr":
            raise PreventUpdate

        selections = selections[page_selected]
        if not selections["update"]:
            raise PreventUpdate

        figs = []
        selectors = [
            x
            for x in ["ZONE", "REGION", "FACIES", "FIPNUM", "SET"]
            if x in volumemodel.selectors
        ]
        color = selections["Color by"] is not None
        for selector in selectors:
            groups = list({selector, selections["Color by"]}) if color else [selector]
            dframe = volumemodel.get_df(filters=selections["filters"], groups=groups)
            piefig = (
                (
                    create_figure(
                        plot_type="pie",
                        data_frame=dframe,
                        values=selections["X Response"],
                        names=selector,
                        color_discrete_sequence=selections["Colorscale"],
                        color=selector,
                    )
                    .update_traces(marker_line=dict(color="#000000", width=1))
                    .update_layout(margin=dict(l=10, b=10))
                )
                if not color
                else []
            )
            barfig = create_figure(
                plot_type="bar",
                data_frame=dframe,
                x=selector,
                y=selections["X Response"],
                title=f"{selections['X Response']} per {selector}",
                barmode="overlay" if selector == selections["Color by"] else "group",
                layout={"bargap": 0.05},
                color_discrete_sequence=selections["Colorscale"],
                color=selections["Color by"],
                text=selections["X Response"],
                xaxis=dict(type="category", tickangle=45, tickfont_size=17, title=None),
            ).update_traces(
                texttemplate=(
                    "%{text:.3s}"
                    if selections["X Response"] in volumemodel.volume_columns
                    else "%{text:.3g}"
                ),
                textposition="auto",
            )

            if selections["X Response"] not in volumemodel.hc_responses:
                barfig.add_annotation(fluid_annotation(selections))
            figs.append([piefig, barfig])
        return plots_per_zone_region_layout(figs)
Exemplo n.º 2
0
    def _update_page_per_zr(
        selections: dict,
        page_selected: str,
        figure_ids: List[dict],
    ) -> list:
        if page_selected != "per_zr":
            raise PreventUpdate

        selections = selections[page_selected]
        if not selections["update"]:
            raise PreventUpdate

        figs = {}
        for selector in [x["selector"] for x in figure_ids]:
            dframe = volumemodel.get_df(filters=selections["filters"],
                                        groups=[selector])
            texttemplate = ("%{text:.3s}" if selections["X Response"]
                            in volumemodel.volume_columns else "%{text:.3g}")
            # pylint: disable=no-member
            figs[selector] = {
                "pie":
                create_figure(
                    plot_type="pie",
                    data_frame=dframe,
                    values=selections["X Response"],
                    names=selector,
                    title=f"{selections['X Response']} per {selector}",
                    color_discrete_sequence=selections["Colorscale"],
                    color=selector,
                ).update_traces(
                    marker_line=dict(color="#000000", width=1)).update_layout(
                        margin=dict(l=10, b=10)),
                "bar":
                create_figure(
                    plot_type="bar",
                    data_frame=dframe,
                    x=selector,
                    y=selections["X Response"],
                    color_discrete_sequence=px.colors.diverging.BrBG_r,
                    color=selections["Color by"],
                    text=selections["X Response"],
                    xaxis=dict(type="category",
                               tickangle=45,
                               tickfont_size=17,
                               title=None),
                ).update_traces(texttemplate=texttemplate,
                                textposition="auto").add_annotation(
                                    fluid_annotation(selections)),
            }

        output_figs = []
        for fig_id in figure_ids:
            output_figs.append(figs[fig_id["selector"]][fig_id["chart"]])
        return output_figs
Exemplo n.º 3
0
def create_realplot(df: pd.DataFrame, sensitivity_colors: dict) -> go.Figure:
    senscasecolors = {
        senscase: sensitivity_colors[sensname]
        for senscase, sensname in zip(df["sensname_case"], df["sensname"])
    }

    return (create_figure(
        plot_type="bar",
        data_frame=df,
        x="REAL",
        y="VALUE",
        color="sensname_case",
        color_discrete_map=senscasecolors,
        barmode="overlay",
        custom_data=["casetype"],
        yaxis={
            "range": [df["VALUE"].min() * 0.7, df["VALUE"].max() * 1.1]
        },
        opacity=0.85,
    ).update_layout(legend={
        "orientation": "h",
        "yanchor": "bottom",
        "y": 1.02
    }).update_layout(legend_title_text="").for_each_trace(lambda t: (
        t.update(marker_line_color="black") if t["customdata"][0][0] == "high"
        else t.update(marker_line_color="white", marker_line_width=2)) if t[
            "customdata"][0][0] != "mc" else None))
Exemplo n.º 4
0
def create_barfig(df: pd.DataFrame, groupby: list, diff_mode: str,
                  colorcol: str) -> Union[None, go.Figure]:
    if df.empty:
        return None
    return (create_figure(
        plot_type="bar",
        data_frame=df,
        x=df[groupby].astype(str).agg(" ".join, axis=1)
        if groupby else ["Total"],
        y=diff_mode,
        color_continuous_scale="teal_r",
        color=df[colorcol],
        hover_data={col: True
                    for col in groupby},
        opacity=1,
    ).update_layout(
        margin={
            "l": 20,
            "r": 20,
            "t": 5,
            "b": 5
        },
        bargap=0.15,
        paper_bgcolor="rgba(0,0,0,0)",
    ).update_xaxes(title_text=None, tickangle=45,
                   ticks="outside").update_yaxes(zeroline=True,
                                                 zerolinecolor="black"))
Exemplo n.º 5
0
 def create_figure(self) -> go.Figure:
     return (create_figure(
         plot_type="scatter",
         data_frame=self.dframe,
         x="X",
         y="Y",
         color=self.color_by if self.color_by != "PERMX" else np.log10(
             self.dframe[self.color_by]),
         color_discrete_map=self.colormap,
         xaxis={
             "constrain": "domain",
             **self.axis_layout
         },
         yaxis={
             "scaleanchor": "x",
             **self.axis_layout
         },
         hover_data=[self.color_by] + self.hover_data,
         color_continuous_scale="Viridis",
     ).update_traces(marker_size=10, unselected={
         "marker": {
             "opacity": 0
         }
     }).update_coloraxes(showscale=False).update_layout(
         plot_bgcolor="white",
         margin={
             "t": 10,
             "b": 10,
             "l": 0,
             "r": 0
         },
         showlegend=False,
     ))
Exemplo n.º 6
0
    def make_grouped_plot(
        self,
        ensembles: list,
        parameters: List[Any],
        plot_type: str = "distribution",
    ) -> go.Figure:
        """Create subplots for selected parameters"""
        df = self.dataframe_melted.copy()
        df = df[df["ENSEMBLE"].isin(ensembles)]
        df = df[df["PARAMETER"].isin(parameters)]
        df = self._sort_parameters_col(df, parameters)

        return (create_figure(
            plot_type=plot_type,
            data_frame=df,
            x="VALUE",
            facet_col="PARAMETER",
            color="ENSEMBLE",
            color_discrete_sequence=self.colorway,
        ).update_xaxes(matches=None).for_each_trace(lambda t: t.update(text=t[
            "text"].replace("VALUE", "") if t["text"] is not None else None)))
Exemplo n.º 7
0
def create_scatterfig(
    df: pd.DataFrame,
    x: str,
    y: str,
    selections: dict,
    groupby: list,
    diff_mode: Optional[str] = None,
) -> go.Figure:

    highlight_colors = {"yes": "#FF1243", "no": "#80B7BC"}
    colorby = (selections["Color by"]
               if selections["Color by"] == "highlighted" else groupby[0])
    df[colorby] = df[colorby].astype(str)

    fig = (create_figure(
        plot_type="scatter",
        data_frame=df,
        x=x,
        y=y,
        color_discrete_sequence=px.colors.qualitative.Dark2,
        color_discrete_map=highlight_colors
        if colorby == "highlighted" else None,
        color=colorby,
        hover_data=groupby,
    ).update_traces(marker_size=10).update_layout(margin={
        "l": 20,
        "r": 20,
        "t": 20,
        "b": 20
    }))
    if len(df) == 1:
        fig.update_xaxes(range=[df[x].mean() * 0.95, df[x].mean() * 1.05])
    if diff_mode is not None:
        fig.update_yaxes(range=find_diff_plot_range(df, diff_mode, selections))
        if diff_mode == "diff (%)" and y == diff_mode:
            fig.add_hline(y=selections["Accept value"],
                          line_dash="dot").add_hline(
                              y=-selections["Accept value"], line_dash="dot")
    return fig
Exemplo n.º 8
0
    def make_grouped_plot(
        self,
        ensembles: list,
        prop: str,
        selector_values: List[Any],
        statistic: str = "Avg",
        plot_type: str = "histogram",
        match_axis: bool = False,
    ) -> go.Figure:
        sel_length = 1
        for selector in selector_values:
            sel_length *= len(selector)

        df = self.dataframe.copy()
        df = df[df["PROPERTY"] == prop]
        if selector_values is not None:
            df = self.filter_dataframe(df, self.selectors, selector_values)

        df = df[df["ENSEMBLE"].isin(ensembles)]

        fig = create_figure(
            plot_type=plot_type
            if plot_type != "scatter_ensemble" else "scatter",
            data_frame=df,
            x="REAL" if plot_type != "distribution" else statistic,
            y=statistic if plot_type != "distribution" else None,
            facet_col="label"
            if plot_type != "scatter_ensemble" else "ENSEMBLE",
            color="ENSEMBLE" if plot_type != "scatter_ensemble" else "label",
            color_discrete_sequence=self.colorway,
        )
        if not match_axis:
            fig.update_xaxes(matches=None).update_yaxes(matches=None)

        fig = fig.to_dict()
        fig["layout"] = self.theme.create_themed_layout(fig["layout"])
        return fig
Exemplo n.º 9
0
    def _update_page_1p1t_and_custom(
        selections: dict,
        plot_table_select: str,
        page_selected: str,
        figure_ids: list,
        table_wrapper_ids: list,
    ) -> tuple:

        if page_selected not in ["1p1t", "custom"]:
            raise PreventUpdate

        selections = selections[page_selected]
        if not selections["update"]:
            raise PreventUpdate

        groups = ["REAL"]
        parameters = []
        responses = []
        for item in ["Subplots", "Color by", "X Response", "Y Response"]:
            if selections[item] is not None:
                if (selections[item] in volumemodel.selectors
                        and selections[item] not in groups):
                    groups.append(selections[item])
                if (selections[item] in volumemodel.parameters
                        and selections[item] not in parameters):
                    parameters.append(selections[item])
                if (item in ["X Response", "Y Response"]
                        and selections[item] not in responses):
                    responses.append(selections[item])

        dframe = volumemodel.get_df(filters=selections["filters"],
                                    groups=groups,
                                    parameters=parameters)

        if not (plot_table_select == "table" and page_selected == "custom"):
            df_for_figure = (
                dframe if
                not (selections["Plot type"] == "bar" and groups != ["REAL"])
                else dframe.groupby([x for x in groups
                                     if x != "REAL"]).mean().reset_index())
            figure = create_figure(
                plot_type=selections["Plot type"],
                data_frame=df_for_figure,
                x=selections["X Response"],
                y=selections["Y Response"],
                nbins=selections["hist_bins"],
                facet_col=selections["Subplots"],
                color=selections["Color by"],
                color_discrete_sequence=selections["Colorscale"],
                color_continuous_scale=selections["Colorscale"],
                barmode=selections["barmode"],
                layout=dict(title=dict(
                    text=(f"{volume_description(selections['X Response'])}" +
                          (f" [{volume_unit(selections['X Response'])}]"
                           if selections["X Response"]
                           in volumemodel.volume_columns else "")),
                    x=0.5,
                    xref="paper",
                    font=dict(size=18),
                ), ),
                yaxis=dict(showticklabels=True),
            ).add_annotation(fluid_annotation(selections))

            if selections["X Response"] in volumemodel.selectors:
                figure.update_xaxes(
                    dict(type="category", tickangle=45, tickfont_size=12))

            if selections["Subplots"] is not None:
                if not selections["X axis matches"]:
                    figure.update_xaxes({"matches": None})
                if not selections["Y axis matches"]:
                    figure.update_yaxes({"matches": None})
        else:
            figure = dash.no_update

        # Make tables
        if not (plot_table_select == "graph" and page_selected == "custom"):
            table_wrapper_children = make_table_wrapper_children(
                dframe=dframe,
                responses=responses,
                groups=groups,
                volumemodel=volumemodel,
                page_selected=page_selected,
                selections=selections,
                table_type="Statistics table",
                view_height=42 if page_selected == "1p1t" else 86,
            )
        else:
            table_wrapper_children = dash.no_update

        return tuple(
            update_relevant_components(
                id_list=id_list,
                update_info=[{
                    "new_value": val,
                    "conditions": {
                        "page": page_selected
                    },
                }],
            ) for val, id_list in zip([figure, table_wrapper_children],
                                      [figure_ids, table_wrapper_ids]))
Exemplo n.º 10
0
    def _update_page_conv(selections: dict, page_selected: str) -> go.Figure:
        if page_selected != "conv":
            raise PreventUpdate

        selections = selections[page_selected]
        if not selections["update"]:
            raise PreventUpdate

        subplots = selections["Subplots"] if selections[
            "Subplots"] is not None else []
        groups = ["REAL"]
        if subplots and subplots not in groups:
            groups.append(subplots)

        dframe = volumemodel.get_df(filters=selections["filters"],
                                    groups=groups)
        dframe = dframe.sort_values(by=["REAL"])

        dfs = []
        df_groups = dframe.groupby(subplots) if subplots else [(None, dframe)]
        for _, df in df_groups:
            for calculation in ["mean", "p10", "p90"]:
                df_stat = df.copy()
                df_stat[selections["X Response"]] = (
                    (df_stat[selections["X Response"]].expanding().mean())
                    if calculation == "mean" else
                    df_stat[selections["X Response"]].expanding().quantile(
                        0.1 if calculation == "p90" else 0.9))
                df_stat["calculation"] = calculation
                dfs.append(df_stat)
        if dfs:
            dframe = pd.concat(dfs)

        figure = (create_figure(
            plot_type="line",
            data_frame=dframe,
            x="REAL",
            y=selections["X Response"],
            facet_col=selections["Subplots"],
            color="calculation",
            title=
            f"Convergence plot of mean/p10/p90 for {selections['X Response']} ",
            yaxis=dict(showticklabels=True),
        ).update_traces(line_width=3.5).update_traces(
            line=dict(color="black"), selector={
                "name": "mean"
            }).update_traces(
                line=dict(color="firebrick", dash="dash"),
                selector={
                    "name": "p10"
                },
            ).update_traces(line=dict(color="royalblue", dash="dash"),
                            selector={
                                "name": "p90"
                            }).add_annotation(fluid_annotation(selections)))

        if selections["Subplots"] is not None:
            if not selections["X axis matches"]:
                figure.update_xaxes({"matches": None})
            if not selections["Y axis matches"]:
                figure.update_yaxes(dict(matches=None))
        return figure
Exemplo n.º 11
0
    def _update_page_custom(selections: dict, page_selected: str) -> tuple:

        if page_selected != "custom":
            raise PreventUpdate

        selections = selections[page_selected]
        if not selections["update"]:
            raise PreventUpdate

        selected_data = [
            selections[x]
            for x in ["Subplots", "Color by", "X Response", "Y Response"]
            if selections[x] is not None
        ]
        groups = ["REAL"]
        parameters = []
        for item in selected_data:
            if item in volumemodel.selectors and item not in groups:
                groups.append(item)
            if item in volumemodel.parameters and item not in parameters:
                parameters.append(item)

        dframe = volumemodel.get_df(
            filters=selections["filters"], groups=groups, parameters=parameters
        )

        if dframe.empty:
            return html.Div(
                "No data left after filtering", style={"margin-top": "40px"}
            )

        df_for_figure = (
            dframe
            if not (selections["Plot type"] == "bar" and not "REAL" in selected_data)
            else dframe.groupby([x for x in groups if x != "REAL"]).mean().reset_index()
        )
        figure = (
            create_figure(
                plot_type=selections["Plot type"],
                data_frame=df_for_figure,
                x=selections["X Response"],
                y=selections["Y Response"],
                nbins=selections["hist_bins"],
                facet_col=selections["Subplots"],
                color=selections["Color by"],
                color_discrete_sequence=selections["Colorscale"],
                color_continuous_scale=selections["Colorscale"],
                barmode=selections["barmode"],
                boxmode=selections["barmode"],
                layout=dict(
                    title=dict(
                        text=(
                            f"{volume_description(selections['X Response'])}"
                            + (
                                f" [{volume_unit(selections['X Response'])}]"
                                if selections["X Response"]
                                in volumemodel.volume_columns
                                else ""
                            )
                        ),
                        x=0.5,
                        xref="paper",
                        font=dict(size=18),
                    ),
                ),
                yaxis=dict(showticklabels=True),
            )
            .add_annotation(fluid_annotation(selections))
            .update_xaxes({"matches": None} if not selections["X axis matches"] else {})
            .update_yaxes({"matches": None} if not selections["Y axis matches"] else {})
            .update_xaxes(
                {"type": "category", "tickangle": 45, "tickfont_size": 12}
                if selections["X Response"] in volumemodel.selectors
                else {}
            )
        )

        return custom_plotting_layout(
            figure=figure,
            tables=make_tables(
                dframe=dframe,
                responses=list({selections["X Response"], selections["Y Response"]}),
                groups=groups,
                volumemodel=volumemodel,
                page_selected=page_selected,
                selections=selections,
                table_type="Statistics table",
                view_height=37,
            )
            if selections["bottom_viz"] == "table"
            else None,
        )
Exemplo n.º 12
0
    def _update_page_conv(selections: dict, page_selected: str) -> go.Figure:
        if page_selected != "conv":
            raise PreventUpdate

        selections = selections[page_selected]
        if not selections["update"]:
            raise PreventUpdate

        subplots = selections["Subplots"] if selections["Subplots"] is not None else []
        groups = ["REAL"]
        if subplots and subplots not in groups:
            groups.append(subplots)

        dframe = volumemodel.get_df(filters=selections["filters"], groups=groups)
        dframe = dframe.sort_values(by=["REAL"])

        if dframe.empty:
            return html.Div(
                "No data left after filtering", style={"margin-top": "40px"}
            )

        dfs = []
        df_groups = dframe.groupby(subplots) if subplots else [(None, dframe)]
        for _, df in df_groups:
            for calculation in ["mean", "p10", "p90"]:
                df_stat = df.reset_index(drop=True).copy()
                df_stat[selections["X Response"]] = (
                    (df_stat[selections["X Response"]].expanding().mean())
                    if calculation == "mean"
                    else df_stat[selections["X Response"]]
                    .expanding()
                    .quantile(0.1 if calculation == "p90" else 0.9)
                )
                df_stat["calculation"] = calculation
                df_stat["index"] = df_stat.index + 1
                dfs.append(df_stat)
        if dfs:
            dframe = pd.concat(dfs)

        title = (
            f"<b>Convergence plot of mean/p10/p90 for {selections['X Response']} </b>"
            "  -  shaded areas indicates failed/filtered out realizations"
        )

        figure = (
            create_figure(
                plot_type="line",
                data_frame=dframe,
                x="REAL",
                y=selections["X Response"],
                facet_col=selections["Subplots"],
                color="calculation",
                custom_data=["calculation", "index"],
                title=title,
                yaxis=dict(showticklabels=True),
            )
            .update_traces(
                hovertemplate=(
                    f"{selections['X Response']} %{{y}} <br>"
                    f"%{{customdata[0]}} for realizations {dframe['REAL'].min()}-%{{x}}<br>"
                    "Realization count: %{customdata[1]} <extra></extra>"
                ),
                line_width=3.5,
            )
            .update_traces(line_color="black", selector={"name": "mean"})
            .update_traces(
                line=dict(color="firebrick", dash="dash"), selector={"name": "p10"}
            )
            .update_traces(
                line=dict(color="royalblue", dash="dash"), selector={"name": "p90"}
            )
            .update_xaxes({"matches": None} if not selections["X axis matches"] else {})
            .update_yaxes({"matches": None} if not selections["Y axis matches"] else {})
        )
        if selections["X Response"] not in volumemodel.hc_responses:
            figure.add_annotation(fluid_annotation(selections))

        missing_reals = [
            x
            for x in range(dframe["REAL"].min(), dframe["REAL"].max())
            if x not in dframe["REAL"].unique()
        ]
        if missing_reals:
            for real_range in to_ranges(missing_reals):
                figure.add_vrect(
                    x0=real_range[0] - 0.5,
                    x1=real_range[1] + 0.5,
                    fillcolor="gainsboro",
                    layer="below",
                    opacity=0.4,
                    line_width=0,
                )

        return convergence_plot_layout(figure=figure)
Exemplo n.º 13
0
def make_distribution_plot(df, parameter, response, theme):
    """Make plotly traces for scatterplot and histograms for selected
    response and input parameter"""

    fig = make_subplots(
        rows=4,
        cols=2,
        specs=[
            [{
                "colspan": 2,
                "rowspan": 2
            }, None],
            [None, None],
            [{
                "rowspan": 2
            }, {
                "rowspan": 2
            }],
            [None, None],
        ],
    )
    scatter_trace, trendline = create_figure(
        plot_type="scatter",
        data_frame=df,
        x=parameter,
        y=response,
        trendline="ols",
        hover_data={
            "REAL": True
        },
        color_discrete_sequence=["SteelBlue"],
        marker={
            "size": 20,
            "opacity": 0.7
        },
    ).data

    fig.add_trace(scatter_trace, 1, 1)
    fig.add_trace(trendline, 1, 1)
    fig.add_trace(
        {
            "type": "histogram",
            "x": df[parameter],
            "showlegend": False,
        },
        3,
        1,
    )
    fig.add_trace(
        {
            "type": "histogram",
            "x": df[response],
            "showlegend": False,
        },
        3,
        2,
    )
    fig["layout"].update(
        theme_layout(
            theme.plotly_theme,
            {
                "bargap": 0.05,
                "xaxis": {
                    "title": parameter,
                },
                "yaxis": {
                    "title": response
                },
                "xaxis2": {
                    "title": parameter
                },
                "xaxis3": {
                    "title": response
                },
                "title": f"Distribution of {response} and {parameter}",
            },
        ))

    return fig