Exemple #1
0
def test_examples(filename):
    source = pkgutil.get_data(examples.__name__, filename)
    chart = eval_block(source)

    if chart is None:
        raise ValueError("Example file should define chart in its final "
                         "statement.")
    chart.to_dict()
Exemple #2
0
def test_examples(filename):
    with open(join(EXAMPLE_DIR, filename)) as f:
        source = f.read()

    chart = eval_block(source)

    if chart is None:
        raise ValueError("Example file should define chart in its final "
                         "statement.")
    dct = chart.to_dict()
Exemple #3
0
def save_example_pngs(examples, image_dir, make_thumbnails=True):
    """Save example pngs and (optionally) thumbnails"""
    if not os.path.exists(image_dir):
        os.makedirs(image_dir)

    # store hashes so that we know whether images need to be generated
    hash_file = os.path.join(image_dir, '_image_hashes.json')

    if os.path.exists(hash_file):
        with open(hash_file) as f:
            hashes = json.load(f)
    else:
        hashes = {}

    for example in examples:
        filename = example['name'] + '.png'
        image_file = os.path.join(image_dir, filename)

        example_hash = hashlib.md5(example['code'].encode()).hexdigest()
        hashes_match = (hashes.get(filename, '') == example_hash)

        if hashes_match and os.path.exists(image_file):
            print('-> using cached {}'.format(image_file))
        else:
            # the file changed or the image file does not exist. Generate it.
            print('-> saving {}'.format(image_file))
            chart = eval_block(example['code'])
            try:
                chart.save(image_file)
                hashes[filename] = example_hash
            except ImportError:
                warnings.warn("Could not import selenium: using generic image")
                create_generic_image(image_file)

            with open(hash_file, 'w') as f:
                json.dump(hashes, f)

        if make_thumbnails:
            params = example.get('galleryParameters', {})
            thumb_file = os.path.join(image_dir,
                                      example['name'] + '-thumb.png')
            create_thumbnail(image_file, thumb_file, **params)

    # Save hashes so we know whether we need to re-generate plots
    with open(hash_file, 'w') as f:
        json.dump(hashes, f)
Exemple #4
0
def save_example_pngs(examples, image_dir, make_thumbnails=True):
    """Save example pngs and (optionally) thumbnails"""
    if not os.path.exists(image_dir):
        os.makedirs(image_dir)

    # store hashes so that we know whether images need to be generated
    hash_file = os.path.join(image_dir, '_image_hashes.json')

    if os.path.exists(hash_file):
        with open(hash_file) as f:
            hashes = json.load(f)
    else:
        hashes = {}

    for example in examples:
        filename = example['name'] + '.png'
        image_file = os.path.join(image_dir, filename)

        example_hash = hashlib.md5(example['code'].encode()).hexdigest()
        hashes_match = (hashes.get(filename, '') == example_hash)

        if hashes_match and os.path.exists(image_file):
            print('-> using cached {}'.format(image_file))
        else:
            # the file changed or the image file does not exist. Generate it.
            print('-> saving {}'.format(image_file))
            chart = eval_block(example['code'])
            try:
                chart.save(image_file)
                hashes[filename] = example_hash
            except ImportError:
                warnings.warn("Could not import selenium: using generic image")
                create_generic_image(image_file)

            with open(hash_file, 'w') as f:
                json.dump(hashes, f)

        if make_thumbnails:
            params = example.get('galleryParameters', {})
            thumb_file = os.path.join(image_dir, example['name'] + '-thumb.png')
            create_thumbnail(image_file, thumb_file, **params)

    # Save hashes so we know whether we need to re-generate plots
    with open(hash_file, 'w') as f:
        json.dump(hashes, f)
Exemple #5
0
def html_visit_altair_plot(self, node):
    # Execute the code, saving output and namespace
    namespace = node["namespace"]
    try:
        f = io.StringIO()
        with contextlib.redirect_stdout(f):
            chart = eval_block(node["code"], namespace)
        stdout = f.getvalue()
    except Exception as e:
        message = "altair-plot: {}:{} Code Execution failed:" "{}: {}".format(
            node["rst_source"], node["rst_lineno"], e.__class__.__name__, str(e)
        )
        if node["strict"]:
            raise ValueError(message) from e
        else:
            warnings.warn(message)
            raise nodes.SkipNode

    chart_name = node["chart-var-name"]
    if chart_name is not None:
        if chart_name not in namespace:
            raise ValueError(
                "chart-var-name='{}' not present in namespace" "".format(chart_name)
            )
        chart = namespace[chart_name]

    output = node["output"]

    if output == "none":
        raise nodes.SkipNode
    elif output == "stdout":
        if not stdout:
            raise nodes.SkipNode
        else:
            output_literal = nodes.literal_block(stdout, stdout)
            output_literal["language"] = "none"
            node.extend([output_literal])
    elif output == "repr":
        if chart is None:
            raise nodes.SkipNode
        else:
            rep = "    " + repr(chart).replace("\n", "\n    ")
            repr_literal = nodes.literal_block(rep, rep)
            repr_literal["language"] = "none"
            node.extend([repr_literal])
    elif output == "plot":
        if isinstance(chart, alt.TopLevelMixin):
            # Last line should be a chart; convert to spec dict
            try:
                spec = chart.to_dict()
            except alt.utils.schemapi.SchemaValidationError:
                raise ValueError("Invalid chart: {0}".format(node["code"]))
            actions = node["links"]

            # TODO: add an option to save spects to file & load from there.
            # TODO: add renderer option

            # Write spec to a *.vl.json file
            # dest_dir = os.path.join(self.builder.outdir, node['relpath'])
            # if not os.path.exists(dest_dir):
            #     os.makedirs(dest_dir)
            # filename = "{0}.vl.json".format(node['target_id'])
            # dest_path = os.path.join(dest_dir, filename)
            # with open(dest_path, 'w') as f:
            #     json.dump(spec, f)

            # Pass relevant info into the template and append to the output
            html = VGL_TEMPLATE.render(
                div_id=node["div_id"],
                spec=json.dumps(spec),
                mode="vega-lite",
                renderer="canvas",
                actions=json.dumps(actions),
            )
            self.body.append(html)
        else:
            warnings.warn(
                "altair-plot: {}:{} Malformed block. Last line of "
                "code block should define a valid altair Chart object."
                "".format(node["rst_source"], node["rst_lineno"])
            )
        raise nodes.SkipNode
Exemple #6
0
def html_visit_altair_plot(self, node):
    # Execute the code, saving output and namespace
    namespace = node['namespace']
    try:
        f = io.StringIO()
        with contextlib.redirect_stdout(f):
            chart = eval_block(node['code'], namespace)
        stdout = f.getvalue()
    except Exception as e:
        warnings.warn("altair-plot: {0}:{1} Code Execution failed:"
                      "{2}: {3}".format(node['rst_source'], node['rst_lineno'],
                                        e.__class__.__name__, str(e)))
        raise nodes.SkipNode

    chart_name = node['chart-var-name']
    if chart_name is not None:
        if chart_name not in namespace:
            raise ValueError("chart-var-name='{0}' not present in namespace"
                             "".format(chart_name))
        chart = namespace[chart_name]

    output = node['output']

    if output == 'none':
        raise nodes.SkipNode
    elif output == 'stdout':
        if not stdout:
            raise nodes.SkipNode
        else:
            output_literal = nodes.literal_block(stdout, stdout)
            output_literal['language'] = 'none'
            node.extend([output_literal])
    elif output == 'repr':
        if chart is None:
            raise nodes.SkipNode
        else:
            rep = '    ' + repr(chart).replace('\n', '\n    ')
            repr_literal = nodes.literal_block(rep, rep)
            repr_literal['language'] = 'none'
            node.extend([repr_literal])
    elif output == 'plot':
        if isinstance(chart, alt.TopLevelMixin):
            # Last line should be a chart; convert to spec dict
            spec = chart.to_dict()
            actions = node['links']

            # TODO: add an option to save spects to file & load from there.
            # TODO: add renderer option

            # Write spec to a *.vl.json file
            # dest_dir = os.path.join(self.builder.outdir, node['relpath'])
            # if not os.path.exists(dest_dir):
            #     os.makedirs(dest_dir)
            # filename = "{0}.vl.json".format(node['target_id'])
            # dest_path = os.path.join(dest_dir, filename)
            # with open(dest_path, 'w') as f:
            #     json.dump(spec, f)

            # Pass relevant info into the template and append to the output
            html = VGL_TEMPLATE.render(div_id=node['div_id'],
                                       spec=json.dumps(spec),
                                       mode='vega-lite',
                                       renderer='canvas',
                                       actions=json.dumps(actions))
            self.body.append(html)
        else:
            warnings.warn(
                'altair-plot: {0}:{1} Malformed block. Last line of '
                'code block should define a valid altair Chart object.'
                ''.format(node['rst_source'], node['rst_lineno']))
        raise nodes.SkipNode
Exemple #7
0
def test_render_examples_to_png(filename):
    source = pkgutil.get_data(examples.__name__, filename)
    chart = eval_block(source)
    out = io.BytesIO()
    chart.save(out, format="png")
    assert out.getvalue().startswith(b'\x89PNG')
Exemple #8
0
def html_visit_altair_plot(self, node):
    # Execute the code, saving output and namespace
    namespace = node['namespace']
    try:
        f = io.StringIO()
        with contextlib.redirect_stdout(f):
            chart = eval_block(node['code'], namespace)
        stdout = f.getvalue()
    except Exception as e:
        warnings.warn("altair-plot: {}:{} Code Execution failed:"
                      "{}: {}".format(node['rst_source'], node['rst_lineno'],
                                        e.__class__.__name__, str(e)))
        raise nodes.SkipNode

    chart_name = node['chart-var-name']
    if chart_name is not None:
        if chart_name not in namespace:
            raise ValueError("chart-var-name='{}' not present in namespace"
                             "".format(chart_name))
        chart = namespace[chart_name]


    output = node['output']

    if output == 'none':
        raise nodes.SkipNode
    elif output == 'stdout':
        if not stdout:
            raise nodes.SkipNode
        else:
            output_literal = nodes.literal_block(stdout, stdout)
            output_literal['language'] = 'none'
            node.extend([output_literal])
    elif output == 'repr':
        if chart is None:
            raise nodes.SkipNode
        else:
            rep = '    ' + repr(chart).replace('\n', '\n    ')
            repr_literal = nodes.literal_block(rep, rep)
            repr_literal['language'] = 'none'
            node.extend([repr_literal])
    elif output == 'plot':
        if isinstance(chart, alt.TopLevelMixin):
            # Last line should be a chart; convert to spec dict
            spec = chart.to_dict()
            actions = node['links']

            # TODO: add an option to save spects to file & load from there.
            # TODO: add renderer option

            # Write spec to a *.vl.json file
            # dest_dir = os.path.join(self.builder.outdir, node['relpath'])
            # if not os.path.exists(dest_dir):
            #     os.makedirs(dest_dir)
            # filename = "{0}.vl.json".format(node['target_id'])
            # dest_path = os.path.join(dest_dir, filename)
            # with open(dest_path, 'w') as f:
            #     json.dump(spec, f)

            # Pass relevant info into the template and append to the output
            html = VGL_TEMPLATE.render(div_id=node['div_id'],
                                       spec=json.dumps(spec),
                                       mode='vega-lite',
                                       renderer='canvas',
                                       actions=json.dumps(actions))
            self.body.append(html)
        else:
            warnings.warn('altair-plot: {}:{} Malformed block. Last line of '
                          'code block should define a valid altair Chart object.'
                          ''.format(node['rst_source'], node['rst_lineno']))
        raise nodes.SkipNode