예제 #1
0
    def _validate(self, value):
        if not self._validator:
            from plotly.validators.layout import TemplateValidator

            self._validator = TemplateValidator()

        return self._validator.validate_coerce(value)
예제 #2
0
    def __init__(self):

        # Initialize properties dict
        self._templates = {}

        # Initialize built-in templates
        default_templates = [
            'ggplot2', 'seaborn', 'plotly', 'plotly_white', 'plotly_dark',
            'presentation', 'xgridoff'
        ]

        for template_name in default_templates:
            self._templates[template_name] = Lazy

        self._validator = TemplateValidator()
        self._default = None
예제 #3
0
    def __init__(self):

        # Initialize properties dict
        self._templates = {}

        # Initialize built-in templates
        default_templates = ['ggplot2', 'seaborn',
                             'plotly', 'plotly_white',
                             'plotly_dark', 'presentation', 'xgridoff']

        for template_name in default_templates:
            self._templates[template_name] = Lazy

        self._validator = TemplateValidator()
        self._default = None
예제 #4
0
class TemplatesConfig(object):
    """
    Singleton object containing the current figure templates (aka themes)
    """
    def __init__(self):

        # Initialize properties dict
        self._templates = {}

        # Initialize built-in templates
        default_templates = [
            "ggplot2",
            "seaborn",
            "simple_white",
            "plotly",
            "plotly_white",
            "plotly_dark",
            "presentation",
            "xgridoff",
            "ygridoff",
            "gridon",
            "none",
        ]

        for template_name in default_templates:
            self._templates[template_name] = Lazy

        self._validator = None
        self._default = None

    # ### Magic methods ###
    # Make this act as a dict of templates
    def __len__(self):
        return len(self._templates)

    def __contains__(self, item):
        return item in self._templates

    def __iter__(self):
        return iter(self._templates)

    def __getitem__(self, item):
        if isinstance(item, string_types):
            template_names = item.split("+")
        else:
            template_names = [item]

        templates = []
        for template_name in template_names:
            template = self._templates[template_name]
            if template is Lazy:
                from plotly.graph_objs.layout import Template

                if template_name == "none":
                    # "none" is a special built-in named template that applied no defaults
                    template = Template(data_scatter=[{}])
                    self._templates[template_name] = template
                else:
                    # Load template from package data
                    path = os.path.join("package_data", "templates",
                                        template_name + ".json")
                    template_str = pkgutil.get_data("plotly",
                                                    path).decode("utf-8")
                    template_dict = json.loads(template_str)
                    template = Template(template_dict)

                    self._templates[template_name] = template
            templates.append(self._templates[template_name])

        return self.merge_templates(*templates)

    def __setitem__(self, key, value):
        self._templates[key] = self._validate(value)

    def __delitem__(self, key):
        # Remove template
        del self._templates[key]

        # Check if we need to remove it as the default
        if self._default == key:
            self._default = None

    def _validate(self, value):
        if not self._validator:
            from plotly.validators.layout import TemplateValidator

            self._validator = TemplateValidator()

        return self._validator.validate_coerce(value)

    def keys(self):
        return self._templates.keys()

    def items(self):
        return self._templates.items()

    def update(self, d={}, **kwargs):
        """
        Update one or more templates from a dict or from input keyword
        arguments.

        Parameters
        ----------
        d: dict
            Dictionary from template names to new template values.

        kwargs
            Named argument value pairs where the name is a template name
            and the value is a new template value.
        """
        for k, v in dict(d, **kwargs).items():
            self[k] = v

    # ### Properties ###
    @property
    def default(self):
        """
        The name of the default template, or None if no there is no default

        If not None, the default template is automatically applied to all
        figures during figure construction if no explicit template is
        specified.

        The names of available templates may be retrieved with:

        >>> import plotly.io as pio
        >>> list(pio.templates)

        Returns
        -------
        str
        """
        return self._default

    @default.setter
    def default(self, value):

        # Validate value
        # Could be a Template object, the key of a registered template,
        # Or a string containing the names of multiple templates joined on
        # '+' characters
        self._validate(value)
        self._default = value

    def __repr__(self):
        return """\
Templates configuration
-----------------------
    Default template: {default}
    Available templates:
{available}
""".format(default=repr(self.default),
           available=self._available_templates_str())

    def _available_templates_str(self):
        """
        Return nicely wrapped string representation of all
        available template names
        """
        available = "\n".join(
            textwrap.wrap(
                repr(list(self)),
                width=79 - 8,
                initial_indent=" " * 8,
                subsequent_indent=" " * 9,
            ))
        return available

    def merge_templates(self, *args):
        """
        Merge a collection of templates into a single combined template.
        Templates are process from left to right so if multiple templates
        specify the same propery, the right-most template will take
        precedence.

        Parameters
        ----------
        args: list of Template
            Zero or more template objects (or dicts with compatible properties)

        Returns
        -------
        template:
            A combined template object

        Examples
        --------

        >>> pio.templates.merge_templates(
        ...     go.layout.Template(layout={'font': {'size': 20}}),
        ...     go.layout.Template(data={'scatter': [{'mode': 'markers'}]}),
        ...     go.layout.Template(layout={'font': {'family': 'Courier'}}))
        layout.Template({
            'data': {'scatter': [{'mode': 'markers', 'type': 'scatter'}]},
            'layout': {'font': {'family': 'Courier', 'size': 20}}
        })
        """
        if args:
            return reduce(self._merge_2_templates, args)
        else:
            from plotly.graph_objs.layout import Template

            return Template()

    def _merge_2_templates(self, template1, template2):
        """
        Helper function for merge_templates that merges exactly two templates

        Parameters
        ----------
        template1: Template
        template2: Template

        Returns
        -------
        Template:
            merged template
        """
        # Validate/copy input templates
        result = self._validate(template1)
        other = self._validate(template2)

        # Cycle traces
        for trace_type in result.data:
            result_traces = result.data[trace_type]
            other_traces = other.data[trace_type]

            if result_traces and other_traces:
                lcm = (len(result_traces) * len(other_traces) //
                       gcd(len(result_traces), len(other_traces)))

                # Cycle result traces
                result.data[trace_type] = result_traces * (lcm //
                                                           len(result_traces))

                # Cycle other traces
                other.data[trace_type] = other_traces * (lcm //
                                                         len(other_traces))

        # Perform update
        result.update(other)

        return result
예제 #5
0
class TemplatesConfig(object):
    """
    Singleton object containing the current figure templates (aka themes)
    """
    def __init__(self):

        # Initialize properties dict
        self._templates = {}

        # Initialize built-in templates
        default_templates = ['ggplot2', 'seaborn',
                             'plotly', 'plotly_white',
                             'plotly_dark', 'presentation', 'xgridoff']

        for template_name in default_templates:
            self._templates[template_name] = Lazy

        self._validator = TemplateValidator()
        self._default = None

    # ### Magic methods ###
    # Make this act as a dict of templates
    def __len__(self):
        return len(self._templates)

    def __contains__(self, item):
        return item in self._templates

    def __iter__(self):
        return iter(self._templates)

    def __getitem__(self, item):
        template = self._templates[item]
        if template is Lazy:
            # Load template from package data
            path = os.path.join('package_data', 'templates', item + '.json')
            template_str = pkgutil.get_data('plotly', path).decode('utf-8')
            template_dict = json.loads(template_str)
            template = Template(template_dict)
            self._templates[item] = template

        return template

    def __setitem__(self, key, value):
        self._templates[key] = self._validator.validate_coerce(value)

    def __delitem__(self, key):
        # Remove template
        del self._templates[key]

        # Check if we need to remove it as the default
        if self._default == key:
            self._default = None

    def keys(self):
        return self._templates.keys()

    def items(self):
        return self._templates.items()

    def update(self, d={}, **kwargs):
        """
        Update one or more templates from a dict or from input keyword
        arguments.

        Parameters
        ----------
        d: dict
            Dictionary from template names to new template values.

        kwargs
            Named argument value pairs where the name is a template name
            and the value is a new template value.
        """
        for k, v in dict(d, **kwargs).items():
            self[k] = v

    # ### Properties ###
    @property
    def default(self):
        """
        The name of the default template, or None if no there is no default

        If not None, the default template is automatically applied to all
        figures during figure construction if no explicit template is
        specified.

        The names of available templates may be retrieved with:

        >>> import plotly.io as pio
        >>> list(pio.templates)

        Returns
        -------
        str
        """
        return self._default

    @default.setter
    def default(self, value):

        # Validate value
        # Could be a Template object, the key of a registered template,
        # Or a string containing the names of multiple templates joined on
        # '+' characters
        self._validator.validate_coerce(value)
        self._default = value

    def __repr__(self):
        return """\
Templates configuration
-----------------------
    Default template: {default}
    Available templates:
{available}
""".format(default=repr(self.default),
           available=self._available_templates_str())

    def _available_templates_str(self):
        """
        Return nicely wrapped string representation of all
        available template names
        """
        available = '\n'.join(textwrap.wrap(
            repr(list(self)),
            width=79 - 8,
            initial_indent=' ' * 8,
            subsequent_indent=' ' * 9
        ))
        return available

    def merge_templates(self, *args):
        """
        Merge a collection of templates into a single combined template.
        Templates are process from left to right so if multiple templates
        specify the same propery, the right-most template will take
        precedence.

        Parameters
        ----------
        args: list of Template
            Zero or more template objects (or dicts with compatible properties)

        Returns
        -------
        template:
            A combined template object

        Examples
        --------
        >>> pio.templates.merge_templates(
        ...     go.layout.Template(layout={'font': {'size': 20}}),
        ...     go.layout.Template(data={'scatter': [{'mode': 'markers'}]}),
        ...     go.layout.Template(layout={'font': {'family': 'Courier'}}))
        layout.Template({
            'data': {'scatter': [{'mode': 'markers', 'type': 'scatter'}]},
            'layout': {'font': {'family': 'Courier', 'size': 20}}
        })
        """
        if args:
            return reduce(self._merge_2_templates, args)
        else:
            return Template()

    def _merge_2_templates(self, template1, template2):
        """
        Helper function for merge_templates that merges exactly two templates

        Parameters
        ----------
        template1: Template
        template2: Template

        Returns
        -------
        Template:
            merged template
        """
        # Validate/copy input templates
        result = self._validator.validate_coerce(template1)
        other = self._validator.validate_coerce(template2)

        # Cycle traces
        for trace_type in result.data:
            result_traces = result.data[trace_type]
            other_traces = other.data[trace_type]

            if result_traces and other_traces:
                lcm = (len(result_traces) * len(other_traces) //
                       gcd(len(result_traces), len(other_traces)))

                # Cycle result traces
                result.data[trace_type] = result_traces * (
                        lcm // len(result_traces))

                # Cycle other traces
                other.data[trace_type] = other_traces * (
                    lcm // len(other_traces))

        # Perform update
        result.update(other)

        return result
예제 #6
0
    def _validate(self, value):
        if not self._validator:
            from plotly.validators.layout import TemplateValidator
            self._validator = TemplateValidator()

        return self._validator.validate_coerce(value)