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()
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()
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)
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
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
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')
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