Public
Edited
Jul 18, 2023
Importers
4 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
lineHistogram(accessToTechnology, {
xProperty: 'age',
xAxisLabel: 'Age',
xAxisTicks: histogramXTicks,
step: 1,
colorField: 'sector'
}).width(800).render({renderer: 'svg'})
Insert cell
lineHistogram(accessToTechnology, {
xProperty: 'age',
xAxisLabel: 'Age',
xAxisTicks: histogramXTicks,
step: 1,
colorField: 'gender',
colorScale: {range: ['red', 'steelblue']}
}).width(800).render({renderer: 'svg'})
Insert cell
Insert cell
Insert cell
md`What's the composition of those without access to phone?`

Insert cell
lineHistogram(noPhoneAccess, {
xProperty: 'age', xAxisLabel: 'Age', xAxisTicks: d3.range(10, 100, 5), step: 1, colorField: 'gender', colorScale: {range: ['red', 'steelblue']}
}).width(800).render({renderer: 'svg'})
Insert cell
{
const data = Array.from(d3.group(noPhoneAccess, d => d.state).entries()).map(([state, values]) => ({state, values, size: values.length}))
return vl.markBar()
.data(data)
.encode(
vl.x().fieldN('state'),
vl.y().fieldQ('size')
).render()
}
Insert cell
selectUnder18 = d => d.age <=25
Insert cell
noPhoneAccess = accessToTechnology.filter(d => !hasAccessToPhone(d))
Insert cell
under18NoPhone = noPhoneAccess.filter(selectUnder18)
Insert cell
under18NoPhone.filter(selectFemale).length / under18NoPhone.length
Insert cell
over18NoPhone = noPhoneAccess.filter(d => !selectUnder18(d))
Insert cell
over18NoPhone.filter(selectFemale).length / over18NoPhone.length
Insert cell
noInternetAccess = accessToTechnology.filter( d=> !hasAccessToInternet(d))
Insert cell
lineHistogram(noInternetAccess, {
xProperty: 'age', xAxisLabel: 'Age', xAxisTicks: histogramXTicks, step: 1, colorField: 'gender'
}).width(800).render({renderer: 'svg'})
Insert cell
noPersonalDevice = accessToInternet.filter(d => !d.personalDevice)
Insert cell
lineHistogram(noPersonalDevice, {
xProperty: 'age', xAxisLabel: 'Age', xAxisTicks: histogramXTicks, step: 1, colorField: 'sector'
}).width(800).render({renderer: 'svg'})
Insert cell
lineHistogram(accessToInternet, {
xProperty: 'age', xAxisLabel: 'Age', xAxisTicks: histogramXTicks, step: 1, colorField: 'gender'
}).width(800).render({renderer: 'svg'})
Insert cell
noPhoneAccess.filter(selectMale).length/noPhoneAccess.length
Insert cell
histogram(accessToPhone.filter(selectRural), {
xProperty: 'age', xAxisLabel: 'Age', xAxisTicks: histogramXTicks, step: 1, colorField: 'sector'
}).width(800).render({renderer: 'svg'})
Insert cell
Insert cell
Insert cell
lineHistogram(accessToInternet, {
xProperty: 'age',
xAxisLabel: 'Age',
xAxisTicks: histogramInternetXAxisTicks,
colorField: 'gender',
colorScale: {range: ['red', 'blue']},
step: 1,
}).width(800).render({ renderer: 'svg'})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
const rural = accessToInternet.filter(d => d.cyberCafe && d.sector === 'Rural');
const urban = accessToInternet.filter(d => d.cyberCafe && d.sector === 'Urban');
return vl.hconcat(
histogram(rural, {
xProperty: 'age',
xAxisLabel: 'Age (Rural)',
xAxisTicks: histogramInternetXAxisTicks,
step: 1,
colorField: 'gender'
}),
histogram(urban, {
xProperty: 'age',
xAxisLabel: 'Age (Urban)',
xAxisTicks: histogramInternetXAxisTicks,
step: 1,
colorField: 'gender'
})
)
.render({ renderer: 'svg'})}
Insert cell
Insert cell
md`What percentage of participants from rural/urban areas have access to phones/internet?`
Insert cell
getSectorProportionRow(accessToTechnology, hasAccessToPhone)
Insert cell
getSectorProportionRow(accessToTechnology, hasAccessToInternet)
Insert cell
Insert cell
Insert cell
getSectorProportionTable(hasAccessToPhone)
Insert cell
getSectorProportionTable(hasAccessToInternet)
Insert cell
function getSectorProportionTable(predicate) {
return md`| State | Rural | Urban| Combined | # Rural | # Urban |
|---|---|---|----|-----|
${states.filter(d => d != '').map(state => {
const stateData = accessToTechnology.filter(d => d.state === state)
return `|${state} | ${getSectorProportionRow(stateData, predicate)}|`
}).join('\n')}`
}
Insert cell
renderSectorProportionByState(accessToTechnology, hasAccessToPhone)
Insert cell
renderSectorProportionByState(accessToTechnology, hasAccessToInternet)
Insert cell
renderSectorProportionByState(accessToInternet, selectFemale)
Insert cell
renderSectorProportionByState(accessToPhone, selectFemale)
Insert cell
renderSectorProportionByState(accessToPhone, selectMale)
Insert cell
renderSectorProportionByState(accessToInternet, selectMale)
Insert cell
Insert cell
renderGenderProportionByState(accessToTechnology, hasAccessToPhone)
Insert cell
renderGenderProportionByState(accessToTechnology, hasAccessToInternet)
Insert cell
Insert cell
vl.hconcat(renderGenderProportionByZone(accessToTechnology, hasAccessToPhone),renderGenderProportionByZone(accessToTechnology, hasAccessToInternet)).config({view: {stroke: 'transparent'}}).render({renderer: "svg"})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
getAccessModeTopStates(accessToInternet.filter(d => d.personalDevice))
Insert cell
Insert cell
Insert cell
getAccessModeTopStates(accessToInternet.filter(d => d.publicWifi))
Insert cell
Insert cell
Insert cell
getAccessModeTopStates(accessToInternet.filter(d => d.workplace))
Insert cell
Insert cell
Insert cell
getAccessModeTopStates(accessToInternet.filter(d => d.otherHousehold))
Insert cell
Insert cell
Insert cell
getAccessModeTopStates(accessToInternet.filter(d => d.relativeOrFriend))
Insert cell
Insert cell
Insert cell
getAccessModeTopStates(accessToInternet.filter(d => d.cyberCafe))
Insert cell
Insert cell
function getAccessModeTopStates(data) {
const result = Array.from(d3.group(data, d => d.state).entries()).map(([state, allValues]) => {
const groups = d3.group(allValues, d => d.accessMode);
const modeGroups = Array.from(groups.entries()).map(([key, groupValues]) => ({key, percent: 100 * groupValues.length/allValues.length})).sort((a,b) => b.percent - a.percent)
return {
state,
modeGroups ,
statePercent: 100 * allValues.length / data.length,
size: allValues.length
}}).sort((a, b) => b.size - a.size);
return result;
}
Insert cell
Array.from(getAccessModeForState('Zamfara').entries())
Insert cell
function getAccessModeForState(state) {
return d3.group(accessToInternet.filter(d => d.state === state), d => d.accessMode)
}
Insert cell
function getAccessModeForZone(zone) {
return d3.group(accessToInternet.filter(d => d.zone === zone), d => d.accessMode)
}
Insert cell
getAccessModeForZone('South South')
Insert cell
Insert cell
Insert cell
Insert cell
hasAccessToPhone = d => d.hasAccessToPhone
Insert cell
accessModePredicateMap = ({
"Access to Phone": hasAccessToPhone,
"Access to Internet": hasAccessToInternet,
"Access to Internet (Personal Device)": d => d.personalDevice,
"Access to Internet (Cyber cafe)": d => d.cyberCafe})
Insert cell
Insert cell
hasAccessToInternet = d => d.hasAccessToInternet
Insert cell
Insert cell
Insert cell
mapInternetAccessMode = (d) => {
const res = [];
if ( d.personalDevice === "1") return ('Personal Device')
if (d.otherHousehold === "1") return ("Other Household Device")
if (d.relativeOrFriend === "1") return ('Relative or Friend')
if (d.workplace === "1") return ('Workplace')
if (d.cyberCafe === "1") return ('Cyber Cafe')
if (d.publicWifi === "1") return ('Public Wifi')
if (d.other === "1") return (d.otherSpecified)
return res.join(',')
}
Insert cell
Insert cell
accessToTechnologyAllAges = d3.csvParse( await FileAttachment("access_to_tech.csv").text()).map(d => ({
...d,
age: +d.age,
gender: getGender(d.gender),
state: states[d.state],
sector: sectors[d.sector],
zone: zones[d.zone],
hasAccessToPhone: toBoolean(d.hasAccessToPhone),
phoneAccessModeRaw: d.phoneAccessMode,
phoneAccessMode: mapPhoneAccessMode(d.phoneAccessMode),
hasAccessToInternet: toBoolean(d.hasAccessToInternet),
personalDevice: toBoolean(d.personalDevice),
otherHousehold: toBoolean(d.otherHousehold),
relativeOrFriend: toBoolean(d.relativeOrFriend),
workplace: toBoolean(d.workplace),
cyberCafe: toBoolean(d.cyberCafe),
publicWifi: toBoolean(d.publicWifi),
other: toBoolean(d.other),
accessMode: mapInternetAccessMode(d)
}))
Insert cell
Insert cell
Insert cell
graph = buildSankeyGraph()
Insert cell
color = d3.scaleOrdinal(d3.schemeCategory10)
Insert cell
sankeyFactors = [/*"sector", 'gender','hasAccessToInternet',*/ 'accessMode', 'zone']
Insert cell
Insert cell
accessToInternetFemale.filter(d => d.personalDevice)
Insert cell
Type JavaScript, then Shift-Enter. Ctrl-space for more options. Arrow ↑/↓ to switch modes.

Insert cell
nodeSortOrder = ['sector:Urban', 'sector:Rural','hasAccessToInternet:false', 'hasAccesstoInternet:true', 'gender:Male', 'gender:Female','accessMode:Personal Device', 'accessMode:Other Household Device','accessMode:Relative or Friend', 'accessMode:Cyber Cafe', 'accessMode:Workplace', 'accessMode:Public Wifi', 'accessMode:Unknown']
Insert cell
sankey = d3.sankey()
.nodeSort((a, b) => nodeSortOrder.indexOf(a.name) - nodeSortOrder.indexOf(b.name))
.linkSort((a, b) => nodeSortOrder.indexOf(a.names[a.names.length -1]) - nodeSortOrder.indexOf(b.names[b.names.length -1]))
.nodeWidth(4)
.nodePadding(20)
.nodeAlign(d3.sankeyLeft)
.extent([[0, 5], [width, height - 5]])
Insert cell
height = 500
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
selectFemale = d => d.gender === 'Female'
Insert cell
selectMale = d => d.gender === "Male"
Insert cell
selectUrban = d => d.sector === "Urban"
Insert cell
selectRural = d => d.sector === "Rural"
Insert cell
getHHID = d => d.hhid
Insert cell
Insert cell
getGender = num => num === "1" ? "Male" : num === "2" ? "Female" : "Other"
Insert cell
accessToPhone = accessToTechnology.filter(d => d.hasAccessToPhone)
Insert cell
Insert cell
Insert cell
accessToInternetFemale = accessToInternet.filter(selectFemale)
Insert cell
accessToInternetUrban = accessToInternet.filter(selectUrban)
Insert cell
indivPointCache = {return {}}
Insert cell
toBoolean = d => d === "1" ? true : false
Insert cell
d3 = require("d3@6", "d3-sankey@0.12")
Insert cell
import { statesGeoJSON } from '@thehogfather/nigeria-geojson'
Insert cell
turf = require('@turf/turf')
Insert cell
import {states, sectors, zones, histogram, lineHistogram } from '@thehogfather/nigeria-household-survey-wave4'
Insert cell
import {vl} from '@vega/vega-lite-api'
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more