Skip to content

Instantly share code, notes, and snippets.

@brendano
Last active November 14, 2017 22:12
Show Gist options
  • Save brendano/2de018cdbbf850ca181d0bc1ed63aee2 to your computer and use it in GitHub Desktop.
Save brendano/2de018cdbbf850ca181d0bc1ed63aee2 to your computer and use it in GitHub Desktop.
gplots.py
"""
Make plots with the "Google Image Charts" API.
The functions here return a URL. That URL will then throw a PNG back at you.
So embed them in <img src=...> or whatever.
This uses the "Google Image Charts API," formerly known as "Google Charts API",
which is officially deprecated and has been since 2012, I guess:
https://en.wikipedia.org/wiki/Google_Chart_API
https://developers.google.com/chart/image/
So look out I guess. But it is a MUCH better quick-and-simple API than their
complicated javascript thing they say you should now use. I like to use it to
embed plots inside static HTML when doing data analysis, especially if I need
to make hundreds of plots all on a page together.
This script uses the python 'GChartWrapper' package, but only for a utility
function. That library does lots of other stuff too.
Last checked: 2017-11-14 it seemed to work:
>>> import gplots
>>> print gplots.barplot([3,3,4,4,4,5,8,3,3,3,4])
http://chart.apis.google.com/chart?chd=e:TlTlaHaHaHgp0PTlTlTlaH&chxt=x,y&chxs=0,676767,11.5,0,lt,676767&chxr=0,0,11|1,0,9.8&chbh=15,1&chs=300x100&cht=bvs&chma=30
"""
from __future__ import division
import math,os
## Google chart library
import GChartWrapper
def extended_encoding(vals, lower, upper, encoding):
encoder = GChartWrapper.encoding.codeset[encoding]
def scale(x):
if not (lower <= x <= upper):
return None
N = encoder['max_value'] + 1 ## um not sure about the +1
scale_on_01 = (x-lower) / (upper - lower)
scaled = math.floor(scale_on_01 * N)
scaled = min(scaled, encoder['max_value'])
assert 0 <= scaled <= encoder['max_value']
return scaled
vals_scaled = [scale(x) for x in vals]
vals_encoded = [encoder['value'](x) if x is not None else encoder['none'] for x in vals_scaled]
return ''.join(vals_encoded)
def barplot(ys1, xmax=None, ymin=0, ymax=None, width=300, height=100, time_labels=None):
ymax = max(ys1)*1.1 + 1 if ymax is None else ymax
params = {}
params['chs'] = '{width}x{height}'.format(**locals())
params['cht'] = 'bvs'
params['chd'] = 'e:' + extended_encoding(ys1, ymin, ymax, 'extended')
params['chbh'] = '15,1'
# axes and stuff
params['chxt'] = 'x,y'
# x-axis
xmax = len(ys1) if xmax is None else xmax
params['chxr'] = '0,0,{xmax}'.format(**locals())
#if time_labels: params['chxl'] = '0:|' + '|'.join(code for num,code in time_labels)
if time_labels: params['chxl'] = '0:|' + '|'.join(time_labels)
params['chxs'] = '0,676767,11.5,0,lt,676767' # tick marks
# y-axis
params['chxr'] += '|1,{ymin},{ymax}'.format(**locals())
params['chma'] = 30
# url
items = [('chd',params['chd'])]
del params['chd']
items += params.items()
return 'http://chart.apis.google.com/chart?' + '&'.join('%s=%s' % kv for kv in items)
def barplot2(ys1, xmax=None, ymin=0, ymax=None, width=300, height=100, time_labels=None, **kwargs):
ymax = max(ys1)*1.1 + 1 if ymax is None else ymax
params = {}
params['chs'] = '{width}x{height}'.format(**locals())
params['cht'] = 'bvs'
params['chd'] = 'e:' + extended_encoding(ys1, ymin, ymax, 'extended')
params['chbh'] = '15,1'
# axes and stuff
params['chxt'] = 'x'
# x-axis
xmax = len(ys1) if xmax is None else xmax
params['chxr'] = '0,0,{xmax}'.format(**locals())
#if time_labels: params['chxl'] = '0:|' + '|'.join(code for num,code in time_labels)
if time_labels: params['chxl'] = '0:|' + '|'.join(time_labels)
params['chxs'] = '0,676767,11.5,0,lt,676767' # tick marks
# y-axis
params['chxr'] += '|1,{ymin},{ymax}'.format(**locals())
#params['chma'] = 30
params.update(kwargs)
# url
items = [('chd',params['chd'])]
del params['chd']
items += params.items()
return 'http://chart.apis.google.com/chart?' + '&'.join('%s=%s' % kv for kv in items)
def circle(diameter=50):
diameter = int(diameter)
return """
<div style="
display: block;
width: {diameter}px;
height: {diameter}px;
background: #333;
-moz-border-radius: 40px;
-webkit-border-radius: 40px;
"></div>
""".format(**locals()).replace("\n"," ").strip()
## jquery sparklines library
def get_js(outputfile):
global __file__
here = os.path.abspath(os.path.dirname(__file__))
there= os.path.abspath(os.path.dirname(outputfile))
os.system("cp {here}/sparks/*.js {there}".format(**locals()))
def spark_js():
""" header stuff for js using jquery-sparklines """
return """
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="jquery.sparkline.min.js"></script>
<script type="text/javascript">
$(function() {
$('.barplot').sparkline('html', {enableTagOptions:true, type:'bar'});
});
</script>
"""
def spark(klass, data, **opts):
bads = [k for k in opts if not k.startswith('spark')]
for k in bads:
opts['spark'+k[0].upper() + k[1:]] = opts[k]
del opts[k]
opts['class'] = klass
opts_h = ' '.join('{}="{}"'.format(k,v) for k,v in opts.items())
data_h = ','.join(str(x) for x in data)
return "<span {}>{}</span>".format(opts_h, data_h)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment