Skip to content

Instantly share code, notes, and snippets.

@josiahdavis
Last active April 14, 2019 22:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save josiahdavis/7a02e811360ff00c4eef to your computer and use it in GitHub Desktop.
Save josiahdavis/7a02e811360ff00c4eef to your computer and use it in GitHub Desktop.
Responsive Multi-Line Chart

Responsive Multi-Line Chart

'''
Calculate the Gini Coefficient for the Line Chart
'''
# Import packages and read data
import pandas as pd
import datetime
loc = '/Users/josiahdavis/Documents/d3/slalom/'
d = pd.read_csv(loc + 'SampleSuperstore.csv')
# Calculate the cost
d['Cost'] = d['Sales'] - d['Profit']
# Modify the order date so it's just the month
d['Order Date'] = pd.to_datetime(d['Order Date'])
d['Order Month'] = d['Order Date'].map(lambda x: datetime.datetime(x.year, x.month, 1))
'''
Create the master dataframes for the product and customer aggregations
'''
# Create the dataframe for the product
p = pd.DataFrame()
for metric in ['Quantity', 'Sales', 'Cost']:
p_temp = d.groupby(['Category', 'Order Month', 'Product Name']).apply(lambda x: x[metric].sum()).order(ascending=True)
p_temp = p_temp.to_frame(name='total')
p_temp['metric'] = metric
p = p.append(p_temp)
p.reset_index(inplace=True)
# Create the dataframe for the customer
c = pd.DataFrame()
for metric in ['Quantity', 'Sales', 'Cost']:
c_temp = d.groupby(['Category', 'Order Month', 'Customer Name']).apply(lambda x: x[metric].sum()).order(ascending=True)
c_temp = c_temp.to_frame(name='total')
c_temp['metric'] = metric
c = c.append(c_temp)
c.reset_index(inplace=True)
'''
Calculate the Gini Coefficient
'''
# Define function to calculate the gini coefficient
# Assumes the data sort order is ascending
def calculateGini(N, ds):
ds.reset_index(inplace=True, drop=True)
G = (2 / float(N)) * (ds.total * (ds.index.values + 1)).sum(axis = 0) / \
ds.total.sum(axis = 0) - (N + 1) / N
return G
# Execute the gini calculation for each product category, time and metric
gp = p.groupby(['metric', 'Category', 'Order Month']).apply(lambda x: calculateGini(x.shape[0], x))
# Change the category from being a row to being a column
gp = gp.unstack('Category')
print gp
print gp.describe()
# Write to csv
gp.to_csv(loc + 'giniLine.csv', index=True)
metric Order Month Furniture Office Supplies Technology
Cost 2011-01-01 00:00:00 0.7111756045105666 0.7828863426080579 0.5047436891235693
Cost 2011-02-01 00:00:00 0.7735896597604033 0.5576691145468795 0.5033405036462606
Cost 2011-03-01 00:00:00 0.5530029054562966 0.7485473664269193 0.9102953901617419
Cost 2011-04-01 00:00:00 0.6283635465533035 0.8410982739367479 0.5895793683884352
Cost 2011-05-01 00:00:00 0.5445991807613348 0.7430376497561306 0.6784338045514724
Cost 2011-06-01 00:00:00 0.6258518359777552 0.7917201095094983 0.5531832573664437
Cost 2011-07-01 00:00:00 0.5957739553664274 0.9117611462009347 0.6446096481782215
Cost 2011-08-01 00:00:00 0.5984749054716585 0.7535971633610465 0.5198525110900314
Cost 2011-09-01 00:00:00 0.6864336777949813 0.8272848499591208 0.8181442958009517
Cost 2011-10-01 00:00:00 0.6072426076995601 0.693573334315317 0.6735986172114161
Cost 2011-11-01 00:00:00 0.6454301849717319 0.7963112043764793 0.647045749182924
Cost 2011-12-01 00:00:00 0.6833851004069575 0.7628965598046231 0.6272490206305601
Cost 2012-01-01 00:00:00 0.7524522985464639 0.6393258867482863 0.7324858973123947
Cost 2012-02-01 00:00:00 0.5955930581651434 0.8246541478232836 0.5713918273723599
Cost 2012-03-01 00:00:00 0.6593082389274929 0.8262474596300065 0.689996623274451
Cost 2012-04-01 00:00:00 0.617388611773642 0.8034859549170046 0.5785074932327066
Cost 2012-05-01 00:00:00 0.6855386343061631 0.6961003000599093 0.6350406573707956
Cost 2012-06-01 00:00:00 0.6689403184537182 0.7937916269805148 0.571504929701445
Cost 2012-07-01 00:00:00 0.5793108731503156 0.6644353272925232 0.5152962236038217
Cost 2012-08-01 00:00:00 0.6117244519244602 0.7804007193012577 0.6469355180034402
Cost 2012-09-01 00:00:00 0.747567521101494 0.7618110922344139 0.5614949949695218
Cost 2012-10-01 00:00:00 0.6111662994177849 0.7975939730301251 0.5384977642359665
Cost 2012-11-01 00:00:00 0.6380376581960248 0.744553974081922 0.6434208828603107
Cost 2012-12-01 00:00:00 0.6614738589206555 0.7405827399532199 0.6833526547963846
Cost 2013-01-01 00:00:00 0.6572079098707195 0.7683661019235544 0.597034899248577
Cost 2013-02-01 00:00:00 0.6092901536022766 0.67468021188993 0.8525628657741262
Cost 2013-03-01 00:00:00 0.5898722302257595 0.8681708976392337 0.7162411256231775
Cost 2013-04-01 00:00:00 0.632313147892307 0.7945519368569791 0.8341497101062791
Cost 2013-05-01 00:00:00 0.7089760834244969 0.7671960878670427 0.7199198017752204
Cost 2013-06-01 00:00:00 0.6140289575866922 0.7018504640773522 0.7401072209488981
Cost 2013-07-01 00:00:00 0.6261492768527188 0.7827686593567282 0.6373608669363735
Cost 2013-08-01 00:00:00 0.597430829334366 0.7477402193514302 0.577543648632304
Cost 2013-09-01 00:00:00 0.6109187507418261 0.7906755875298999 0.6478303312865763
Cost 2013-10-01 00:00:00 0.6125648844744702 0.7825530625043315 0.7992523193185832
Cost 2013-11-01 00:00:00 0.6611182718366524 0.7385401915981673 0.7268500938264588
Cost 2013-12-01 00:00:00 0.5925635474859461 0.8062018527977535 0.6104276546311223
Cost 2014-01-01 00:00:00 0.6324014626069228 0.8544715088579422 0.6795102795009915
Cost 2014-02-01 00:00:00 0.6031341014307863 0.7683427078046521 0.6284568830543864
Cost 2014-03-01 00:00:00 0.6411569617894899 0.732675984705929 0.7039112796263505
Cost 2014-04-01 00:00:00 0.5984644927504845 0.7721839982637473 0.796688797243946
Cost 2014-05-01 00:00:00 0.6507249772744859 0.7183582487651525 0.6512411766388349
Cost 2014-06-01 00:00:00 0.5743421264157598 0.7598577698750744 0.6187213250865218
Cost 2014-07-01 00:00:00 0.6019222918600577 0.6910876361103222 0.6213584830682723
Cost 2014-08-01 00:00:00 0.7501038272687035 0.8116237278525016 0.7024782881881877
Cost 2014-09-01 00:00:00 0.6337433839523121 0.80067674839068 0.6258859347248127
Cost 2014-10-01 00:00:00 0.6604221573125393 0.8118930380564746 0.7712798735097712
Cost 2014-11-01 00:00:00 0.6452477526512921 0.7761031440689949 0.7507379782671
Cost 2014-12-01 00:00:00 0.6265558881005657 0.792166394177839 0.595675862209669
Quantity 2011-01-01 00:00:00 0.30555555555555536 0.3412228796844181 0.4419753086419753
Quantity 2011-02-01 00:00:00 0.4099999999999999 0.3444928021426179 0.43722943722943697
Quantity 2011-03-01 00:00:00 0.32538167938931295 0.30923423423423424 0.3582766439909295
Quantity 2011-04-01 00:00:00 0.3055555555555556 0.34884057971014504 0.3694545454545455
Quantity 2011-05-01 00:00:00 0.3913043478260869 0.34289978188497283 0.3522727272727273
Quantity 2011-06-01 00:00:00 0.33182589033352183 0.3492780511414053 0.29220779220779214
Quantity 2011-07-01 00:00:00 0.35307017543859653 0.34193452711971206 0.44543689320388347
Quantity 2011-08-01 00:00:00 0.366043613707165 0.3532349109856707 0.44510582010582
Quantity 2011-09-01 00:00:00 0.3663273001508296 0.3473016285516286 0.34662236987818384
Quantity 2011-10-01 00:00:00 0.3292307692307692 0.3209320799682247 0.3261261261261261
Quantity 2011-11-01 00:00:00 0.2912578055307762 0.337249303784138 0.336888888888889
Quantity 2011-12-01 00:00:00 0.36293363499245856 0.34760066750742014 0.29765299407764867
Quantity 2012-01-01 00:00:00 0.42727272727272725 0.29147727272727275 0.3875598086124401
Quantity 2012-02-01 00:00:00 0.4444444444444444 0.3498452012383899 0.38156028368794326
Quantity 2012-03-01 00:00:00 0.35897435897435903 0.3699204021784668 0.33080808080808066
Quantity 2012-04-01 00:00:00 0.3795598432318359 0.348829595678507 0.33574879227053134
Quantity 2012-05-01 00:00:00 0.30612244897959173 0.3069981583793737 0.29501915708812243
Quantity 2012-06-01 00:00:00 0.3185714285714287 0.3308277027027027 0.26331360946745574
Quantity 2012-07-01 00:00:00 0.3557504873294346 0.3156509019990248 0.3784313725490196
Quantity 2012-08-01 00:00:00 0.3353794642857142 0.3822124450031428 0.30200222469410454
Quantity 2012-09-01 00:00:00 0.3261324041811846 0.37555184240612083 0.3766825879287885
Quantity 2012-10-01 00:00:00 0.3331932773109245 0.36157190053903676 0.3529411764705883
Quantity 2012-11-01 00:00:00 0.3447405329593267 0.29733595565885906 0.3143212508884148
Quantity 2012-12-01 00:00:00 0.34872743509600057 0.33796146808739636 0.3414758269720102
Quantity 2013-01-01 00:00:00 0.38883888388838894 0.35626535626535616 0.3257575757575757
Quantity 2013-02-01 00:00:00 0.2890922959572846 0.3482280431432976 0.3459119496855345
Quantity 2013-03-01 00:00:00 0.33434547908232104 0.33010204081632666 0.3008484848484849
Quantity 2013-04-01 00:00:00 0.25650874946649593 0.30781398291679873 0.38477801268498957
Quantity 2013-05-01 00:00:00 0.30672210672210665 0.3291025878574516 0.35687606112054326
Quantity 2013-06-01 00:00:00 0.276867418599702 0.33840471672539985 0.3535353535353536
Quantity 2013-07-01 00:00:00 0.3344645550527905 0.34523646801530883 0.37841796875
Quantity 2013-08-01 00:00:00 0.33386666666666653 0.345123595505618 0.3338345864661654
Quantity 2013-09-01 00:00:00 0.3351493428912786 0.362408580598208 0.3405797101449275
Quantity 2013-10-01 00:00:00 0.3553332467195012 0.3474683268753538 0.32893553223388294
Quantity 2013-11-01 00:00:00 0.34587612323491657 0.3688776973036314 0.2933061962912711
Quantity 2013-12-01 00:00:00 0.33130097394884794 0.3599544847113616 0.32062915910465817
Quantity 2014-01-01 00:00:00 0.3536821705426356 0.33854053663122885 0.3098400650582813
Quantity 2014-02-01 00:00:00 0.37239436619718314 0.28783727687837257 0.4013605442176871
Quantity 2014-03-01 00:00:00 0.3699248120300753 0.36522694866920147 0.33501501501501507
Quantity 2014-04-01 00:00:00 0.32520325203252054 0.33057141790766265 0.3704481792717087
Quantity 2014-05-01 00:00:00 0.3794230769230771 0.349431553443295 0.36030378267854535
Quantity 2014-06-01 00:00:00 0.32267441860465107 0.33350840336134446 0.3547237076648839
Quantity 2014-07-01 00:00:00 0.31905864197530853 0.3045725496114089 0.3264248704663213
Quantity 2014-08-01 00:00:00 0.32672882672882664 0.3445878080815885 0.39269776876267737
Quantity 2014-09-01 00:00:00 0.33642754145638065 0.33206300813008127 0.30619018215498617
Quantity 2014-10-01 00:00:00 0.3916603678508439 0.35694575843582466 0.3991534939967176
Quantity 2014-11-01 00:00:00 0.3160196409390823 0.36021225986623917 0.3431843137254902
Quantity 2014-12-01 00:00:00 0.357560855667568 0.35173602636075185 0.3141836734693877
Sales 2011-01-01 00:00:00 0.7522652072981642 0.7695639081056866 0.525145804413705
Sales 2011-02-01 00:00:00 0.7774779798753615 0.5598731737288509 0.5351190143140454
Sales 2011-03-01 00:00:00 0.5375733045646633 0.7171018836851724 0.8872198978785102
Sales 2011-04-01 00:00:00 0.6141840082223629 0.8018041744949429 0.5598729021381696
Sales 2011-05-01 00:00:00 0.5501148561480278 0.7433633853049468 0.6679356467328732
Sales 2011-06-01 00:00:00 0.6404314310959893 0.7922027069038693 0.5721082768835577
Sales 2011-07-01 00:00:00 0.5916996186414796 0.8783220735692612 0.6301871807743349
Sales 2011-08-01 00:00:00 0.6145742326996861 0.7458950903596926 0.5050920627543976
Sales 2011-09-01 00:00:00 0.6818882579798087 0.8369524602668041 0.7816257114960048
Sales 2011-10-01 00:00:00 0.6097639186426171 0.6672828348166799 0.6846107843585649
Sales 2011-11-01 00:00:00 0.6299487687253889 0.7695244368908383 0.6607522208039904
Sales 2011-12-01 00:00:00 0.6996313398352494 0.7372096985714169 0.6633899265551659
Sales 2012-01-01 00:00:00 0.7211308876244042 0.6204034625548713 0.7217066078519707
Sales 2012-02-01 00:00:00 0.6206676094851475 0.8374301793172119 0.5938177919052701
Sales 2012-03-01 00:00:00 0.6665921456845327 0.8479552813187781 0.7193377017934446
Sales 2012-04-01 00:00:00 0.6136591535345872 0.8037496335362633 0.5858287397387285
Sales 2012-05-01 00:00:00 0.7094594183266811 0.6824420388935755 0.6492976200701013
Sales 2012-06-01 00:00:00 0.6266238364445522 0.7949093080442278 0.5897224804307946
Sales 2012-07-01 00:00:00 0.5646487998836709 0.6623656909851714 0.5177975127871408
Sales 2012-08-01 00:00:00 0.6201462530492781 0.7636378427995323 0.6733287067349987
Sales 2012-09-01 00:00:00 0.7201897482991801 0.7223473802862885 0.561835705786641
Sales 2012-10-01 00:00:00 0.590123614446878 0.7619429047948321 0.5511211004276324
Sales 2012-11-01 00:00:00 0.6464745449359619 0.7264312602791416 0.6823364420091342
Sales 2012-12-01 00:00:00 0.6511813630211036 0.6878594377407026 0.6834472009283332
Sales 2013-01-01 00:00:00 0.6631805995200515 0.7629406306402398 0.5939715104607475
Sales 2013-02-01 00:00:00 0.6112473865385224 0.6486319671608678 0.8695696970656075
Sales 2013-03-01 00:00:00 0.5957331599738223 0.8416073172037974 0.7405242322907672
Sales 2013-04-01 00:00:00 0.6260942433173569 0.7215914311309997 0.8477686388335601
Sales 2013-05-01 00:00:00 0.7175148166973964 0.7621913997980754 0.7271425796166859
Sales 2013-06-01 00:00:00 0.6306911805603692 0.6702110943619264 0.7190691476286468
Sales 2013-07-01 00:00:00 0.6276414909304071 0.7398643596152783 0.6629907656056868
Sales 2013-08-01 00:00:00 0.5919207611568711 0.7364967015630477 0.5539836606243795
Sales 2013-09-01 00:00:00 0.6020236482213743 0.7660831391311564 0.6518956061910957
Sales 2013-10-01 00:00:00 0.589126048283251 0.7903524683843552 0.8498322925178059
Sales 2013-11-01 00:00:00 0.6606363899032519 0.7244289380444013 0.6551638158161446
Sales 2013-12-01 00:00:00 0.5868539993014559 0.8177254397825533 0.6148797957434102
Sales 2014-01-01 00:00:00 0.6060216477711722 0.8549179531045237 0.6962572757690324
Sales 2014-02-01 00:00:00 0.6010756127422456 0.7531247973347133 0.6305381830078596
Sales 2014-03-01 00:00:00 0.6537659856273261 0.697858861929574 0.7531252835336011
Sales 2014-04-01 00:00:00 0.575889848119929 0.7902234205060674 0.7488603427718206
Sales 2014-05-01 00:00:00 0.6454390665664127 0.714673382861073 0.6621491345892592
Sales 2014-06-01 00:00:00 0.580475140727774 0.7562924357488909 0.6462431963940227
Sales 2014-07-01 00:00:00 0.5684585220970577 0.6865434544052571 0.6076236842756726
Sales 2014-08-01 00:00:00 0.7246999247795265 0.7939992814960151 0.6860321260541293
Sales 2014-09-01 00:00:00 0.6426244183555783 0.7724519383124895 0.6086466118449132
Sales 2014-10-01 00:00:00 0.6292719613010673 0.8033463246477612 0.7995391448490718
Sales 2014-11-01 00:00:00 0.6372120534441854 0.7491178165423342 0.7371111538231812
Sales 2014-12-01 00:00:00 0.6198492908595687 0.7436327438088823 0.6219558096338558
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.line {
fill: none;
stroke: steelblue;
stroke-width: 2px;
}
#chart {
width: 100%;
height: 100%;
position: absolute;
}
</style>
<body>
<svg id="chart"></svg>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"> </script>
<script>
// Define margins
var margin = {top: 20, right: 80, bottom: 30, left: 50},
width = parseInt(d3.select("#chart").style("width")) - margin.left - margin.right,
height = parseInt(d3.select("#chart").style("height")) - margin.top - margin.bottom;
// Define date parser
var parseDate = d3.time.format("%Y-%m-%d %H:%M:%S").parse;
// Define scales
var xScale = d3.time.scale().range([0, width]);
var yScale = d3.scale.linear().range([height, 0]);
var color = d3.scale.ordinal()
.range(["#8c510a", "#dfc27d", "#35978f"]);
// Define axes
var xAxis = d3.svg.axis().scale(xScale).orient("bottom");
var yAxis = d3.svg.axis().scale(yScale).orient("left");
// Define lines
var line = d3.svg.line().interpolate("basis")
.x(function(d) { return xScale(d["date"]); })
.y(function(d) { return yScale(d["concentration"]); });
// Define svg canvas
var svg = d3.select("#chart")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// Read in data
d3.csv("giniLine.csv", function(error, data){
if (error) throw error;
// Set the color domain equal to the three product categories
var productCategories = d3.keys(data[0]).filter(function(key){return (key !== "Order Month") && (key !== "metric")})
color.domain(productCategories);
// console.log(JSON.stringify(data, null, 2)) // to view the structure
// Format the data field
data.forEach(function(d){
d["Order Month"] = parseDate(d["Order Month"])
});
// Filter the data to only include a single metric
var subset = data.filter(function(el) {return el.metric === "Quantity" });
// console.log(JSON.stringify(subset, null, 2))
// Reformat data to make it more copasetic for d3
// data = An array of objects
// concentrations = An array of three objects, each of which contains an array of objects
var concentrations = productCategories.map(function(category){
return {category: category, datapoints: subset.map(function(d){
return {date: d["Order Month"], concentration: +d[category]}
})}
})
// console.log(JSON.stringify(concentrations, null, 2)) // to view the structure
// Set the domain of the axes
xScale.domain(d3.extent(subset, function(d) {return d["Order Month"]; }));
yScale.domain([0.25, 0.5]);
// Place the axes on the chart
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("class", "label")
.attr("y", 6)
.attr("dy", ".71em")
.attr("dx", ".71em")
.style("text-anchor", "beginning")
.text("Product Concentration");
var products = svg.selectAll(".category")
.data(concentrations)
.enter().append("g")
.attr("class", "category");
products.append("path")
.attr("class", "line")
.attr("d", function(d) {return line(d.datapoints); })
.style("stroke", function(d) {return color(d.category); });
// console.log(JSON.stringify(d3.values(concentrations), null, 2)) // to view the structure
console.log(d3.values(concentrations)); // to view the structure
console.log(concentrations);
// console.log(concentrations.map(function()))
});
// Define responsive behavior
function resize() {
var width = parseInt(d3.select("#chart").style("width")) - margin.left - margin.right,
height = parseInt(d3.select("#chart").style("height")) - margin.top - margin.bottom;
// Update the range of the scale with new width/height
xScale.range([0, width]);
yScale.range([height, 0]);
// Update the axis and text with the new scale
svg.select('.x.axis')
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.select('.y.axis')
.call(yAxis);
// Force D3 to recalculate and update the line
svg.selectAll('.line')
.attr("d", function(d) { return line(d.datapoints); });
// Update the tick marks
xAxis.ticks(Math.max(width/75, 2));
yAxis.ticks(Math.max(height/50, 2));
};
// Call the resize function whenever a resize event occurs
d3.select(window).on('resize', resize);
// Call the resize function
resize();
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment