======================== CODE SNIPPETS ======================== TITLE: Install Detroit with pip DESCRIPTION: Installs the latest stable version of the Detroit library from PyPI using pip. This is the standard method for installing Python packages. SOURCE: https://github.com/bourbonut/detroit/blob/main/docs/source/index.rst#_snippet_0 LANGUAGE: shell CODE: ``` pip install detroit ``` ---------------------------------------- TITLE: Load and Prepare Data using Polars DESCRIPTION: Loads alphabet frequency data from a CSV URL using Polars and sorts it by frequency in descending order. This step prepares the data for visualization. SOURCE: https://github.com/bourbonut/detroit/blob/main/docs/source/bar.rst#_snippet_0 LANGUAGE: python CODE: ``` # Source : https://observablehq.com/@d3/bar-chart/2 import detroit as d3 import polars as pl # for data manipulation from collections import namedtuple URL = "https://static.observableusercontent.com/files/09f63bb9ff086fef80717e2ea8c974f918a996d2bfa3d8773d3ae12753942c002d0dfab833d7bee1e0c9cd358cd3578c1cd0f9435595e76901508adc3964bbdc?response-content-disposition=attachment%3Bfilename*%3DUTF-8%27%27alphabet.csv" Margin = namedtuple("Margin", ["top", "right", "bottom", "left"]) alphabet = pl.read_csv(URL).sort(by="frequency", descending=True) ``` ---------------------------------------- TITLE: Create an SVG element with Detroit DESCRIPTION: Shows how to create a root SVG element using the `d3.create` function in the Detroit library. This is the starting point for building SVG-based visualizations. SOURCE: https://github.com/bourbonut/detroit/blob/main/docs/source/index.rst#_snippet_2 LANGUAGE: python CODE: ``` import detroit as d3 svg = d3.create("svg") ``` ---------------------------------------- TITLE: Load Car Data with Polars DESCRIPTION: Loads car dataset from a URL into a Polars DataFrame with a predefined schema. Requires detroit, polars, and collections.namedtuple. SOURCE: https://github.com/bourbonut/detroit/blob/main/docs/source/scatter.rst#_snippet_0 LANGUAGE: python CODE: ``` # Source : https://observablehq.com/@d3/brushable-scatterplot import detroit as d3 import polars as pl # for data manipulation from collections import namedtuple URL = "https://static.observableusercontent.com/files/53c407ee531bab128477148c9e28c49dd06bf83a93ae317e58dbb9fc819db0d4f6c4fb9646fa2fe20faad76addee20cfc360eab2362eeaec3340a5e4655b9996?response-content-disposition=attachment%3Bfilename*%3DUTF-8%27%27cars-2.csv" Margin = namedtuple("Margin", ["top", "right", "bottom", "left"]) schema = pl.Schema( { "Name": pl.String, "Miles_per_Gallon": pl.Float32, "Cylinders": pl.Int32, "Displacement": pl.Float32, "Horsepower": pl.Int32, "Weight_in_lbs": pl.Int32, "Acceleration": pl.Float32, "Year": pl.Int32, "Origin": pl.String, } ) cars = pl.read_csv(URL, schema=schema) ``` ---------------------------------------- TITLE: Install Detroit using pip DESCRIPTION: This command installs the Detroit Python package using pip. Ensure you have Python and pip installed on your system. SOURCE: https://github.com/bourbonut/detroit/blob/main/README.md#_snippet_0 LANGUAGE: sh CODE: ``` pip install detroit ``` ---------------------------------------- TITLE: Load Data for Pie Chart (Python) DESCRIPTION: Loads population data by age from a CSV file using the polars library. This data is then used to generate a pie chart. Dependencies include polars and detroit. SOURCE: https://github.com/bourbonut/detroit/blob/main/docs/source/pie.rst#_snippet_0 LANGUAGE: python CODE: ``` # Source : https://observablehq.com/@d3/donut-chart/2 import polars as pl # for data manipulation import detroit as d3 URL = "https://static.observableusercontent.com/files/bee673b386dd058ab8d2cf353acbedc6aa01ebd1e6f63e2a9ab1b4273c7e6efd1eeea526345e4be7f0012d5db3ec743ef39ad9e6a043c196670bf9658cb02e79?response-content-disposition=attachment%3Bfilename*%3DUTF-8%27%27population-by-age.csv" data = pl.read_csv(URL) ``` ---------------------------------------- TITLE: Save SVG Chart to File DESCRIPTION: Writes the generated SVG chart to a file named 'bar.svg'. This allows the visualization to be saved and shared. SOURCE: https://github.com/bourbonut/detroit/blob/main/docs/source/bar.rst#_snippet_2 LANGUAGE: python CODE: ``` with open("bar.svg", "w") as file: file.write(str(svg)) ``` ---------------------------------------- TITLE: Load Penguin Data with Polars DESCRIPTION: Loads the penguin dataset from a URL into a Polars DataFrame and converts it to a list of dictionaries. Requires Polars and standard Python libraries. SOURCE: https://github.com/bourbonut/detroit/blob/main/docs/source/complex_charts/scatter_matrix.rst#_snippet_0 LANGUAGE: python CODE: ``` # Source: https://observablehq.com/@d3/brushable-scatterplot-matrix import detroit as d3 import polars as pl from operator import itemgetter, iadd from math import isnan, exp from itertools import product, accumulate URL = "https://static.observableusercontent.com/files/715db1223e067f00500780077febc6cebbdd90c151d3d78317c802732252052ab0e367039872ab9c77d6ef99e5f55a0724b35ddc898a1c99cb14c31a379af80a?response-content-disposition=attachment%3Bfilename*%3DUTF-8%27%27penguins.csv" # Load data penguins = pl.read_csv(URL) data = penguins.to_dicts() ``` ---------------------------------------- TITLE: Draw a line chart with axes using Detroit DESCRIPTION: Provides a complete example of drawing a line chart with X and Y axes using the Detroit library. It includes data preparation, scale definition, axis generation, and path creation for the line. SOURCE: https://github.com/bourbonut/detroit/blob/main/docs/source/index.rst#_snippet_4 LANGUAGE: python CODE: ``` data = [ {"quantity": 0, "ratio": 50}, {"quantity": 1, "ratio": 12}, {"quantity": 2, "ratio": 89}, {"quantity": 3, "ratio": 87}, {"quantity": 4, "ratio": 62}, {"quantity": 5, "ratio": 8}, {"quantity": 6, "ratio": 10}, {"quantity": 7, "ratio": 33}, {"quantity": 8, "ratio": 8}, {"quantity": 9, "ratio": 23}, {"quantity": 10, "ratio": 10}, ] # Add x axis ( svg.append("g") .attr("class", "x-axis") .attr("transform", f"translate(0, {height - margin_bottom})") .call(d3.axis_bottom(x)) ) # Add y axis ( svg.append("g") .attr("class", "y-axis") .attr("transform", f"translate({margin_left}, 0)") .call(d3.axis_left(y)) ) line = d3.line().x(lambda d: x(d["quantity"])).y(lambda d: y(d["ratio"])) # noqa # Add line path ( svg.append("path") .attr("fill", "none") .attr("stroke", "steelblue") .attr("stroke-width", 1.5) .attr("d", line(data)) ) ``` ---------------------------------------- TITLE: DataFrame Shape and Sample Data DESCRIPTION: This section displays the shape of the loaded unemployment DataFrame and a sample of its data. It shows the column names, data types, and a few rows to illustrate the data structure, including 'date', 'industry', and 'unemployed'. SOURCE: https://github.com/bourbonut/detroit/blob/main/docs/source/stack.rst#_snippet_1 LANGUAGE: text CODE: ``` shape: (1_708, 3) ┌─────────────────────┬──────────────────────────────┬────────────┐ │ date ┆ industry ┆ unemployed │ │ --- ┆ --- ┆ --- │ │ datetime[μs] ┆ str ┆ i64 │ ╞═════════════════════╪══════════════════════════════╪════════════╡ │ 2000-01-01 00:00:00 ┆ Wholesale and Retail Trade ┆ 1000 │ │ 2000-01-01 00:00:00 ┆ Manufacturing ┆ 734 │ │ 2000-01-01 00:00:00 ┆ Leisure and hospitality ┆ 782 │ │ 2000-01-01 00:00:00 ┆ Business services ┆ 655 │ │ 2000-01-01 00:00:00 ┆ Construction ┆ 745 │ │ … ┆ … ┆ … │ │ 2010-02-01 00:00:00 ┆ Other ┆ 603 │ │ 2010-02-01 00:00:00 ┆ Transportation and Utilities ┆ 591 │ │ 2010-02-01 00:00:00 ┆ Information ┆ 300 │ │ 2010-02-01 00:00:00 ┆ Agriculture ┆ 285 │ │ 2010-02-01 00:00:00 ┆ Mining and Extraction ┆ 79 │ └─────────────────────┴──────────────────────────────┴────────────┘ ``` ---------------------------------------- TITLE: Load and Prepare Unemployment Data using Polars DESCRIPTION: This snippet loads unemployment data from a CSV file using the Polars library. It parses the 'date' column into datetime objects and selects relevant columns for further processing. The data is fetched from a public URL. SOURCE: https://github.com/bourbonut/detroit/blob/main/docs/source/stack.rst#_snippet_0 LANGUAGE: python CODE: ``` # Source: https://observablehq.com/@d3/normalized-stacked-area-chart/2 import polars as pl import detroit as d3 URL = "https://static.observableusercontent.com/files/76f13741128340cc88798c0a0b7fa5a2df8370f57554000774ab8ee9ae785ffa2903010cad670d4939af3e9c17e5e18e7e05ed2b38b848ac2fc1a0066aa0005f?response-content-disposition=attachment%3Bfilename*%3DUTF-8%27%27unemployment.csv" unemployment = pl.read_csv(URL).select( pl.col("date").str.to_datetime("%Y-%m-%d"), pl.all().exclude("date"), ) ``` ---------------------------------------- TITLE: Load Data for Histogram (Python) DESCRIPTION: Loads unemployment data from a CSV file using the Polars library. It also defines a named tuple for margin values and imports the detroit library. SOURCE: https://github.com/bourbonut/detroit/blob/main/docs/source/histogram.rst#_snippet_0 LANGUAGE: python CODE: ``` # Source : https://observablehq.com/@d3/histogram/2 import detroit as d3 import polars as pl # for data manipulation from collections import namedtuple URL = "https://static.observableusercontent.com/files/8a6057f29caa4e010854bfc31984511e074ff9042ec2a99f30924984821414fbaeb75e59654e9303db359dfa0c1052534691dac86017c4c2f992d23b874f9b6e?response-content-disposition=attachment%3Bfilename*%3DUTF-8%27%27unemployment-x.csv" Margin = namedtuple("Margin", ["top", "right", "bottom", "left"]) unemployment = pl.read_csv(URL) ``` ---------------------------------------- TITLE: Create a Line Chart using Detroit DESCRIPTION: Configures and generates a line chart using the Detroit library. It sets up scales for time and linear data, defines a line generator, creates an SVG container, and appends axes with custom styling and grid lines. The line path is drawn using the prepared data. SOURCE: https://github.com/bourbonut/detroit/blob/main/docs/source/line.rst#_snippet_1 LANGUAGE: python CODE: ``` # Declare the chart dimensions and margins. width = 928 height = 500 margin = Margin(20, 30, 30, 40) # Declare the x (horizontal position) scale. x = d3.scale_time( [aapl["date"].min(), aapl["date"].max()], [margin.left, width - margin.right] ) # Declare the y (vertical position) scale. y = d3.scale_linear([0, aapl["close"].max()], [height - margin.bottom, margin.top]) # Declare the area generator. line = d3.line().x(lambda d: x(d[0].timestamp())).y(lambda d: y(d[1])) # Create the SVG container. svg = ( d3.create("svg") .attr("width", width) .attr("height", height) .attr("viewBox", f"0 0 {width} {height}") .attr("style", "max-width: 100%; height: auto; height: intrinsic;") ) # Add the x-axis. svg.append("g").attr("transform", f"translate(0, {height - margin.bottom})").call( d3.axis_bottom(x).set_ticks(width / 80).set_tick_size_outer(0) ) # Add the y-axis, remove the domain line, add grid lines and a label. ( svg.append("g") .attr("transform", f"translate({margin.left}, 0)") .call(d3.axis_left(y).set_ticks(height / 40)) .call(lambda g: g.select(".domain").remove()) .call(lambda g: g.select_all(".tick") .select_all("line") .clone() .attr("x2", width - margin.left - margin.right) .attr("stroke-opacity", 0.1) ) .call( lambda g: ( g.append("text") .attr("x", -margin.left) .attr("y", 10) .attr("fill", "currentColor") .attr("text-anchor", "start") .text("↑ Daily close ($)") ) ) ) # Append a path for the line. ( svg.append("path") .attr("fill", "none") .attr("stroke", "steelblue") .attr("stroke-width", 1.5) .attr("d", line(aapl.iter_rows())) ) ``` ---------------------------------------- TITLE: Python D3.js Scatter Matrix Setup DESCRIPTION: This snippet sets up the SVG canvas and defines a D3.js y-axis. It then defines a Python function to generate transform attributes for cells in the scatter matrix. SOURCE: https://github.com/bourbonut/detroit/blob/main/docs/source/complex_charts/scatter_matrix.rst#_snippet_2 LANGUAGE: python CODE: ``` .attr("transform", lambda d, i: f"translate(0,{i * size})") .each(lambda node, d, i, data: d3.select(node).call(axis_y.set_scale(d))) .call(lambda g: g.select(".domain").remove()) .call(lambda g: g.select_all(".tick").select_all("line").attr("stroke", "#ddd")) ) svg.append("g").call(y_axis) # Translate function for cells def transform(d): i, j = d return f"translate({i * size},{j * size})" ``` ---------------------------------------- TITLE: Load and Prepare Apple Stock Data with Polars DESCRIPTION: Loads Apple stock data from a CSV URL using the Polars library. It selects the 'date' and 'close' columns and converts the date column to datetime objects. This step is crucial for time-series visualization. SOURCE: https://github.com/bourbonut/detroit/blob/main/docs/source/line.rst#_snippet_0 LANGUAGE: python CODE: ``` # Source : https://observablehq.com/@d3/line-chart/2 import detroit as d3 import polars as pl # for data manipulation from collections import namedtuple URL = "https://static.observableusercontent.com/files/de259092d525c13bd10926eaf7add45b15f2771a8b39bc541a5bba1e0206add4880eb1d876be8df469328a85243b7d813a91feb8cc4966de582dc02e5f8609b7?response-content-disposition=attachment%3Bfilename*%3DUTF-8%27%27aapl.csv" Margin = namedtuple("Margin", ["top", "right", "bottom", "left"]) aapl = pl.read_csv(URL).select( pl.col("date").str.to_datetime("%Y-%m-%d"), pl.col("close"), ) ``` ---------------------------------------- TITLE: Load and Prepare Data with Polars DESCRIPTION: Loads Apple stock data from a CSV file using Polars, selecting the date and closing price. It converts the date column to datetime objects. Dependencies include 'detroit', 'polars', and 'collections.namedtuple'. SOURCE: https://github.com/bourbonut/detroit/blob/main/docs/source/area.rst#_snippet_0 LANGUAGE: python CODE: ``` # Source : https://observablehq.com/@d3/area-chart/2 import detroit as d3 import polars as pl # for data manipulation from collections import namedtuple URL = "https://static.observableusercontent.com/files/de259092d525c13bd10926eaf7add45b15f2771a8b39bc541a5bba1e0206add4880eb1d876be8df469328a85243b7d813a91feb8cc4966de582dc02e5f8609b7?response-content-disposition=attachment%3Bfilename*%3DUTF-8%27%27aapl.csv" Margin = namedtuple("Margin", ["top", "right", "bottom", "left"]) aapl = pl.read_csv(URL).select( pl.col("date").str.to_datetime("%Y-%m-%d"), pl.col("close"), ) ``` ---------------------------------------- TITLE: Save Histogram Chart to SVG (Python) DESCRIPTION: Saves the generated SVG chart to a file named 'histogram.svg'. This allows the visualization to be shared or embedded elsewhere. SOURCE: https://github.com/bourbonut/detroit/blob/main/docs/source/histogram.rst#_snippet_2 LANGUAGE: python CODE: ``` with open("histogram.svg", "w") as file: file.write(str(svg)) ``` ---------------------------------------- TITLE: Save SVG Heatmap to File (Python) DESCRIPTION: Saves the generated SVG heatmap to a file named 'heatmap.svg'. This snippet demonstrates basic file writing operations in Python to persist the visualization. SOURCE: https://github.com/bourbonut/detroit/blob/main/docs/source/heatmap.rst#_snippet_2 LANGUAGE: python CODE: ``` with open(f"heatmap.svg", "w") as file: file.write(str(svg)) ``` ---------------------------------------- TITLE: Detroit Group Functions (Multiple) DESCRIPTION: Provides functionalities for grouping and indexing data. Includes functions for creating groups, getting group indices, and rolling up data. SOURCE: https://github.com/bourbonut/detroit/blob/main/docs/source/api/array.rst#_snippet_13 LANGUAGE: python CODE: ``` detroit.group ``` LANGUAGE: python CODE: ``` detroit.groups ``` LANGUAGE: python CODE: ``` detroit.index ``` LANGUAGE: python CODE: ``` detroit.indexes ``` LANGUAGE: python CODE: ``` detroit.rollup ``` LANGUAGE: python CODE: ``` detroit.rollups ``` ---------------------------------------- TITLE: Generate and Render Pie Chart (Python) DESCRIPTION: Generates a pie chart using detroit's arc and pie generators. It configures dimensions, color scales, and appends data to the SVG. The chart includes labels and values for each segment. Dependencies: detroit, polars. SOURCE: https://github.com/bourbonut/detroit/blob/main/docs/source/pie.rst#_snippet_1 LANGUAGE: python CODE: ``` # Declare the chart dimensions. width = 500 height = min(width, 500) radius = min(width, height) / 2 # Declare the arc generator with its dimensions. arc = d3.arc().set_inner_radius(radius * 0.67).set_outer_radius(radius - 1) # Declare pie generator with its dimensions. pie = d3.pie().set_pad_angle(1 / radius).set_sort(None).set_value(lambda d: d[1]) # Declare color scale. color = ( d3.scale_ordinal() .set_domain(data["name"].to_list()) .set_range( d3.quantize( lambda t: d3.interpolate_spectral(t * 0.8 + 0.1), data.height, )[::-1] ) ) # Create the SVG container. svg = ( d3.create("svg") .attr("width", width) .attr("height", height) .attr("viewBox", f"{-width / 2} {-height / 2} {width} {height}") .attr("style", "max-width: 100% height: auto;") ) # Generate pies and add arcs to the chart. ( svg.append("g") .select_all() .data(pie(data.iter_rows())) .join("path") .attr("fill", lambda d: color(d["data"][0])) .attr("d", arc) .append("title") .text(lambda d: f"{d['data'][0]}: {d['data'][1]}") ) # Generate pies and add text on them. ( svg.append("g") .attr("font-family", "sans-serif") .attr("font-size", 12) .attr("text-anchor", "middle") .select_all() .data(pie(data.iter_rows())) .join("g") # .attr("fill", "white") # white text .attr( "transform", lambda d: f"translate({arc.centroid(d)[0]}, {arc.centroid(d)[1]})" ) .call( lambda g: ( g.append("text") .append("tspan") .attr("y", "-0.4em") .attr("font-weight", "bold") .text(lambda d: d["data"][0]) ) ) .call( lambda g: ( g.filter(lambda d: (d["end_angle"] - d["start_angle"]) > 0.25) .select_all("text") .append("tspan") .attr("x", 0) .attr("y", "0.7em") .attr("fill-opacity", 0.7) .text(lambda d: str(d["data"][1])) ) ) ) ``` ---------------------------------------- TITLE: Create Normalized Stacked Area Chart using Detroit DESCRIPTION: This Python snippet constructs a normalized stacked area chart using the Detroit library. It configures stacking parameters, defines scales for time and linear axes, sets up color encoding, and prepares the area shape generator. It also creates an SVG container and appends elements for each series, including paths with tooltips. SOURCE: https://github.com/bourbonut/detroit/blob/main/docs/source/stack.rst#_snippet_2 LANGUAGE: python CODE: ``` data = unemployment.to_dicts() # Declare chart's dimensions width = 928 height = 500 margin_top = 20 margin_right = 20 margin_bottom = 20 margin_left = 40 # Determine the series that need to be stacked. # set_keys: distinct series keys, in input order # set_values: get value for each series key and stack # index: group by stack then series key series = ( d3.stack() .set_order(d3.stack_order_descending) .set_offset(d3.stack_offset_expand) .set_keys(unemployment["industry"].unique().to_list()) .set_value(lambda d, key, i, data: data[d][key]["unemployed"])( d3.index(data, lambda d: d["date"], lambda d: d["industry"]) ) ) # Prepare the scales for positional and color encodings. x = ( d3.scale_time() .set_domain(d3.extent(data, lambda d: d["date"])) .set_range([margin_left, width - margin_right]) ) y = d3.scale_linear().set_range_round([height - margin_bottom, margin_top]) color = ( d3.scale_ordinal() .set_domain([d.key for d in series]) .set_range(d3.SCHEME_TABLEAU_10) ) # Construct an area shape. area = ( d3.area() .x(lambda d: x(d.data.timestamp())) .y0(lambda d: y(d[0])) .y1(lambda d: y(d[1])) ) # Create the SVG container. svg = ( d3.create("svg") .attr("width", width) .attr("height", height) .attr("view_box", [0, 0, width, height]) .attr("style", "max-width: 100% height: auto") ) # Append a path for each series. ( svg.append("g") .select_all() .data(series) .join("path") .attr("fill", lambda d: color(d.key)) .attr("d", area) .append("title") .text(lambda d: d.key) ) # Append the x axis, and remove the domain line. ( svg.append("g") .attr("transform", f"translate(0, {height - margin_bottom})") .call(d3.axis_bottom(x).set_tick_size_outer(0)) .call(lambda g: g.select(".domain").remove()) ) # Add the y axis, remove the domain line, add grid lines and a label. ( svg.append("g") .attr("transform", f"translate({margin_left},0)") .call(d3.axis_left(y).set_ticks(height / 80, "%" )) .call(lambda g: g.select(".domain").remove()) .call( lambda g: g.select_all(".tick line") .filter(lambda d: d == 0 or d == 1) .clone() .attr("x2", width - margin_left - margin_right) ) .call( lambda g: g.append("text") .attr("x", -margin_left) .attr("y", 10) .attr("fill", "currentColor") .attr("text-anchor", "start") .text("↑ Unemployed persons") ) ) ``` ---------------------------------------- TITLE: Create Histogram Chart (Python) DESCRIPTION: Generates a histogram chart using detroit. It bins the data, defines scales for x and y axes, creates an SVG container, and appends rectangular elements for each bin. It also adds x and y axes with labels. SOURCE: https://github.com/bourbonut/detroit/blob/main/docs/source/histogram.rst#_snippet_1 LANGUAGE: python CODE: ``` width = 928 height = 500 margin = Margin(20, 20, 30, 40) # Bin the data. bins = d3.bin().set_thresholds(40).set_value(lambda d: d[3])(unemployment.iter_rows()) # Declare the x (horizontal position) scale. x = ( d3.scale_linear() .set_domain([bins[0].x0, bins[-1].x1]) .set_range([margin.left, width - margin.right]) ) # Declare the y (vertical position) scale. y = ( d3.scale_linear() .set_domain([0, max(map(len, bins))]) .set_range([height - margin.bottom, margin.top]) ) # Create the SVG container. svg = ( d3.create("svg") .attr("width", width) .attr("height", height) .attr("viewBox", f"0, 0, {width}, {height}") .attr("style", "max-width: 100%; height: auto;") ) # Add a rect for each bin. ( svg.append("g") .attr("fill", "steelblue") .select_all() .data(bins) .join("rect") .attr("x", lambda d: x(d.x0) + 1) .attr("width", lambda d: x(d.x1) - x(d.x0) - 1) .attr("y", lambda d: y(len(d))) .attr("height", lambda d: y(0) - y(len(d))) ) # Add the x-axis and label. ( svg.append("g") .attr("transform", f"translate(0, {height - margin.bottom})") .call(d3.axis_bottom(x).set_ticks(width / 80).set_tick_size_outer(0)) .call( lambda g: g.append("text") .attr("x", width) .attr("y", margin.bottom - 4) .attr("fill", "currentColor") .attr("text-anchor", "end") .text("Unemployment rate (%) →") ) ) # Add the y-axis and label, and remove the domain line. ( svg.append("g") .attr("transform", f"translate({margin.left}, 0)") .call(d3.axis_left(y).set_ticks(height / 40)) .call(lambda g: g.select(".domain").remove()) .call( lambda g: ( g.append("text") .attr("x", -margin.left) .attr("y", 10) .attr("fill", "currentColor") .attr("text-anchor", "start") .text("↑ Frequency (no. of counties)") ) ) ) ``` ---------------------------------------- TITLE: Load Population and US Geographical Data DESCRIPTION: Loads population data from a URL and US geographical data (nation, states, counties) from a local JSON file. It also loads state and county mesh data for borders. Dependencies include requests, json, pytopojson, math, and detroit. It processes the data to create dictionaries for quick lookup and calculates centroids. SOURCE: https://github.com/bourbonut/detroit/blob/main/docs/source/bubble.rst#_snippet_0 LANGUAGE: python CODE: ``` # https://observablehq.com/@d3/bubble-map/ import detroit as d3 import requests import json from pytopojson.feature import Feature from math import isnan URL = "https://static.observableusercontent.com/files/beb56a2d9534662123fa352ffff2db8472e481776fcc1608ee4adbd532ea9ccf2f1decc004d57adc76735478ee68c0fd18931ba01fc859ee4901deb1bee2ed1b?response-content-disposition=attachment%3Bfilename*%3DUTF-8%27%27population.json" US_URL = "https://cdn.jsdelivr.net/npm/us-atlas@3/counties-10m.json" # Load data population = json.loads(requests.get(URL).content) us = json.loads(requests.get(US_URL).content) nation = Feature()(us, us["objects"]["nation"]) statemap = dict( (d["id"], d) for d in Feature()(us, us["objects"]["states"])["features"] ) countymap = dict( (d["id"], d) for d in Feature()(us, us["objects"]["counties"])["features"] ) statemesh = json.load(open("data/statemesh.json")) countymesh = json.load(open("data/countymesh.json")) # Declare the chart dimensions. width = 975 height = 610 projection = ( d3.geo_albers_usa().scale(width * 1.2).translate([width * 0.5, height * 0.5]) ) # Helps to compute centroid positions class Centroid: def __init__(self): self._centroid = d3.geo_path(projection).centroid def __call__(self, feature): return f"translate({','.join(map(str, self._centroid(feature)))})" def is_valid(self, feature): return not any(map(isnan, self._centroid(feature))) centroid = Centroid() # Process data population = [ { "state": statemap.get(state), "county": countymap.get(f"{state}{county}"), "fips": f"{state}{county}", "population": int(p), } for p, state, county in population[1:] ] data = sorted( filter(lambda d: centroid.is_valid(d["county"]), population), key=lambda d: d["population"], reverse=True, ) ``` ---------------------------------------- TITLE: Save SVG chart to file DESCRIPTION: This snippet shows how to save an SVG object to a file named 'scatter.svg'. It opens the file in write mode and writes the string representation of the SVG object. SOURCE: https://github.com/bourbonut/detroit/blob/main/docs/source/scatter.rst#_snippet_4 LANGUAGE: python CODE: ``` with open("scatter.svg", "w") as file: file.write(str(svg)) ``` ---------------------------------------- TITLE: Save Stacked Area Chart to SVG File DESCRIPTION: This snippet shows how to save the generated SVG chart to a file named 'stack-area.svg'. It opens the file in write mode and writes the string representation of the SVG object to it. SOURCE: https://github.com/bourbonut/detroit/blob/main/docs/source/stack.rst#_snippet_3 LANGUAGE: python CODE: ``` with open("stack-area.svg", "w") as file: file.write(str(svg)) ``` ---------------------------------------- TITLE: Create Scatter Chart Axes with Detroit DESCRIPTION: Configures the horizontal (x) and vertical (y) scales for a scatter plot using Detroit's scale_linear. Handles data ranges and margins. Requires Detroit library and Margin namedtuple. SOURCE: https://github.com/bourbonut/detroit/blob/main/docs/source/scatter.rst#_snippet_1 LANGUAGE: python CODE: ``` # Specify the chart’s dimensions. width = 928 height = 600 margin = Margin(20, 30, 30, 40) # Create the horizontal (x) scale, positioning N/A values on the left margin. x = ( d3.scale_linear() .set_domain([0, cars["Miles_per_Gallon"].max()]) .nice() .set_range([margin.left, width - margin.right]) .set_unknown(margin.left) ) # Create the vertical (y) scale, positioning N/A values on the bottom margin. y = ( d3.scale_linear() .set_domain([0, cars["Horsepower"].max()]) .nice() .set_range([height - margin.bottom, margin.top]) .set_unknown(height - margin.bottom) ) # Create the SVG container. svg = ( d3.create("svg") .attr("width", width) .attr("height", height) .attr("viewBox", f"0 0 {width} {height}") ) # Append the axes. ( svg.append("g") .attr("transform", f"translate(0, {height - margin.bottom})") .call(d3.axis_bottom(x)) .call(lambda g: g.select(".domain").remove()) .call( lambda g: g.append("text") .attr("x", width - margin.right) .attr("y", -4) .attr("fill", "#000") .attr("font-weight", "bold") .attr("text-anchor", "end") .text("Miles per Gallon") ) ) ( svg.append("g") .attr("transform", f"translate({margin.left}, 0)") .call(d3.axis_left(y)) .call(lambda g: g.select(".domain").remove()) .call( ``` ---------------------------------------- TITLE: Python D3.js Scatter Matrix Legend Creation DESCRIPTION: This section creates the legend for the scatter matrix. It calculates weights and spaces for labels based on their lengths and then appends rectangles and text for each legend item. SOURCE: https://github.com/bourbonut/detroit/blob/main/docs/source/complex_charts/scatter_matrix.rst#_snippet_6 LANGUAGE: python CODE: ``` # Legend part # Labels of the legend data = color.get_domain() # Function to clamp input between 0 and 1 def clamp_total(total): def f(x): return 1 - exp(-x / total) return f offset_space = 80 lengths = list(map(len, data)) clamp = clamp_total(max(lengths)) weights = list(map(clamp, lengths)) w_max = max(weights) weights = [w / w_max for w in weights] # normalize weights # Spaces between labels spaces = [0] + list( accumulate( map(lambda w: w * offset_space + rect_size, weights[:-1]), iadd, ) ) g = ( legend.select_all("g") .data(data) .enter() .append("g") .attr("transform", lambda _, i: f"translate({spaces[i]}, 0)") ) ( g.append("rect") .attr("x", 0) .attr("y", 0) .attr("width", rect_size) .attr("height", rect_size) .attr("fill", lambda d: color(d)) .attr("stroke", "none") ) ( g.append("text") .attr("x", rect_size + 5) .attr("y", rect_size * 0.75) .attr("fill", "black") .attr("stroke", "none") .attr("font-size", "0.75em") .text(lambda d: d) ) ``` ---------------------------------------- TITLE: Python Save Scatter Matrix to SVG DESCRIPTION: This snippet shows how to save the generated D3.js scatter matrix visualization to an SVG file named 'scatter-matrix.svg'. SOURCE: https://github.com/bourbonut/detroit/blob/main/docs/source/complex_charts/scatter_matrix.rst#_snippet_7 LANGUAGE: python CODE: ``` # 3. Save your chart with open(f"scatter-matrix.svg", "w") as file: file.write(str(scatter)) ``` ---------------------------------------- TITLE: Save the Generated SVG Map DESCRIPTION: Saves the complete SVG chart object to a file named 'bubble-map.svg'. This action writes the string representation of the SVG DOM to the specified file. SOURCE: https://github.com/bourbonut/detroit/blob/main/docs/source/bubble.rst#_snippet_2 LANGUAGE: python CODE: ``` with open(f"bubble-map.svg", "w") as file: file.write(str(svg)) ``` ---------------------------------------- TITLE: Save Chart to SVG File DESCRIPTION: Saves the generated SVG chart to a file named 'area.svg'. This step requires the 'svg' object created in the previous step. The code writes the string representation of the SVG object to the file. SOURCE: https://github.com/bourbonut/detroit/blob/main/docs/source/area.rst#_snippet_2 LANGUAGE: python CODE: ``` with open("area.svg", "w") as file: file.write(str(svg)) ``` ---------------------------------------- TITLE: Python D3.js Scatter Matrix Text Labels DESCRIPTION: This snippet adds text labels for each column to the scatter matrix. It sets the font style, positions the text, and displays the column name. SOURCE: https://github.com/bourbonut/detroit/blob/main/docs/source/complex_charts/scatter_matrix.rst#_snippet_5 LANGUAGE: python CODE: ``` # Add some texts in cells ( svg.append("g") .style("font", "bold 10px sans-serif") .style("pointer-events", "none") .select_all("text") .data(columns) .join("text") .attr("transform", lambda d, i: f"translate({i * size},{i * size})") .attr("x", padding) .attr("y", padding) .attr("dy", ".71em") .text(lambda d: d) ) ``` ---------------------------------------- TITLE: Create Heatmap SVG with Detroit (Python) DESCRIPTION: Generates an SVG heatmap visualization using the Detroit library. It configures band scales for x and y axes, a sequential color scale based on vehicle counts, and appends rect elements to represent the heatmap cells. The chart includes axes and is styled according to defined margins. SOURCE: https://github.com/bourbonut/detroit/blob/main/docs/source/heatmap.rst#_snippet_1 LANGUAGE: python CODE: ``` data = traffic.to_dicts() width = 640 height = 820 margin = Margin(15, 40, 45, 120) # Declare the x (horizontal position) scale. x = d3.scale_band(list(map(str, range(24))), [margin.left, width - margin.right]) # Declare the y (vertical position) scale. sorted_locations = ( traffic.select(["location", "vehicles"]) .sort("vehicles", descending=True)["location"] .unique(maintain_order=True) .to_list() ) y = d3.scale_band(sorted_locations, [height - margin.bottom, margin.top]) # Color scale for cell colors color = d3.scale_sequential([0, traffic["vehicles"].max()], d3.interpolate_turbo) svg = ( d3.create("svg") .attr("width", width) .attr("height", height) .attr("viewBox", f"0 0 {width} {height}") ) # Add the x-axis, remove the domain line. ( svg.append("g") .attr("transform", f"translate(0, {height - margin.bottom})") .call(d3.axis_bottom(x)) .call(lambda g: g.select(".domain").remove()) ) # Add the y-axis, remove the domain line. ( svg.append("g") .attr("transform", f"translate({margin.left}, 0)") .call(d3.axis_left(y)) .call(lambda g: g.select(".domain").remove()) ) # Add cells. ( svg.append("g") .select_all() .data(data) .join("rect") .attr("x", lambda d: x(str(d["hour"])) + 0.5) .attr("y", lambda d: y(d["location"]) + 0.5) .attr("width", 19) .attr("height", 19) .attr("fill", lambda d: color(d["vehicles"])) ) ``` ---------------------------------------- TITLE: Create Bar Chart SVG with Detroit DESCRIPTION: Generates an SVG bar chart using the Detroit library. It configures scales for x and y axes, appends rectangles for each data point, and adds axis labels and ticks. The y-axis is formatted to display percentages. SOURCE: https://github.com/bourbonut/detroit/blob/main/docs/source/bar.rst#_snippet_1 LANGUAGE: python CODE: ``` width = 928 height = 500 margin = Margin(30, 0, 30, 40) # Declare the x (horizontal position) scale. # descending frequency x = ( d3.scale_band() .set_domain(alphabet["letter"].unique(maintain_order=True)) .set_range([margin.left, width - margin.right]) .set_padding(0.1) ) # Declare the y (vertical position) scale. y = ( d3.scale_linear() .set_domain([0, alphabet["frequency"].max()]) .set_range([height - margin.bottom, margin.top]) ) # Create the SVG container. svg = ( d3.create("svg") .attr("width", width) .attr("height", height) .attr("viewBox", f"0 0 {width} {height}") .attr("style", "max-width: 100%; height: auto;") ) # Add a rect for each bar. ( svg.append("g") .select_all() .data(alphabet.iter_rows()) .join("rect") .attr("x", lambda d: x(d[0])) .attr("y", lambda d: y(d[1])) .attr("height", lambda d: y(0) - y(d[1])) .attr("width", x.get_bandwidth()) .attr("fill", "steelblue") ) # Add the x-axis and label. svg.append("g").attr("transform", f"translate(0, {height - margin.bottom})").call( d3.axis_bottom(x).set_tick_size_outer(0) ) # Add the y-axis and label, and remove the domain line. ( svg.append("g") .attr("transform", f"translate({margin.left}, 0)") .call(d3.axis_left(y).set_tick_format(lambda y: str(int(y * 100)))) .call(lambda g: g.select(".domain").remove()) .call( lambda g: g.append("text") .attr("x", -margin.left) .attr("y", 10) .attr("fill", "currentColor") .attr("text-anchor", "start") .text("↑ Frequency (%)") ) ) ``` ---------------------------------------- TITLE: Scatter Matrix Chart Creation with Detroit DESCRIPTION: Generates an SVG scatter matrix chart. It defines dimensions, identifies numerical columns, sets up linear and ordinal scales for axes and color, and prepares SVG elements for the chart and legend. Requires Detroit, Polars, and standard Python libraries. SOURCE: https://github.com/bourbonut/detroit/blob/main/docs/source/complex_charts/scatter_matrix.rst#_snippet_1 LANGUAGE: python CODE: ``` # Declare the chart dimensions. width = 928 height = 928 padding = 28 columns = list(filter(lambda d: isinstance(data[0][d], float), penguins.columns)) size = (width - (len(columns) + 1) * padding) / len(columns) + padding # Declare the legend dimensions. rect_size = 15 legend_width = width legend_height = rect_size * 2 # Create the SVG container. scatter = ( d3.create("svg") .attr("width", width) .attr("height", height) .attr("viewBox", f"{-padding} 0 {width} {height}") ) scatter.append("style").text(".circle.hidden{fill:#000;fill-opacity:1;r:1px;}") # Create the legend container. legend = scatter.append("g").attr( "transform", f"translate({rect_size / 2}, {rect_size / 2})" ) svg = scatter.append("g").attr("transform", f"translate(0, {legend_height})") # Declare the x (horizontal position) scales. x = [ d3.scale_linear() .set_domain(d3.extent(data, lambda d: d[c])) .set_range([padding / 2, size - padding / 2]) for c in columns ] axis_x = d3.axis_bottom(None).set_ticks(6).set_tick_size(size * len(columns)) # Declare the y (vertical position) scales. y = [scale.copy().set_range([size - padding / 2, padding / 2]) for scale in x] axis_y = d3.axis_left(None).set_ticks(6).set_tick_size(-size * len(columns)) # Declare the color scale. color = ( d3.scale_ordinal() .set_domain(list(map(itemgetter("species"), data))) .set_range(d3.SCHEME_CATEGORY_10) ) # Function which add all x-axes, remove the domain lines, and add grid lines def x_axis(g): return ( g.select_all("g") .data(x) .join("g") .attr("transform", lambda d, i: f"translate({i * size},0)") .each(lambda node, d, i, data: d3.select(node).call(axis_x.set_scale(d))) .call(lambda g: g.select(".domain").remove()) .call(lambda g: g.select_all(".tick").select_all("line").attr("stroke", "#ddd")) ) svg.append("g").call(x_axis) # Function which add all y-axes, remove the domain lines, and add grid lines def y_axis(g): return ( g.select_all("g") .data(y) .join("g") ```