From b937e3e1b596b36f4a7f66c42c2269e7e930d270 Mon Sep 17 00:00:00 2001 From: Anton Nesterov Date: Tue, 24 Sep 2024 16:03:58 +0200 Subject: [PATCH] first commit --- plots.ts | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 plots.ts diff --git a/plots.ts b/plots.ts new file mode 100644 index 0000000..f365e8b --- /dev/null +++ b/plots.ts @@ -0,0 +1,70 @@ +import * as Plot from "npm:@observablehq/plot"; +import { DOMParser, SVGElement } from "npm:linkedom"; + +const defaultPlotSettings = { + grid: true, + margin: 50, + style: { + backgroundColor: "#fff" + } +} + +/** + * Configure default plot settings + * @param options + */ +export function configurePlots(options: any) { + Object.assign(defaultPlotSettings, options) +} + + +/** + * Draw side-by-side plots + * Example: + * ```ts + * const plt = sideBySidePlot({ + * x: ['enginesize', 'horsepower', 'citympg', 'highwaympg'], + * y: ['price'], + * marks: [ + * (x, y) => Plot.dot(data, {x, y, fill: "species"}), + * (x, y) => Plot.linearRegressionY(data, {x, y, stroke: "red"}), + * ], + * cols: 2 + * }) + * @param x List of x-axis targets + * @param y List of y-axis targets + * @param marks List of plot callbacks + * @param cols Number of columns + */ +export function sideBySidePlot(opts: { + x: string[], + y: string[], + marks: any[] + cols: number, + options, +}) { + const document = new DOMParser().parseFromString(``, "text/html"); + const imgTags: string[] = [] + for (const xTarget of opts.x) { + for (const yTarget of opts.y) { + const plt = Plot.plot({ + ...(opts.options ?? defaultPlotSettings), + marks: opts.marks.map(fn => fn(xTarget, yTarget)), + document + }) + plt.setAttribute('xmlns', 'http://www.w3.org/2000/svg') + const svgUrl = `data:image/svg+xml;base64,${btoa(unescape(encodeURIComponent(plt)))}` + imgTags.push(``) + } + } + const output = ` +
+ ${imgTags.join('')} +
+ ` + return { + [Symbol.for("Jupyter.display")]: () => ({ + "text/html": output + }) + } +} \ No newline at end of file