A barebones generator for Socr Motion Charts - SOCR HTML5 Motion Chart.
Useful data sources include the World Bank, UN Population Division and the UN Data website.
pandas has inbuilt support for the World Bank indicators API (remote data access), and I have popped a couple of hacky scrapers together for getting data into pandas dataframes from:
socrTemplate='''<!DOCTYPE html>
<html>
<head>
<!-- Meta Needed to force IE out of Quirks mode -->
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<!--StyleSheets-->
<link href="css/bootstrap/bootstrap.min.css" rel="stylesheet">
<link href="css/jquery-ui-1.8.20.custom.css" rel="stylesheet">
<link href="css/jquery.handsontable.css" rel="stylesheet">
<link href="css/jquery.motionchart.css" rel="stylesheet">
<link href="css/jquery.contextMenu.css" rel="stylesheet">
<!--Scripts-->
<script src="js/jquery-1.7.2.min.js"></script>
<script src="js/dependencies.min.js"></script>
<script src="js/custom-bootstrap.js"></script>
<script src="js/jquery.handsontable.js"></script>
<script src="js/jquery.motionchart.js"></script>
</head>
<body>
<div class="motionchart" style="width:1000px; height:600px;"></div>
<script src="data/{stub}_data.js"></script>
<!-- <script src="data/{stub}_config.js"></script> -->
<script>
$('.motionchart').motionchart({{
title: '{title}',
'data': data,
mappings: {{
key: {key},
x: {x},
y: {y},
size: {size},
color: {color},
category: {category} }},
scalings: {{ x: '{xscale}', y: '{yscale}' }},
colorPalette: {{"Blue-Red": {{from: "rgb(0,0,255)", to: "rgb(255,0,0)"}}}},
color: "Red-Blue",
play: false,
loop: false
}});
</script>
</body>
</html>
'''
import pandas as pd
import json
#TO DO - option for square axes, or axis limits?
def socrdata(df,STUB,title,key,x,y,size,color,category,xscale='linear',yscale='linear'):
PATH='./'
txtlist=[df.columns.tolist()]
for row in df.iterrows():
txtlist.append(row[1].tolist())
with open(PATH+"data/"+STUB+"_data.js", "w") as f:
f.write('var data='+json.dumps(txtlist, indent=4,sort_keys=True))
cols=df.columns
with open(PATH+STUB+".html", "w") as f:
f.write(socrTemplate.format(
stub=STUB,title=title,
key=df.columns.get_loc(key),
x=df.columns.get_loc(x),
y=df.columns.get_loc(y),
size=df.columns.get_loc(size),
color=df.columns.get_loc(color),
category=df.columns.get_loc(category),
xscale=xscale, yscale=yscale
))
!head -n 5 ../../bahrainPop.csv
dfb=pd.read_csv('../../bahrainPop.csv',skip_footer=2)
tmp=dfb[['Year','Age','Sex','Value']].set_index(['Year','Age','Sex']).unstack("Sex").reset_index()
tmp.columns = [' '.join(col).strip() for col in tmp.columns.values]
tmp[:4]
Year | Age | Value Female | Value Male | Value Total | |
---|---|---|---|---|---|
0 | 1950 | 0-4 | 10 | 10 | 20 |
1 | 1950 | 10-14 | 6 | 7 | 13 |
2 | 1950 | 15-19 | 5 | 6 | 11 |
3 | 1950 | 20-24 | 5 | 6 | 11 |
socrdata(tmp[(~tmp['Age'].isin([' 5-9', ' 10-14', ' 15-19', ' 20-24',' 35-39', ' 40-44', ' 45-49', ' 50-54', ' 55-59', ' 60-64',
' 65-69', ' 70-74', ' 75-79', ' 80+', ' 80-84', ' 85-89', ' 90-94',
' 95-99', ' 100+'])) & (tmp['Year']<2020) ],
'bahrainPopx','Bahrain','Year','Value Female','Value Male','Value Total','Age','Age')
!ls
README.md bangladeshPopx.html js SocrMotionChart Configurator.ipynb bigtest.html license _index.html css wiki.documentation.txt bangladeshPop.html data