more elegantly handle samples, properly use sample data in SampleSets for bands

This commit is contained in:
Conor Barnes 2022-08-31 11:19:11 -03:00
parent 07b7b26d60
commit bc64d2882f
4 changed files with 42 additions and 43 deletions

View File

@ -19,6 +19,7 @@ import { NumberShower } from "./NumberShower";
import { Plot, parsePlot } from "../lib/plotParser"; import { Plot, parsePlot } from "../lib/plotParser";
import { flattenResult } from "../lib/utility"; import { flattenResult } from "../lib/utility";
import { hasMassBelowZero } from "../lib/distributionUtils"; import { hasMassBelowZero } from "../lib/distributionUtils";
import { point } from "@quri/squiggle-lang/src/js/distribution";
export type DistributionPlottingSettings = { export type DistributionPlottingSettings = {
/** Whether to show a summary of means, stdev, percentiles etc */ /** Whether to show a summary of means, stdev, percentiles etc */
@ -65,6 +66,7 @@ export const DistributionChart: React.FC<DistributionChartProps> = (props) => {
// color: x.color, // not supported yet // color: x.color, // not supported yet
continuous: shape.continuous, continuous: shape.continuous,
discrete: shape.discrete, discrete: shape.discrete,
samples: [] as point[],
})) }))
) )
); );
@ -77,6 +79,12 @@ export const DistributionChart: React.FC<DistributionChartProps> = (props) => {
); );
} }
// if this is a sample set, include the samples
const t = plot?.distributions[0]?.distribution?.t;
if (t.tag === "SampleSet") {
shapes.value[0].samples = t.value.map((v) => ({ x: v, y: 0 }));
}
const spec = buildVegaSpec(props); const spec = buildVegaSpec(props);
let widthProp = width ? width : size.width; let widthProp = width ? width : size.width;
@ -106,12 +114,13 @@ export const DistributionChart: React.FC<DistributionChartProps> = (props) => {
discrete: val.discrete.map((p) => { discrete: val.discrete.map((p) => {
return { dateTime: p.x, y: p.y }; return { dateTime: p.x, y: p.y };
}), }),
samples: val.samples.map((p) => {
return { dateTime: p, y: 0 };
}),
}; };
}) })
: shapes.value; : shapes.value;
console.log({ data });
return ( return (
<div style={{ width: widthProp }}> <div style={{ width: widthProp }}>
{logX && shapes.value.some(hasMassBelowZero) ? ( {logX && shapes.value.some(hasMassBelowZero) ? (

View File

@ -51,8 +51,6 @@ export interface SquiggleChartProps {
minX?: number; minX?: number;
/** Specify the upper bound of the x scale */ /** Specify the upper bound of the x scale */
maxX?: number; maxX?: number;
// /** Whether to include the sample band below the chart */
sample?: boolean;
/** Whether the x-axis should be dates or numbers */ /** Whether the x-axis should be dates or numbers */
xAxis?: "number" | "dateTime"; xAxis?: "number" | "dateTime";
/** Whether to show vega actions to the user, so they can copy the chart spec */ /** Whether to show vega actions to the user, so they can copy the chart spec */
@ -83,7 +81,6 @@ export const SquiggleChart: React.FC<SquiggleChartProps> = React.memo(
maxX, maxX,
color, color,
title, title,
sample = false,
xAxis = "number", xAxis = "number",
distributionChartActions, distributionChartActions,
enableLocalSettings = false, enableLocalSettings = false,
@ -96,7 +93,7 @@ export const SquiggleChart: React.FC<SquiggleChartProps> = React.memo(
onChange, onChange,
executionId, executionId,
}); });
console.log({ result });
const distributionPlotSettings = { const distributionPlotSettings = {
showSummary, showSummary,
logX, logX,
@ -107,7 +104,6 @@ export const SquiggleChart: React.FC<SquiggleChartProps> = React.memo(
color, color,
title, title,
xAxis, xAxis,
sample,
actions: distributionChartActions, actions: distributionChartActions,
}; };

View File

@ -81,7 +81,6 @@ export function buildVegaSpec(
maxX, maxX,
logX, logX,
expY, expY,
sample = false,
xAxis = "number", xAxis = "number",
} = specOptions; } = specOptions;
@ -110,7 +109,7 @@ export function buildVegaSpec(
width: width, width: width,
height: 100, height: 100,
padding: 5, padding: 5,
data: [{ name: "data" }, { name: "domain" }], data: [{ name: "data" }, { name: "domain" }, { name: "samples" }],
signals: [ signals: [
{ {
name: "hover", name: "hover",
@ -218,7 +217,6 @@ export function buildVegaSpec(
}, },
}, },
}, },
], ],
}, },
{ {
@ -299,6 +297,35 @@ export function buildVegaSpec(
}, },
], ],
}, },
{
name: "sample_distributions",
type: "group",
from: {
facet: {
name: "sample_facet",
data: "distribution_facet",
field: "samples",
},
},
marks: [
{
name: "samples",
type: "rect",
from: { data: "sample_facet" },
encode: {
enter: {
x: { scale: "xscale", field: dateTime ? "dateTime" : "x" },
width: { value: 0.1 },
y: { value: 25, offset: { signal: "height" } },
height: { value: 5 },
fill: { value: "steelblue" },
fillOpacity: { value: 1 },
},
},
},
],
},
], ],
}, },
{ {
@ -384,37 +411,5 @@ export function buildVegaSpec(
}), }),
}; };
// include the band at the bottom if specified in the React component
if (sample) {
spec.marks?.push({
name: "sample_distributions",
type: "group",
from: {
facet: {
name: "distribution_facet",
data: "domain",
groupby: ["name"],
},
},
marks: [
{
name: "samples",
type: "rect",
from: { data: "distribution_facet" },
encode: {
enter: {
x: { scale: "xscale", field: dateTime ? "dateTime" : "x" },
width: { value: 0.5 },
y: { value: 25, offset: { signal: "height" } },
height: { value: 5 },
fill: { value: "steelblue" },
fillOpacity: { value: 0.8 },
},
},
},
],
});
}
return spec; return spec;
} }

View File

@ -59,7 +59,6 @@ could be continuous, discrete or mixed.
args={{ args={{
code: "SampleSet.fromDist(normal(5,2))", code: "SampleSet.fromDist(normal(5,2))",
width, width,
sample: true,
}} }}
> >
{Template.bind({})} {Template.bind({})}