<commit_before>import numpy as np
import warnings
from . import colors
from ..utils import ordinal_str
import random
import string
import json
try:
    from IPython.core.display import display as ipython_display, HTML
    have_ipython = True
except ImportError:
    have_ipython = False


# TODO: we should support text output explanations (from models that output text not numbers), this would require the force
# the force plot and the coloring to update based on mouseovers (or clicks to make it fixed) of the output text
def text(shap_values, num_starting_labels=0, grouping_threshold=0.01, separator='', xmin=None, xmax=None, cmax=None, display=True):
    """ Plots an explanation of a string of text using coloring and interactive labels.

    The output is interactive HTML and you can click on any token to toggle the display of the
    SHAP value assigned to that token.

    Parameters
    ----------
    shap_values : [numpy.array]
        List of arrays of SHAP values. Each array has the shap values for a string(# input_tokens x output_tokens).

    num_starting_labels : int
        Number of tokens (sorted in decending order by corresponding SHAP values) that are uncovered in the initial view. When set to 0 all tokens
        covered. 

    grouping_threshold : float
        If the component substring effects are less than a grouping_threshold fraction of an unlowered interaction effect then we
        visualize the entire group as a single chunk. This is primarily used for explanations that were computed with fixed_context set to 1 or 0
        when using the Partition explainer, since this causes interaction effects to be left on internal nodes rather than lowered.

    separator : string
        The string seperator that joins tokens grouped by interation effects and unbroken string spans.

    xmin : float
        Minimum shap value bound. 

    xmax : float
        Maximum shap value bound.

    cmax : float
        Maximum absolute shap value for sample. Used for scaling colors for input tokens.
    
    display: bool
        Whether to display or return html to further manipulate or embed. default: True

    """

    def values_min_max(values, base_values):
        """ Used to pick our axis limits.
        """
        fx = base_values + values.sum()
        xmin = fx - values[values > 0].sum()
        xmax = fx - values[values < 0].sum()
        cmax = max(abs(values.min()), abs(values.max()))
        d = xmax - xmin
        xmin -= 0.1 * d
        xmax += 0.1 * d

        return xmin, xmax, cmax

    uuid = ''.join(random.choices(string.ascii_lowercase, k=20))

    # loop when we get multi-row inputs
    if len(shap_values.shape) == 2 and (shap_values.output_names is None or isinstance(shap_values.output_names, str)):
        xmin = 0
        xmax = 0
        cmax = 0

        for i, v in enumerate(shap_values):
            values, clustering = unpack_shap_explanation_contents(v)<commit_msg>Update _text.py<commit_after>import numpy as np
import warnings
from . import colors
from ..utils import ordinal_str
import random
import string
import json
try:
    from IPython.core.display import display as ipython_display, HTML
    have_ipython = True
except ImportError:
    have_ipython = False


# TODO: we should support text output explanations (from models that output text not numbers), this would require the force
# the force plot and the coloring to update based on mouseovers (or clicks to make it fixed) of the output text
def text(shap_values, num_starting_labels=0, grouping_threshold=0.01, separator='', xmin=None, xmax=None, cmax=None, display=True):
    """ Plots an explanation of a string of text using coloring and interactive labels.

    The output is interactive HTML and you can click on any token to toggle the display of the
    SHAP value assigned to that token.

    Parameters
    ----------
    shap_values : [numpy.array]
        List of arrays of SHAP values. Each array has the shap values for a string(# input_tokens x output_tokens).

    num_starting_labels : int
        Number of tokens (sorted in decending order by corresponding SHAP values) that are uncovered in the initial view. When set to 0 all tokens
        covered. 

    grouping_threshold : float
        If the component substring effects are less than a grouping_threshold fraction of an unlowered interaction effect then we
        visualize the entire group as a single chunk. This is primarily used for explanations that were computed with fixed_context set to 1 or 0
        when using the Partition explainer, since this causes interaction effects to be left on internal nodes rather than lowered.

    separator : string
        The string seperator that joins tokens grouped by interation effects and unbroken string spans.

    xmin : float
        Minimum shap value bound. 

    xmax : float
        Maximum shap value bound.

    cmax : float
        Maximum absolute shap value for sample. Used for scaling colors for input tokens.
    
    display: bool
        Whether to display or return html to further manipulate or embed. default: True

    """

    def values_min_max(values, base_values):
        """ Used to pick our axis limits.
        """
        values = np.array(values)
        fx = base_values + values.sum()
        xmin = fx - values[values > 0].sum()
        xmax = fx - values[values < 0].sum()
        cmax = max(abs(values.min()), abs(values.max()))
        d = xmax - xmin
        xmin -= 0.1 * d
        xmax += 0.1 * d

        return xmin, xmax, cmax

    uuid = ''.join(random.choices(string.ascii_lowercase, k=20))

    # loop when we get multi-row inputs
    if len(shap_values.shape) == 2 and (shap_values.output_names is None or isinstance(shap_values.output_names, str)):
        xmin = 0
        xmax = 0
        cmax = 0

        for i, v in enumerate(shap_values):
            values, clustering = unpack_shap_explanation_contents(v)
{'fraction_non_alphanumeric': 0.0631525766251263, 'fraction_numerical': 0.006399461098012799, 'mean_word_length': 2.84899546338302, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '766521', 'n_tokens_mistral': 1677, 'n_tokens_neox': 1555, 'n_words': 716}