Weibull Probability Plot for Reliability Analysis — Apache ECharts

A Weibull probability plot displays failure or lifetime data on Weibull probability paper (logarithmic x-axis for time/cycles, linearized Weibull CDF on y-axis) with a fitted straight line. It is the standard tool in reliability engineering for estimating Weibull distribution parameters (shape and scale), assessing whether data follow a Weibull distribution, and extrapolating failure probabilities. The slope of the fitted line gives the shape parameter (beta), while the characteristic life (eta) is read at the 63.2% failure probability crossing.

Weibull Probability Plot for Reliability Analysis rendered with Apache ECharts

Renders

JavaScript source (Apache ECharts)

// anyplot.ai
// probability-weibull: Weibull Probability Plot for Reliability Analysis
// Library: echarts 5.5.1 | JavaScript 22.22.3
// Quality: 90/100 | Created: 2026-06-07
//# anyplot-orientation: landscape
// anyplot.ai
// probability-weibull: Weibull Probability Plot for Reliability Analysis
// Library: echarts 5.5.1 | JavaScript 22
// Quality: pending | Created: 2026-06-07

const t = window.ANYPLOT_TOKENS;

// --- Data: hydraulic pump service-life study (hours, n=20) ---
// 14 failures, 6 right-censored (still running at inspection end)
// Already sorted ascending by time — required for rank assignment
const observations = [
  { time: 620,   fail: true  },
  { time: 890,   fail: true  },
  { time: 1100,  fail: false },
  { time: 1340,  fail: true  },
  { time: 1580,  fail: true  },
  { time: 1920,  fail: false },
  { time: 2200,  fail: true  },
  { time: 2550,  fail: true  },
  { time: 2900,  fail: false },
  { time: 3300,  fail: true  },
  { time: 3750,  fail: true  },
  { time: 4100,  fail: true  },
  { time: 4600,  fail: false },
  { time: 5200,  fail: true  },
  { time: 5900,  fail: true  },
  { time: 6700,  fail: true  },
  { time: 7800,  fail: false },
  { time: 9200,  fail: true  },
  { time: 11000, fail: true  },
  { time: 13500, fail: false },
];

const n = observations.length;

// Median rank (i - 0.3) / (n + 0.4) where i = 1-based rank among ALL observations
const failurePoints = [];
const censoredTimes = [];

observations.forEach((obs, idx) => {
  const i = idx + 1;
  if (obs.fail) {
    const F  = (i - 0.3) / (n + 0.4);
    const yW = Math.log(-Math.log(1 - F));
    failurePoints.push({ time: obs.time, F, yW });
  } else {
    censoredTimes.push(obs.time);
  }
});

// Linear regression: log10(time) vs Weibull y  →  estimates beta (shape) and eta (scale)
const logT  = failurePoints.map(p => Math.log10(p.time));
const yVals = failurePoints.map(p => p.yW);
const nF    = failurePoints.length;
const mLogT = logT.reduce((a, b) => a + b, 0) / nF;
const mY    = yVals.reduce((a, b) => a + b, 0) / nF;
let ssXX = 0, ssXY = 0;
for (let i = 0; i < nF; i++) {
  ssXX += (logT[i] - mLogT) ** 2;
  ssXY += (logT[i] - mLogT) * (yVals[i] - mY);
}
const beta      = ssXY / ssXX;                        // shape parameter β
const intercept = mY - beta * mLogT;
const eta       = Math.pow(10, -intercept / beta);    // characteristic life η (hours)

// Fitted line spanning the full x range
const tMin = 350, tMax = 22000;
const fitData = [
  [tMin, beta * Math.log10(tMin) + intercept],
  [tMax, beta * Math.log10(tMax) + intercept],
];

// Censored markers: project each suspended time onto the fitted line for y-position
const censoredData = censoredTimes.map(time => [
  time,
  beta * Math.log10(time) + intercept,
]);

// Parameter labels
const betaStr = beta.toFixed(2);
const etaStr  = Math.round(eta).toLocaleString();

// --- Init ---
const chart = echarts.init(document.getElementById("container"));

// --- Option ---
chart.setOption({
  animation: false,
  color: t.palette,
  backgroundColor: "transparent",

  title: {
    text: "probability-weibull · javascript · echarts · anyplot.ai",
    left: "center",
    top: 24,
    textStyle: { color: t.ink, fontSize: 22, fontWeight: "bold" },
  },

  legend: {
    top: 65,
    left: "center",
    textStyle: { color: t.inkSoft, fontSize: 14 },
    itemGap: 32,
    data: [
      { name: "Failure", icon: "circle" },
      { name: "Censored (suspended)", icon: "circle" },
      { name: "Weibull Fit" },
      { name: "63.2% Reference" },
    ],
  },

  grid: { left: 115, right: 70, top: 110, bottom: 90 },

  xAxis: {
    type: "log",
    name: "Time to Failure (hours)",
    nameLocation: "middle",
    nameGap: 52,
    nameTextStyle: { color: t.inkSoft, fontSize: 16 },
    min: tMin,
    max: tMax,
    axisLabel: {
      color: t.inkSoft,
      fontSize: 13,
      formatter: val => {
        if (val >= 10000) return (val / 1000).toFixed(0) + "k";
        if (val >= 1000)  return (val / 1000).toFixed(0) + "k";
        return String(val);
      },
    },
    axisLine: { lineStyle: { color: t.inkSoft } },
    splitLine: { lineStyle: { color: t.grid, type: "dashed" } },
    minorSplitLine: { show: true, lineStyle: { color: t.grid, opacity: 0.45 } },
  },

  yAxis: {
    type: "value",
    name: "Cumulative Failure Probability",
    nameLocation: "middle",
    nameGap: 88,
    nameTextStyle: { color: t.inkSoft, fontSize: 16 },
    min: -4.5,
    max: 2.0,
    interval: 1,
    axisLabel: {
      color: t.inkSoft,
      fontSize: 13,
      // Convert Weibull y-value back to a readable probability percentage
      formatter: val => {
        if (val < -4.3 || val > 1.85) return "";
        const F   = 1 - Math.exp(-Math.exp(val));
        const pct = F * 100;
        return pct < 1 ? pct.toFixed(1) + "%" : Math.round(pct) + "%";
      },
    },
    axisLine: { lineStyle: { color: t.inkSoft } },
    splitLine: { lineStyle: { color: t.grid } },
  },

  series: [
    // Weibull fitted line
    {
      name: "Weibull Fit",
      type: "line",
      data: fitData,
      symbol: "none",
      lineStyle: { color: t.palette[2], width: 3 },
      z: 2,
    },
    // Horizontal reference at 63.2% cumulative probability (y = 0)
    {
      name: "63.2% Reference",
      type: "line",
      data: [[tMin, 0], [tMax, 0]],
      symbol: "none",
      lineStyle: { color: t.palette[3], width: 2, type: "dashed" },
      z: 1,
    },
    // Failure observations — filled circles
    {
      name: "Failure",
      type: "scatter",
      data: failurePoints.map(p => [p.time, p.yW]),
      symbolSize: 16,
      itemStyle: {
        color: t.palette[0],
        borderColor: t.pageBg,
        borderWidth: 1.5,
      },
      z: 3,
    },
    // Censored (suspended) observations — hollow circles at projected y position
    {
      name: "Censored (suspended)",
      type: "scatter",
      data: censoredData,
      symbolSize: 16,
      itemStyle: {
        color: "transparent",
        borderColor: t.inkSoft,
        borderWidth: 2,
      },
      z: 3,
    },
  ],

  // Weibull parameter annotation
  graphic: [
    {
      type: "group",
      left: "66%",
      top: "18%",
      children: [
        {
          type: "rect",
          shape: { width: 200, height: 66, r: 4 },
          style: { fill: t.elevatedBg, stroke: t.grid, lineWidth: 1 },
        },
        {
          type: "text",
          style: {
            text: `β (shape)  =  ${betaStr}`,
            fill: t.ink,
            fontSize: 15,
            fontWeight: "bold",
            x: 14,
            y: 14,
          },
        },
        {
          type: "text",
          style: {
            text: `η (char. life)  =  ${etaStr} h`,
            fill: t.ink,
            fontSize: 15,
            fontWeight: "bold",
            x: 14,
            y: 38,
          },
        },
      ],
    },
  ],
});

Retrieve this implementation

Runnable source as JSON, for any HTTP client: https://api.anyplot.ai/specs/probability-weibull/echarts/code. Any spec id and library id listed in llms-full.txt fit the same URL shape; every URL below is complete and callable.

{
  "spec_id": "probability-weibull",
  "language": "javascript",
  "library": "echarts",
  "page": "https://anyplot.ai/probability-weibull/javascript/echarts",
  "hub": "https://anyplot.ai/probability-weibull",
  "code_json": "https://api.anyplot.ai/specs/probability-weibull/echarts/code",
  "spec_json": "https://api.anyplot.ai/specs/probability-weibull",
  "render_light_png": "https://storage.googleapis.com/anyplot-images/plots/probability-weibull/javascript/echarts/plot-light.png",
  "render_dark_png": "https://storage.googleapis.com/anyplot-images/plots/probability-weibull/javascript/echarts/plot-dark.png",
  "interactive_light_html": "https://storage.googleapis.com/anyplot-images/plots/probability-weibull/javascript/echarts/plot-light.html",
  "interactive_dark_html": "https://storage.googleapis.com/anyplot-images/plots/probability-weibull/javascript/echarts/plot-dark.html",
  "quality_score": 90.0,
  "license": "MIT",
  "guide": "https://anyplot.ai/llms.txt"
}

Part of Weibull Probability Plot for Reliability Analysis on anyplot.ai.

Other implementations