=============== LIBRARY RULES =============== From library maintainers: - Every chart function returns a matplotlib Figure; save it with datachart.utils.save_figure - Set global style with config.set_theme or config.update_config; per-chart overrides go in the chart's style parameter - Combine rendered figures with Panel (overlay on shared axes, optional dual y-axes) and Grid (grid layout, grids nest) ### Import random library Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/utility/stats.ipynb Initial setup to generate random data for statistical examples. ```python import random ``` -------------------------------- ### Install datachart Source: https://github.com/eriknovak/datachart/blob/main/README.md Use pip or uv to install the datachart package. ```bash pip install datachart # or: uv add datachart ``` -------------------------------- ### Install datachart with uv Source: https://github.com/eriknovak/datachart/blob/main/README.md Installation command for the datachart library using the uv package manager. ```bash uv add datachart ``` -------------------------------- ### Install datachart package Source: https://github.com/eriknovak/datachart/blob/main/README.md Standard installation command for the datachart library using pip. ```bash pip install -U datachart ``` -------------------------------- ### Setup and Test Datachart Locally Source: https://github.com/eriknovak/datachart/blob/main/README.md Commands to clone the repository, sync development dependencies, and execute test suites. ```bash git clone https://github.com/eriknovak/datachart.git cd datachart uv sync --group dev # package + dev dependencies python -m unittest discover test # unit tests pytest # documentation notebooks mkdocs serve # docs at http://127.0.0.1:8000 ``` -------------------------------- ### Create Histograms Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/styling/theme-gallery.ipynb Example of creating a histogram chart. ```python figs = groups["Distributions"] figs.append( Histogram( HIST, title="Histogram", figsize=FIGSIZE, subtitle=["Before", "After"], show_legend=True, ) ) ``` -------------------------------- ### Configuring Histogram Style Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/charts/histogram.ipynb Example demonstrating how to customize histogram appearance using the style dictionary. ```python Histogram( data=penguins, # define the style of the histogram style={ "plot_hist_color": "#e76f51", "plot_hist_alpha": 0.6, "plot_hist_hatch": HATCH_STYLE.DIAGONAL, "plot_hist_edge_width": 1.5, "plot_hist_edge_color": "#1d3557", "plot_hist_type": HISTOGRAM_TYPE.STEP_FILLED, }, title="Flipper length of Palmer penguins", xlabel="Flipper length (mm)", ylabel="Number of penguins", xticks=FLIPPER_TICKS, figsize=FIG_SIZE.FULL_SHORT, show_grid=SHOW_GRID.Y, ).show() ``` -------------------------------- ### Enzyme Kinetics Panel Example Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/utility/panel.ipynb Demonstrates overlaying scatter and line charts to compare observed data with a fitted model. ```python import numpy as np rng = np.random.RandomState(42) # Michaelis-Menten parameters: maximum velocity and the Michaelis constant V_MAX, K_M = 50, 20 substrate = np.linspace(0, 100, 15) observed = [ {"x": float(s), "y": float(V_MAX * s / (K_M + s) + rng.randn() * 2)} for s in substrate ] curve = np.linspace(0, 100, 100) model = [{"x": float(s), "y": float(V_MAX * s / (K_M + s))} for s in curve] ``` ```python from datachart.charts import ScatterChart Panel( [ ScatterChart(data=observed, subtitle="Observed"), LineChart(data=model, subtitle="Michaelis-Menten model"), ], title="Enzyme kinetics", xlabel="Substrate concentration (μM)", ylabel_left="Reaction velocity (μmol/min)", figsize=FIG_SIZE.FULL_SHORT, show_grid=SHOW_GRID.BOTH, show_legend=True, ).show() ``` -------------------------------- ### Configuring Heatmap Style Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/charts/heatmap.ipynb Example of applying various style attributes to a Heatmap instance. ```python Heatmap( data=temperatures, # define the style of the heatmap style={ "plot_heatmap_cmap": COLORS.YlOrRd, "plot_heatmap_alpha": 0.9, "plot_heatmap_font_size": 7, "plot_heatmap_font_style": FONT_STYLE.ITALIC, "plot_heatmap_font_weight": FONT_WEIGHT.BOLD, "plot_heatmap_frame_color": "#b5442c", "plot_heatmap_edge_width": 1, "plot_heatmap_edge_color": "#FFFFFF", }, title="Mean monthly temperature", xlabel="Month", ylabel="City", figsize=FIG_SIZE.FULL_MEDIUM, show_colorbars=True, show_heatmap_values=True, valfmt=VALUE_FORMAT.DECIMAL, ).show() ``` -------------------------------- ### Configuring Chart Baselines Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/charts/stackedareachart.ipynb Examples of setting different baseline behaviors for stacked area charts. ```python StackedAreaChart( data=generation, # every year sums to 100: the bands are shares baseline=BASELINE.PERCENT, subtitle=SOURCES, show_legend=True, title="World electricity mix", xlabel="Year", ylabel="Share (%)", figsize=FIG_SIZE.FULL_MEDIUM, ).show() ``` ```python StackedAreaChart( data=generation, # a streamgraph: the baseline wiggles to flatten the bands baseline=BASELINE.WEIGHTED_WIGGLE, subtitle=SOURCES, show_legend=True, title="World electricity generation", xlabel="Year", ylabel="Generation (TWh)", figsize=FIG_SIZE.FULL_MEDIUM, ).show() ``` -------------------------------- ### Setting Histogram Orientation Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/charts/histogram.ipynb Example demonstrating how to switch to a horizontal histogram layout. ```python Histogram( data=penguins, title="Flipper length of Palmer penguins", # the flipper length is now on the y-axis xlabel="Number of penguins", ylabel="Flipper length (mm)", yticks=FLIPPER_TICKS, figsize=FIG_SIZE.FULL_MEDIUM, # change the grid to match the change in orientation show_grid=SHOW_GRID.X, # change the orientation of the bars orientation=ORIENTATION.HORIZONTAL, ).show() ``` -------------------------------- ### Define Sample Data Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/styling/theme-gallery.ipynb Prepares the datasets used across all theme suite examples, including bar, line, scatter, histogram, heatmap, hexbin, area, and funnel data. ```python BAR = [ {"label": l, "y": y} for l, y in zip( ["Alpha", "Beta", "Gamma", "Delta", "Epsilon"], [54.0, 47.1, 62.3, 51.4, 43.8] ) ] CATS = ["Bench A", "Bench B", "Bench C", "Bench D"] GROUPED = [ [{"label": c, "y": y} for c, y in zip(CATS, [66.7, 58.6, 76.7, 83.2])], [{"label": c, "y": y} for c, y in zip(CATS, [65.4, 57.7, 77.8, 82.7])], [{"label": c, "y": y} for c, y in zip(CATS, [68.5, 53.4, 76.9, 85.9])], ] LINES = [ [ {"x": x, "y": 40 + 18 * math.sin(x / 3.2) + x * k + random.uniform(-2, 2)} for x in range(0, 21) ] for k in (1.6, 0.9, 0.3) ] SCATTER = [ [{"x": random.gauss(mx, 1.4), "y": random.gauss(my, 1.2)} for _ in range(45)] for mx, my in ((3, 4), (6.5, 7), (9, 3.5)) ] HIST = [ [{"x": random.gauss(50, 10)} for _ in range(400)], [{"x": random.gauss(68, 8)} for _ in range(400)], ] HEAT = { "z": [ [ round(abs(math.sin(0.5 * i + 0.8 * j)) * (1 - 0.07 * abs(i - j)), 2) for j in range(6) ] for i in range(6) ], } # dense points: two overlapping clusters of unequal weight, for the hexbin HEXBIN = {"x": [], "y": []} for mx, my, n in ((3.5, 4.5, 2100), (7, 6.5, 900)): HEXBIN["x"] += [random.gauss(mx, 1.3) for _ in range(n)] HEXBIN["y"] += [random.gauss(my, 1.1) for _ in range(n)] # Stacked area: world electricity generation by source, TWh (Ember, rounded) AREA_YEARS = list(range(2000, 2024)) AREA = [ [{"x": y, "y": v} for y, v in zip(AREA_YEARS, vals)] for vals in ( [5993, 6070, 6350, 6800, 7100, 7322, 7700, 8200, 8300, 8200, 8673, 9200, 9300, 9600, 9700, 9538, 9500, 9800, 10100, 9900, 9421, 10200, 10300, 10434], [2753, 2880, 3000, 3100, 3320, 3681, 3830, 4100, 4260, 4230, 4831, 4900, 5080, 5050, 5150, 5543, 5800, 5900, 6100, 6300, 6268, 6500, 6600, 6634], [2696, 2620, 2700, 2730, 2880, 2982, 3110, 3150, 3290, 3330, 3532, 3560, 3740, 3830, 3920, 3890, 4050, 4100, 4200, 4270, 4355, 4300, 4340, 4210], [32, 39, 54, 65, 88, 108, 139, 179, 232, 296, 374, 500, 621, 776, 913, 1083, 1289, 1573, 1840, 2110, 2437, 2880, 3400, 3933], ) ] # Sankey: a signup funnel, visits to outcomes FUNNEL = { "links": [ {"source": s, "target": t, "value": v} for s, t, v in ( ("Visited", "Signed up", 300), ("Visited", "Bounced", 700), ("Signed up", "Activated", 180), ("Signed up", "Churned", 120), ("Activated", "Paid", 90), ("Activated", "Free tier", 90), ) ] } ``` -------------------------------- ### Create relationship charts Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/styling/theme-gallery.ipynb Examples for generating scatter charts, heatmaps, contour charts, and hexbin charts. ```python figs = groups["Relationships"] figs.append( ScatterChart( SCATTER, title="Scatter", figsize=FIGSIZE, subtitle=["C1", "C2", "C3"], show_legend=True, ) ) figs.append( ScatterChart( REG, title="Model fit with confidence interval", xlabel="Input", ylabel="Prediction", show_regression=True, show_ci=True, figsize=FIGSIZE, ) ) figs.append( Heatmap(HEAT, title="Heatmap", figsize=FIGSIZE, show_heatmap_values=True) ) figs.append( ContourChart( PEAKS, title="Filled contour", figsize=FIGSIZE, filled=True, ) ) figs.append( ContourChart( PEAKS, title="Contour lines", figsize=FIGSIZE, show_labels=True, valfmt="{x:.0f}", ) ) # 2-D density: the scatter clusters as a kernel density surface figs.append( ContourChart( kde2d( [p["x"] for pts in SCATTER for p in pts], [p["y"] for pts in SCATTER for p in pts], gridsize=60, ), title="Density contour", figsize=FIGSIZE, filled=True, ) ) figs.append( HexbinChart( HEXBIN, title="Hexbin", figsize=FIGSIZE, gridsize=18, show_colorbars=False, ) ) ``` -------------------------------- ### Example plot_text configuration output Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/utility/annotations.ipynb The resulting dictionary of default text annotation settings. ```text {'plot_text_color': None, 'plot_text_size': 9.5, 'plot_text_weight': 'normal', 'plot_text_halign': 'left', 'plot_text_valign': 'center', 'plot_text_alpha': 1.0, 'plot_text_box_visible': True, 'plot_text_box_style': 'round,pad=0.4', 'plot_text_box_facecolor': '#FFFFFF', 'plot_text_box_edgecolor': '#B4BCC4', 'plot_text_box_edge_width': 0.8, 'plot_text_box_alpha': 0.92, 'plot_text_arrow_style': 'curve', 'plot_text_arrow_curve': None, 'plot_text_arrow_color': '#7F8C8D', 'plot_text_arrow_width': 1.0} ``` -------------------------------- ### Create Bar Charts Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/styling/theme-gallery.ipynb Examples of creating standard, grouped, horizontal, error bar, and stacked bar charts. ```python figs.append(BarChart(BAR, title="Bar", figsize=FIGSIZE, value_format="%.1f")) ``` ```python figs.append( BarChart( GROUPED, title="Grouped bar", figsize=FIGSIZE, subtitle=["Model A", "Model B", "Model C"], show_values=False, show_legend=True, ) ) ``` ```python figs.append( BarChart( ABLATION, title="Ablation: performance delta", orientation=ORIENTATION.HORIZONTAL, show_values=True, value_format="%.3f", xlabel="Δ score", show_grid="x", figsize=FIGSIZE, vlines={ "x": 0, "style": { "plot_vline_width": 1.0, "plot_vline_style": "-", "plot_vline_alpha": 1.0, }, }, ) ) ``` ```python figs.append( BarChart( ERRBAR, title="Benchmark scores (3 seeds)", subtitle=["Model A", "Model B"], show_yerr=True, show_values=False, show_legend=True, figsize=FIGSIZE, ) ) ``` ```python figs.append( BarChart( STACKED, title="Token usage by release", subtitle=["Reasoning", "Code", "Tool use", "Other"], bar_mode="stack", show_values=False, show_legend=True, ylabel="Share (%)", figsize=FIGSIZE, ) ) ``` -------------------------------- ### Create distribution plots Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/styling/theme-gallery.ipynb Examples for generating density curves, box plots, violin plots, raincloud plots, and swarm plots. ```python # 1-D density: the binned distribution with its kernel density curve binned = Histogram(HIST[0], subtitle="Binned", show_density=True, figsize=FIGSIZE) curve = LineChart( kde1d([p["x"] for p in HIST[0]]), subtitle="Kernel density", show_area=True, figsize=FIGSIZE, ) figs.append( Panel( [binned, curve], title="Density curve", ylabel_left="Density", show_legend=True, figsize=FIGSIZE, ) ) plt.close(binned) plt.close(curve) figs.append( BoxPlot( BOX, title="Score distribution by release", ylabel="Score", show_outliers=True, figsize=FIGSIZE, ) ) figs.append( ViolinPlot( BOX, title="Score density by release", ylabel="Score", figsize=FIGSIZE, ) ) figs.append( RaincloudPlot( BOX, title="Score raincloud by release", ylabel="Score", figsize=FIGSIZE, ) ) # every observation on top of its summary box, points in the theme's swarm style boxes = BoxPlot(BOX, show_outliers=False, figsize=FIGSIZE) points = SwarmPlot(BOX, figsize=FIGSIZE) figs.append( Panel( [{"figure": boxes, "emphasis": "background"}, points], title="Score spread by release", ylabel_left="Score", figsize=FIGSIZE, ) ) plt.close(boxes) plt.close(points) ``` -------------------------------- ### Create Pyramid and Radial Charts Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/styling/theme-gallery.ipynb Examples of creating pyramid and radial charts with custom axis labels and area styling. ```python figs.append( PyramidChart( PYRAMID, title="Pyramid", figsize=FIGSIZE, subtitle=["Site A", "Site B"], show_legend=True, show_values=False, yticks=list(range(0, 30, 5)), yticklabels=[PYR_AGE_BANDS[i] for i in range(0, 30, 5)], ) ) ``` ```python figs.append( RadialChart( RADIAL, title="Radial", figsize=FIGSIZE, subtitle=["Model v1", "Model v2"], show_area=True, ymin=0, show_legend=True, ) ) ``` -------------------------------- ### Create Line Charts Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/styling/theme-gallery.ipynb Examples of creating line charts for ROC curves, scaling laws, probability distributions, and annotated trends. ```python figs.append( LineChart( ROC_CURVES + [ROC_CHANCE], subtitle=ROC_LABELS + ["Chance"], style=[{"plot_line_drawstyle": "steps-post"}] * len(ROC_CURVES) + [ { "plot_line_style": "--", "plot_line_color": "#888888", "plot_line_width": 1.2, } ], title="ROC curves", xlabel="False positive rate", ylabel="True positive rate", show_legend=True, figsize=FIGSIZE, ) ) ``` ```python figs.append( LineChart( SCALING, subtitle=["1 epoch", "2 epochs", "4 epochs"], title="Scaling law", xlabel="Compute (FLOPs)", ylabel="Loss", scalex="log", scaley="log", show_legend=True, style=[{"plot_line_marker": "o"}] * 3, figsize=FIGSIZE, ) ) ``` ```python figs.append( LineChart( list(DISTS.values()), subtitle=list(DISTS.keys()), title="Probability distributions", xlabel="x", ylabel="Density", show_legend=True, figsize=FIGSIZE, ) ) ``` ```python figs.append( LineChart( [{"x": t, "y": v} for t, v in zip(TS_X, TS_EMA)], title="Annotated trend", xlabel="Day", ylabel="Value", figsize=FIGSIZE, texts=[ { "text": "cycle peak", "x": 0.18, "y": 0.88, "coords": "axes", "target": (PEAK_DAY, TS_EMA[PEAK_DAY]), }, { "text": "smoothed EMA", "x": 0.62, "y": 0.06, "coords": "axes", "style": {"plot_text_box_visible": False}, }, ], ) ) ``` -------------------------------- ### Create flow and composition charts Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/styling/theme-gallery.ipynb Examples for generating parallel coordinates, Sankey charts, and Pareto front visualizations. ```python # parallel coordinates: numeric hue colors lines along the theme ramp figs.append( ParallelCoords( PARCOORD, title="Hyperparameter search", dimensions=["lr", "batch", "layers", "dropout", "score"], hue="score", figsize=FIGSIZE, ) ) figs = groups["Flows"] figs.append(SankeyChart(FUNNEL, title="Sankey", figsize=FIGSIZE)) figs.append( SankeyChart( FUNNEL, title="Sankey, ribbons by target", figsize=FIGSIZE, style={"plot_sankey_link_color": "target"}, ) ) figs = groups["Composition"] # pareto front: scatter families + frontier line families = ScatterChart( PARETO_SCATTER, subtitle=list(PARETO_FAMILIES.keys()), figsize=FIGSIZE ) front = LineChart( PARETO_FRONT, subtitle="Pareto front", style={"plot_line_style": "--", "plot_line_color": "#555555"}, figsize=FIGSIZE, ) figs.append( Panel( [families, front], title="Model performance vs throughput", xlabel="Throughput (tok/s)", ylabel_left="Score", show_legend=True, figsize=FIGSIZE, ) ) plt.close(families) plt.close(front) ``` -------------------------------- ### Configuring Heatmap Dimensions and Aspect Ratio Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/charts/heatmap.ipynb Example of setting a specific figure size and forcing square cells using the Heatmap constructor. ```python Heatmap( data=temperatures, title="Mean monthly temperature", xlabel="Month", ylabel="City", # add to determine the figure size figsize=FIG_SIZE.FULL_SHORT, # keep the cells square aspect_ratio=ASPECT_RATIO.EQUAL, ).show() ``` -------------------------------- ### Cell Size Distribution Panel Example Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/utility/panel.ipynb Combines a histogram with a normal distribution curve to visualize cell size measurements. ```python rng = np.random.RandomState(42) MEAN, STD, N_CELLS, N_BINS = 12.5, 2.3, 250, 25 measurements = rng.normal(MEAN, STD, N_CELLS) diameters = [{"x": float(x)} for x in measurements] # the normal density scaled to the histogram counts: N * bin width * pdf(x) bin_width = (measurements.max() - measurements.min()) / N_BINS grid = np.linspace(measurements.min(), measurements.max(), 150) density = N_CELLS * bin_width * np.exp(-0.5 * ((grid - MEAN) / STD) ** 2) / (STD * np.sqrt(2 * np.pi)) normal_fit = [{"x": float(x), "y": float(y)} for x, y in zip(grid, density)] ``` ```python from datachart.charts import Histogram Panel( [ Histogram(data=diameters, num_bins=N_BINS, subtitle="Measured diameters"), LineChart(data=normal_fit, subtitle="Normal fit"), ], title="Cell size distribution", xlabel="Cell diameter (μm)", ylabel_left="Number of cells", figsize=FIG_SIZE.FULL_SHORT, show_grid=SHOW_GRID.Y, show_legend=True, ).show() ``` -------------------------------- ### Update panel configuration and instantiate Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/utility/panel.ipynb Demonstrates updating global defaults using update_config and creating a Panel with specific overrides. ```python config.update_config( { # split the y-axes sooner "overlay_auto_threshold": 2.0, # draw overlaid bars more transparent "overlay_bar_alpha": 0.5, } ) Panel( [precipitation, temperature], title="Climate of Ljubljana", xlabel="Month", ylabel_left="Precipitation (mm)", ylabel_right="Temperature (°C)", figsize=FIG_SIZE.FULL_SHORT, show_grid=SHOW_GRID.Y, show_legend=True, ).show() # restore the defaults for the rest of the guide config.reset_config() ``` -------------------------------- ### Adjust start angle and direction Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/charts/radialchart.ipynb Control the starting position and rotation direction of the radial chart using compass bearings or degree values. ```python from datachart.constants import DIRECTION ``` ```python RadialChart( data=sunshine_by_month, type=RADIAL_TYPE.BAR, title="Monthly sunshine hours", # start at the right and run counterclockwise (the math convention) startangle="E", direction=DIRECTION.COUNTERCLOCKWISE, ).show() ``` -------------------------------- ### Initialize Chart Environment Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/styling/theme-gallery.ipynb Imports necessary chart components, utilities, and configuration constants for the theme gallery. ```python import math import random import matplotlib.pyplot as plt from datachart.charts import ( BarChart, BoxPlot, ContourChart, Heatmap, HexbinChart, Histogram, LineChart, ParallelCoords, PyramidChart, RadialChart, RaincloudPlot, SankeyChart, ScatterChart, StackedAreaChart, SwarmPlot, ViolinPlot, ) from datachart.config import config from datachart.constants import THEME, ORIENTATION from datachart.utils import Grid, Panel from datachart.utils.stats import kde1d, kde2d random.seed(42) FIGSIZE = (4.2, 3.0) GROUPS = [ "Trends and Comparisons", "Distributions", "Relationships", "Flows", "Composition", ] def ema(vals, alpha=0.35): out, acc = [], vals[0] for v in vals: acc = alpha * v + (1 - alpha) * acc out.append(acc) return out ``` -------------------------------- ### Prepare Dataset Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/charts/hexbinchart.ipynb Generate a synthetic dataset of apartment listings with floor area, rent, and days on the market. ```python import numpy as np rng = np.random.default_rng(7) N_LISTINGS = 8000 # the floor area (m²): log-normal around 60 m², clipped to a realistic range area = np.clip(rng.lognormal(mean=np.log(60), sigma=0.35, size=N_LISTINGS), 18, 220) # the rent (€/month): a base plus a per-m² rate that varies by district rate = rng.choice([13.5, 16.0, 19.5], size=N_LISTINGS, p=[0.5, 0.35, 0.15]) rent = 180 + rate * area + rng.normal(0, 120, N_LISTINGS) rent = np.clip(rent, 300, None) # the days on the market: small, cheap apartments go fastest days = rng.gamma(shape=2.0, scale=6 + 0.12 * area + 0.006 * (rent - rate * area)) listings = { "x": np.round(area, 1).tolist(), "y": np.round(rent).tolist(), "c": np.round(days).tolist(), } # the same listings without the per-point value, for the count charts points = {"x": listings["x"], "y": listings["y"]} ``` -------------------------------- ### Prepare district data Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/charts/hexbinchart.ipynb Organize apartment listing data into separate datasets based on district price rates. ```python DISTRICTS = ["Outskirts", "Midtown", "Center"] by_district = [ { key: [value for value, r in zip(listings[key], rate) if r == district_rate] for key in ("x", "y", "c") } for district_rate in (13.5, 16.0, 19.5) ] points_by_district = [{"x": d["x"], "y": d["y"]} for d in by_district] ``` -------------------------------- ### Define Heatmap Dataset Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/charts/heatmap.ipynb Define the climate data structures for temperatures and precipitation used in the heatmap examples. ```python CITIES = ["Reykjavik", "Moscow", "Ljubljana", "Cairo", "Singapore", "Sydney"] MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] # mean monthly temperature in °C, one row per city TEMPERATURES = [ [-0.2, 0.4, 0.9, 3.2, 6.6, 9.5, 11.3, 10.9, 8.3, 4.9, 1.9, 0.3], [-6.5, -6.7, -1.0, 6.7, 13.2, 17.0, 19.2, 17.0, 11.3, 5.6, -1.2, -5.2], [0.8, 2.4, 6.8, 11.5, 16.2, 20.1, 22.0, 21.4, 16.6, 11.5, 5.9, 1.3], [14.0, 15.2, 17.9, 21.9, 25.3, 27.8, 28.5, 28.5, 26.8, 24.0, 19.6, 15.5], [26.5, 27.1, 27.5, 28.0, 28.3, 28.3, 27.9, 27.9, 27.6, 27.6, 27.0, 26.4], [23.0, 22.9, 21.5, 18.8, 15.8, 13.3, 12.5, 13.5, 16.0, 18.2, 20.0, 21.9], ] # mean monthly precipitation in mm, one row per city PRECIPITATION = [ [90, 80, 80, 60, 55, 45, 50, 60, 70, 85, 80, 95], [50, 40, 35, 40, 50, 80, 85, 80, 65, 70, 55, 50], [75, 70, 85, 95, 105, 120, 110, 125, 135, 145, 130, 105], [5, 4, 4, 1, 1, 0, 0, 0, 0, 1, 3, 6], [240, 160, 185, 180, 170, 130, 150, 175, 170, 190, 260, 290], [100, 120, 130, 125, 120, 130, 95, 80, 70, 75, 85, 80], ] temperatures = {"x": MONTHS, "y": CITIES, "z": TEMPERATURES} precipitation = {"x": MONTHS, "y": CITIES, "z": PRECIPITATION} ``` -------------------------------- ### Calculate KDE and Prepare Data Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/charts/contourchart.ipynb Calculate Gaussian kernel density estimates for penguin data and prepare the surface objects for plotting. ```python from datachart.utils.stats import kde2d, minimum, maximum SPECIES = ["Adelie", "Chinstrap", "Gentoo"] # one grid shared by every species: the range of all penguins, padded by 10% ALL_LENGTHS = [length for record in PENGUINS for length in record["flipper_length"]] ALL_MASSES = [mass for record in PENGUINS for mass in record["body_mass"]] def padded_range(values, padding=0.1): lo, hi = minimum(values), maximum(values) return lo - padding * (hi - lo), hi + padding * (hi - lo) def density(records): # a Gaussian kernel density of the (flipper length, body mass) points surface = kde2d( [length for record in records for length in record["flipper_length"]], [mass for record in records for mass in record["body_mass"]], gridsize=80, xlim=padded_range(ALL_LENGTHS), ylim=padded_range(ALL_MASSES), ) # per mm of flipper length and kg of body mass surface["z"] = (np.array(surface["z"]) * 1000).tolist() return surface # one surface per species: what a KDE chart draws species_density = [ density([p for p in PENGUINS if p["species"] == species]) for species in SPECIES ] # every penguin as a point penguin_points = [ {"x": length, "y": mass} for record in PENGUINS for length, mass in zip(record["flipper_length"], record["body_mass"]) ] ``` -------------------------------- ### Apply a Predefined Theme Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/styling/themes.ipynb Sets a global theme before building charts. Reset the configuration to return to the default theme. ```python config.set_theme(THEME.MINIMAL) BarChart( data=[{"label": f"cat{idx}", "y": 10 + 5 * idx} for idx in range(5)], title="Bar chart under THEME.MINIMAL", figsize=FIG_SIZE.FULL_SHORT, ).show() ``` ```text Result: ``` ```python config.reset_config() ``` -------------------------------- ### Render Basic Hexbin Chart Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/charts/hexbinchart.ipynb Create a basic hexbin chart using only the required data argument. ```python HexbinChart( # add the data to the chart data=points ).show() ``` -------------------------------- ### Create complex chart panels Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/styling/theme-gallery.ipynb Examples of grouping multiple charts into a single Panel with shared axes, legends, and styling. ```python # training loss + validation performance on twin axes loss = LineChart( [{"x": e, "y": v} for e, v in zip(EPOCHS, TRAIN_LOSS)], subtitle="Train loss", style={"plot_line_alpha": 0.3, "plot_line_color": c1}, figsize=FIGSIZE, ) loss_trend = LineChart( [{"x": e, "y": v} for e, v in zip(EPOCHS, LOSS_TREND)], subtitle="Loss trend", style={"plot_line_style": "--", "plot_line_color": c1}, figsize=FIGSIZE, ) val = LineChart( [{"x": e, "y": v} for e, v in zip(EPOCHS, VAL_ACC)], subtitle="Val accuracy", style={"plot_line_alpha": 0.3, "plot_line_color": c2}, figsize=FIGSIZE, ) val_trend = LineChart( [{"x": e, "y": v} for e, v in zip(EPOCHS, VAL_TREND)], subtitle="Val trend", style={"plot_line_style": "--", "plot_line_color": c2}, figsize=FIGSIZE, ) figs.append( Panel( [ {"figure": loss, "y_axis": "left"}, {"figure": loss_trend, "y_axis": "left"}, {"figure": val, "y_axis": "right"}, {"figure": val_trend, "y_axis": "right"}, ], title="Training loss vs validation performance", xlabel="Epoch", ylabel_left="Loss", ylabel_right="Accuracy (%)", show_legend=True, figsize=FIGSIZE, ) ) for fig in (loss, loss_trend, val, val_trend): plt.close(fig) # time series + EMA + forecast horizon raw = LineChart( [{"x": t, "y": v} for t, v in zip(TS_X, TS_RAW)], subtitle="Observed", style={"plot_line_alpha": 0.3, "plot_line_color": c1}, figsize=FIGSIZE, ) smoothed = LineChart( [{"x": t, "y": v} for t, v in zip(TS_X, TS_EMA)], subtitle="EMA", style={"plot_line_color": c1}, figsize=FIGSIZE, ) forecast = LineChart( [{"x": t, "y": v} for t, v in zip(FC_X, TS_FORECAST)], subtitle="Forecast", style={"plot_line_style": "--", "plot_line_color": c2}, vlines={"x": 80, "style": {"plot_vline_style": ":"}}, figsize=FIGSIZE, ) figs.append( Panel( [raw, smoothed, forecast], title="Time series forecast", xlabel="Day", ylabel_left="Value", show_legend=True, figsize=FIGSIZE, ) ) for fig in (raw, smoothed, forecast): plt.close(fig) # random walks through pinned waypoints walks = LineChart( WALKS, subtitle=[None] * len(WALKS), style=[ {"plot_line_alpha": 0.3, "plot_line_width": 1.0, "plot_line_color": c1} ] * len(WALKS), figsize=FIGSIZE, ) pins = ScatterChart( WAYPOINT_PTS, subtitle="Waypoints", style={"plot_scatter_color": "#1F1F1F", "plot_scatter_size": 45}, figsize=FIGSIZE, ) figs.append( Panel( [walks, {"figure": pins, "y_axis": "left", "z_order": 5}], title="Random walks through waypoints", xlabel="Step", ylabel_left="Value", figsize=FIGSIZE, ) ) plt.close(walks) plt.close(pins) figs.append(small_multiples()) return groups ``` -------------------------------- ### Render Minimal Theme Gallery Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/styling/theme-gallery.ipynb Initializes the gallery with the Minimal theme and displays specific chart categories. ```python gallery = render_gallery(THEME.MINIMAL, pair=("#2B7FFF", "#525C66")) gallery["Trends and Comparisons"].show() ``` ```python gallery["Distributions"].show() ``` ```python gallery["Relationships"].show() ``` ```python gallery["Flows"].show() ``` ```python gallery["Composition"].show() ``` -------------------------------- ### Create a LineChart with custom theme settings Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/styling/themes.ipynb Configures a line chart with multiple data series, subtitles, and legend visibility. ```python LineChart( data=[ [{"x": x / 10, "y": np.cos(x / 2)} for x in range(21)], [{"x": x / 10, "y": np.sin(x / 2)} for x in range(21)], ], subtitle=["cosine", "sine"], title="Title", xlabel="the global x-axis label", ylabel="the global y-axis label", figsize=FIG_SIZE.FULL_SHORT, show_grid=SHOW_GRID.BOTH, show_legend=True, ).show() ``` -------------------------------- ### Prepare data for wind and solar streamgraph Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/charts/stackedareachart.ipynb Calculate raw generation and percentage shares for wind and solar sources. ```python renewables = [generation[SOURCES.index(source)] for source in ("Wind", "Solar")] renewable_shares = [ [{"x": year, "y": 100 * GENERATION[source][i] / totals[i]} for i, year in enumerate(YEARS)] for source in ("Wind", "Solar") ] ``` -------------------------------- ### Configure Bar Chart with Reference Lines Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/charts/barchart.ipynb Example of adding a dashed horizontal goal line and a dotted vertical event line to a BarChart instance. ```python BarChart( data=sales_total, # add a horizontal line at the sales goal hlines={ "y": SALES_GOAL, "label": "monthly goal", "style": { "plot_hline_color": "#c1121f", "plot_hline_style": LINE_STYLE.DASHED, "plot_hline_width": 1.5, }, }, # add a vertical line between the June and July bars vlines={ "x": 5.5, "label": "price cut", "style": { "plot_vline_color": "#555555", "plot_vline_style": LINE_STYLE.DOTTED, "plot_vline_width": 1.5, }, }, title="Monthly unit sales (2025)", xlabel="Month", ylabel="Units sold", figsize=FIG_SIZE.FULL_SHORT, show_grid=SHOW_GRID.Y, show_legend=True, ).show() ``` -------------------------------- ### Initialize Individual Charts Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/utility/grid.ipynb Creates LineChart and BarChart instances with specific titles to be used as grid cells. ```python temperature = LineChart(data=temperature_data, title="Temperature (°C)") precipitation = BarChart(data=precipitation_data, title="Precipitation (mm)") sunshine = BarChart(data=sunshine_data, title="Sunshine (hours)") humidity = LineChart(data=humidity_data, title="Humidity (%)") ``` -------------------------------- ### Inspect Data Structure Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/charts/hexbinchart.ipynb Display the first five entries of the prepared listings dictionary. ```python {key: values[:5] for key, values in listings.items()} ``` -------------------------------- ### Import Grid and Chart Functions Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/utility/grid.ipynb Initial imports required to utilize the Grid utility and chart functions. ```python from datachart.charts import BarChart, LineChart from datachart.utils import Grid ``` -------------------------------- ### Configure figure size and grid Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/charts/pyramidchart.ipynb Set figure dimensions using figsize constants and enable specific grid lines with show_grid. ```python from datachart.constants import FIG_SIZE, SHOW_GRID ``` ```python PyramidChart( data=[riverside_bands, hillcrest_bands], title="Residents by age band", # a taller figure and vertical grid lines figsize=FIG_SIZE.FULL_TALL, show_grid=SHOW_GRID.X, ).show() ``` -------------------------------- ### Render Hatch Theme Gallery Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/styling/theme-gallery.ipynb Initializes the gallery with the Hatch theme and displays specific chart categories. ```python gallery = render_gallery(THEME.HATCH, pair=("#5B84C4", "#C85450")) gallery["Trends and Comparisons"].show() ``` ```python gallery["Distributions"].show() ``` ```python gallery["Relationships"].show() ``` ```python gallery["Flows"].show() ``` ```python gallery["Composition"].show() ``` -------------------------------- ### Importing the global config instance Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/styling/config.ipynb Import the config object to begin customizing global package settings. ```python from datachart.config import config ``` -------------------------------- ### Prepare Dataset Source: https://github.com/eriknovak/datachart/blob/main/docs/how-to-guides/charts/linechart.ipynb Define monthly temperature data and standard deviations for multiple cities to be used in charts. ```python MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] MONTH_TICKS = list(range(1, 13)) CITIES = ["Ljubljana", "Reykjavik", "Lisbon"] # average monthly temperature in °C (1991-2020 climate normals, rounded) TEMPERATURE = { "Ljubljana": [0.3, 1.9, 6.2, 10.9, 15.6, 19.4, 21.4, 20.9, 16.3, 11.2, 5.8, 1.3], "Reykjavik": [-0.5, 0.4, 0.5, 2.9, 6.3, 9.0, 10.6, 10.3, 7.4, 4.4, 1.1, 0.2], "Lisbon": [11.6, 12.7, 14.5, 15.9, 18.2, 21.1, 23.5, 23.8, 22.2, 18.8, 15.0, 12.4], } # year-to-year standard deviation of the monthly mean TEMPERATURE_STD = { "Ljubljana": [2.1, 2.4, 1.8, 1.5, 1.4, 1.3, 1.2, 1.4, 1.3, 1.5, 1.7, 1.9], "Reykjavik": [1.6, 1.7, 1.5, 1.1, 0.9, 0.8, 0.8, 0.8, 0.9, 1.2, 1.5, 1.6], "Lisbon": [1.1, 1.2, 1.2, 1.1, 1.2, 1.1, 1.2, 1.1, 1.2, 1.2, 1.1, 1.0], } temperature_ljubljana = [ {"x": month, "y": temp} for month, temp in zip(MONTH_TICKS, TEMPERATURE["Ljubljana"]) ] temperature_by_city = [ [ {"x": month, "y": temp, "yerr": std} for month, temp, std in zip(MONTH_TICKS, TEMPERATURE[city], TEMPERATURE_STD[city]) ] for city in CITIES ] ```