-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patherror-bar-generator.html
More file actions
488 lines (444 loc) · 44.1 KB
/
Copy patherror-bar-generator.html
File metadata and controls
488 lines (444 loc) · 44.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
<!DOCTYPE html>
<html lang="en" class="light">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Error Bar Generator | Calculate SD, SEM, & CI | STEMKit</title>
<meta name="title" content="Error Bar Generator | Calculate SD, SEM, & CI | STEMKit">
<meta name="description" content="Compute Mean, SD, SEM, median, IQR and 95% Confidence Intervals from raw replicate data, render a publication-ready error-bar plot (SD/SEM/CI), and export it as PNG or SVG.">
<meta name="keywords" content="error bar calculator, standard deviation calculator, standard error of the mean, 95% confidence interval, scientific plotting, STEMKit">
<link rel="canonical" href="https://stemkit.net/error-bar-generator.html">
<meta property="og:url" content="https://stemkit.net/error-bar-generator.html">
<meta property="twitter:url" content="https://stemkit.net/error-bar-generator.html">
<meta property="og:title" content="Error Bar Generator | Calculate SD, SEM, & CI">
<meta property="twitter:title" content="Error Bar Generator | Calculate SD, SEM, & CI">
<meta property="og:description" content="Instantly calculate Mean, SD, SEM, and 95% CI from raw replicate data locally.">
<meta property="twitter:description" content="Instantly calculate Mean, SD, SEM, and 95% CI from raw replicate data locally.">
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebApplication",
"name": "STEMKit Error Bar Generator",
"url": "https://stemkit.net/error-bar-generator.html",
"description": "Calculate Mean, SD, SEM, and 95% CI from raw data.",
"author": { "@type": "Person", "name": "Olanrewaju M. Daramola" },
"applicationCategory": "UtilityApplication",
"operatingSystem": "All",
"browserRequirements": "Requires JavaScript",
"offers": { "@type": "Offer", "price": "0", "priceCurrency": "USD" },
"featureList": [ "Instant Statistical Generation", "Data Array Parsing", "Local Execution", "100% Client-Side" ]
}
</script>
<meta name="author" content="Olanrewaju M. Daramola">
<meta name="theme-color" content="#4f46e5">
<meta property="og:type" content="website">
<meta property="og:image" content="https://stemkit.net/assets/og-image.webp">
<meta property="twitter:card" content="summary_large_image">
<meta property="twitter:image" content="https://stemkit.net/assets/og-image.webp">
<link rel="icon" type="image/x-icon" href="https://stemkit.net/assets/favicon.ico">
<link rel="icon" type="image/png" sizes="32x32" href="https://stemkit.net/assets/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="https://stemkit.net/assets/favicon-16x16.png">
<link rel="apple-touch-icon" href="https://stemkit.net/assets/apple-touch-icon.png">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="css/all.min.css">
<link rel="stylesheet" href="css/dependencies/katex.min.css"> <script defer src="js/dependencies/katex.min.js"></script>
<script src="js/dependencies/jstat.min.js"></script>
<script src="js/dependencies/papaparse.min.js"></script>
<script type="application/ld+json">
{"@context": "https://schema.org", "@type": "HowTo", "name": "How to compute error bars", "totalTime": "PT2M", "step": [{"@type": "HowToStep", "position": 1, "name": "Arrange your data", "text": "One group per row: a text label in the first column, then its replicate measurements across the remaining columns. Or click one of the example chips to try sample data."}, {"@type": "HowToStep", "position": 2, "name": "Set options", "text": "Leave First row is a header on Auto-detect (it detects whether the top row names the columns), then choose a confidence level (90/95/99%) and number of decimals."}, {"@type": "HowToStep", "position": 3, "name": "Calculate and plot", "text": "Click Calculate Metrics for the stats table (mean, SD, SEM, median, IQR, CV, t*, CI) and the error-bar plot. Toggle bars between SD, SEM and CI; non-overlapping CIs are flagged as a significance cue."}, {"@type": "HowToStep", "position": 4, "name": "Export", "text": "Download the plot as PNG or SVG, or the full table with CI bounds as CSV."}]}
</script>
<script type="application/ld+json">
{"@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [{"@type": "Question", "name": "Is my data uploaded anywhere?", "acceptedAnswer": {"@type": "Answer", "text": "No. Parsing and all statistics run locally in your browser via PapaParse and jStat."}}, {"@type": "Question", "name": "Which standard deviation is used?", "acceptedAnswer": {"@type": "Answer", "text": "The sample standard deviation (Bessel's correction, dividing by n−1), the usual choice for summarising experimental replicates."}}, {"@type": "Question", "name": "How is the confidence interval computed?", "acceptedAnswer": {"@type": "Answer", "text": "As mean ± t* × SEM, where t* is the two-tailed Student-t critical value for your chosen level with n−1 degrees of freedom."}}, {"@type": "Question", "name": "What data layout is expected?", "acceptedAnswer": {"@type": "Answer", "text": "One group per row: a label in the first column followed by that group's replicate values. Wide (several replicate columns) and long (a single value column) layouts both work."}}, {"@type": "Question", "name": "Why is the CI blank or zero for a group?", "acceptedAnswer": {"@type": "Answer", "text": "A group needs at least two values to estimate variability; single-measurement groups report zero SD/SEM/CI."}}]}
</script>
<link rel="stylesheet" href="src/home.css">
<link rel="stylesheet" href="src/output.css">
<link rel="stylesheet" href="src/stemkit-docs.css">
<link rel="stylesheet" href="src/tools/error-bar-generator.css">
</head>
<body class="bg-slate-50 dark:bg-slate-900 text-slate-900 dark:text-slate-100 min-h-screen flex flex-col transition-colors duration-300">
<nav class="sticky top-0 z-50 w-full bg-white/80 dark:bg-slate-950/80 backdrop-blur-md border-b border-slate-200 dark:border-slate-800 transition-colors duration-300">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between items-center h-16 sm:h-20">
<a href="index.html" class="flex items-center gap-2 hover:opacity-80 transition-opacity">
<div class="bg-indigo-600 text-white p-2 sm:p-2.5 rounded-lg shadow-sm flex items-center justify-center">
<i class="fa-solid fa-flask text-lg sm:text-xl"></i>
</div>
<span class="text-xl sm:text-2xl font-black tracking-tighter text-slate-900 dark:text-white">STEMKit</span>
</a>
<div class="hidden md:flex items-center gap-6 text-sm font-semibold text-slate-600 dark:text-slate-300">
<a href="index.html#data-tools" class="hover:text-indigo-600 dark:hover:text-indigo-400 transition-colors">Data</a>
<a href="index.html#comp-tools" class="hover:text-indigo-600 dark:hover:text-indigo-400 transition-colors">Compute</a>
<a href="index.html#pub-tools" class="hover:text-indigo-600 dark:hover:text-indigo-400 transition-colors">Writing & Citations</a>
<a href="index.html#focus-tools" class="hover:text-indigo-600 dark:hover:text-indigo-400 transition-colors">Focus</a>
<div class="h-5 w-px bg-slate-200 dark:bg-slate-700"></div>
<button class="themeToggle p-2 rounded-full hover:bg-slate-100 dark:hover:bg-slate-800 transition-colors" aria-label="Toggle dark mode">
<i class="fa-solid fa-moon dark:hidden text-lg"></i>
<i class="fa-solid fa-sun hidden dark:block text-yellow-400 text-lg"></i>
</button>
<a href="plot-digitizer.html" class="bg-indigo-600 hover:bg-indigo-700 text-white px-5 py-2.5 rounded-full text-sm font-bold transition-all shadow-md hover:shadow-lg">
<i class="fa-solid fa-crosshairs mr-1"></i> Plot Digitizer
</a>
</div>
<div class="flex items-center gap-2 md:hidden">
<button class="themeToggle p-2 rounded-full hover:bg-slate-100 dark:hover:bg-slate-800 transition-colors text-slate-600 dark:text-slate-300">
<i class="fa-solid fa-moon dark:hidden text-lg"></i>
<i class="fa-solid fa-sun hidden dark:block text-yellow-400 text-lg"></i>
</button>
<button id="mobile-menu-btn" class="text-slate-600 dark:text-slate-300 hover:text-indigo-600 p-2 focus:outline-none">
<i class="fa-solid fa-bars text-2xl" id="menu-icon"></i>
</button>
</div>
</div>
</div>
<div id="mobile-menu" class="hidden md:hidden bg-white/95 dark:bg-slate-900/95 backdrop-blur-md border-b border-slate-200 dark:border-slate-800 absolute w-full shadow-xl">
<div class="px-4 pt-2 pb-6 space-y-2 text-base font-semibold text-slate-600 dark:text-slate-300">
<a href="index.html#data-tools" class="mobile-link block py-3 px-4 rounded-xl hover:bg-slate-50 dark:hover:bg-slate-800 hover:text-indigo-600 transition-colors">Data & Stats</a>
<a href="index.html#comp-tools" class="mobile-link block py-3 px-4 rounded-xl hover:bg-slate-50 dark:hover:bg-slate-800 hover:text-indigo-600 transition-colors">Compute</a>
<a href="index.html#pub-tools" class="mobile-link block py-3 px-4 rounded-xl hover:bg-slate-50 dark:hover:bg-slate-800 hover:text-indigo-600 transition-colors">Writing & Citations</a>
<a href="index.html#focus-tools" class="mobile-link block py-3 px-4 rounded-xl hover:bg-slate-50 dark:hover:bg-slate-800 hover:text-indigo-600 transition-colors">Focus & Flow</a>
<div class="pt-4 mt-2 border-t border-slate-100 dark:border-slate-800">
<a href="plot-digitizer.html" class="block text-center bg-indigo-600 hover:bg-indigo-700 text-white py-3 rounded-xl shadow-md transition-colors">Digitizer Pro</a>
</div>
</div>
</div>
</nav>
<main class="flex-grow max-w-7xl mx-auto px-6 py-8 w-full flex flex-col gap-6">
<div class="mb-4">
<h1 class="text-3xl font-bold mb-2">Error Bar Generator</h1>
<p class="text-slate-500 dark:text-slate-400">Paste raw experimental replicates or upload a CSV to instantly compute the Mean, SD, SEM, median, IQR and Confidence Interval per group, then render a publication-ready error-bar plot with SD/SEM/CI toggle and export it as PNG or SVG.</p>
<p class="text-xs text-slate-400 mt-3">100% client-side</p>
</div>
<div class="grid grid-cols-1 lg:grid-cols-12 gap-8">
<div class="lg:col-span-4 flex flex-col gap-6">
<div class="bg-white dark:bg-slate-950 border border-slate-200 dark:border-slate-800 rounded-2xl p-6 shadow-sm flex flex-col flex-grow">
<div class="flex justify-between items-end mb-4">
<h2 class="text-lg font-semibold">1. Input Replicate Data</h2>
<label class="cursor-pointer bg-indigo-50 dark:bg-indigo-900/30 text-indigo-600 dark:text-indigo-400 px-3 py-1.5 rounded text-sm font-medium hover:bg-indigo-100 dark:hover:bg-indigo-900/50 transition-colors">
<i class="fa-solid fa-upload mr-1"></i> Upload CSV
<input type="file" id="fileInput" accept=".csv,.txt" class="hidden">
</label>
</div>
<textarea id="dataInput" class="w-full flex-grow min-h-[300px] bg-slate-50 dark:bg-slate-900 border border-slate-200 dark:border-slate-700 rounded-xl p-4 text-xs font-mono focus:ring-2 focus:ring-indigo-500 outline-none resize-y whitespace-pre" placeholder="Label	Rep1	Rep2	Rep3 Ctrl	4.5	4.2	4.8 Trt1	6.1	6.5	6.2 Trt2	8.3	8.1	8.9"></textarea>
<div class="mt-4">
<div class="flex items-center gap-2 text-sm text-slate-600 dark:text-slate-400 mb-4">
<label for="hasHeaders">First row is a header:</label>
<select id="hasHeaders" class="bg-slate-50 dark:bg-slate-900 border border-slate-200 dark:border-slate-700 rounded-lg px-2 py-1 text-sm focus:ring-2 focus:ring-indigo-500 outline-none">
<option value="auto" selected>Auto-detect</option>
<option value="yes">Yes</option>
<option value="no">No</option>
</select>
<span class="text-xs text-slate-400" title="A header row names the columns (e.g. Label, Rep1, Rep2). Auto-detect works for most data."><i class="fa-solid fa-circle-question"></i></span>
</div>
<div class="flex items-center gap-3 mb-4 flex-wrap">
<label class="text-sm text-slate-600 dark:text-slate-400">Confidence level
<select id="ciLevel" class="ml-2 bg-slate-50 dark:bg-slate-900 border border-slate-200 dark:border-slate-700 rounded-lg px-2 py-1 text-sm focus:ring-2 focus:ring-indigo-500 outline-none">
<option value="0.90">90%</option>
<option value="0.95" selected>95%</option>
<option value="0.99">99%</option>
</select>
</label>
<label class="text-sm text-slate-600 dark:text-slate-400">Decimals
<select id="decimals" class="ml-2 bg-slate-50 dark:bg-slate-900 border border-slate-200 dark:border-slate-700 rounded-lg px-2 py-1 text-sm focus:ring-2 focus:ring-indigo-500 outline-none">
<option value="2">2</option>
<option value="3">3</option>
<option value="4" selected>4</option>
<option value="6">6</option>
</select>
</label>
</div>
<div class="eb-samples">
<span class="eb-samples-label"><i class="fa-solid fa-flask-vial"></i> Try an example:</span>
<div class="eb-chips">
<button class="eb-chip" data-sample="basic" title="3 groups, clear separation | significance cue fires.">Basic</button>
<button class="eb-chip" data-sample="overlap" title="Groups close & variable, CIs overlap, no significance.">Overlapping CIs</button>
<button class="eb-chip" data-sample="many" title="6 groups (pH series) | palette cycling.">Many groups</button>
<button class="eb-chip" data-sample="ragged" title="Different replicate counts per group.">Ragged n</button>
<button class="eb-chip" data-sample="negative" title="Negative means and a group crossing zero.">Negatives</button>
<button class="eb-chip" data-sample="messy" title="Blank lines and a stray text row | robust parsing.">Messy data</button>
</div>
</div>
<button id="calculateBtn" class="bg-indigo-600 hover:bg-indigo-700 text-white w-full py-3 rounded-xl font-bold transition-all duration-150 shadow-sm hover:shadow-md active:scale-[0.98] focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-2 dark:focus-visible:ring-offset-slate-950 flex items-center justify-center gap-2">
<i class="fa-solid fa-calculator text-sm"></i> Calculate Metrics
</button>
</div>
</div>
<div class="bg-indigo-50 dark:bg-indigo-900/20 border border-indigo-200 dark:border-indigo-800/50 rounded-xl p-5 text-sm text-indigo-800 dark:text-indigo-300">
<strong class="block mb-2"><i class="fa-solid fa-graduation-cap mr-1"></i> Which error bar to use?</strong>
<ul class="list-disc pl-4 space-y-1">
<li><strong>SD:</strong> Shows the variability/scatter of your raw data.</li>
<li><strong>SEM:</strong> Shows the precision of your mean estimate.</li>
<li><strong>95% CI:</strong> Shows the range where the true population mean lies with 95% certainty. Best for visual significance testing.</li>
</ul>
</div>
</div>
<div class="lg:col-span-8 flex flex-col h-full gap-6">
<!-- PLOT PANEL -->
<div class="bg-white dark:bg-slate-950 border border-slate-200 dark:border-slate-800 rounded-2xl shadow-sm overflow-hidden">
<div class="bg-slate-50 dark:bg-slate-900 border-b border-slate-200 dark:border-slate-800 p-4 flex flex-wrap justify-between items-center gap-3">
<h2 class="text-sm font-bold text-slate-700 dark:text-slate-300 uppercase tracking-wider">Error Bar Plot</h2>
<div class="flex items-center gap-2 flex-wrap">
<div class="errmode-tabs">
<button class="errmode-tab" data-errmode="sd">SD</button>
<button class="errmode-tab" data-errmode="sem">SEM</button>
<button class="errmode-tab errmode-active" data-errmode="ci">CI</button>
</div>
<button id="exportPngBtn" class="px-3 py-1.5 bg-white dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-md text-xs font-bold text-slate-600 dark:text-slate-300 hover:text-indigo-600 transition-colors shadow-sm"><i class="fa-solid fa-image mr-1"></i> PNG</button>
<button id="exportSvgBtn" class="px-3 py-1.5 bg-white dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-md text-xs font-bold text-slate-600 dark:text-slate-300 hover:text-indigo-600 transition-colors shadow-sm"><i class="fa-solid fa-bezier-curve mr-1"></i> SVG</button>
</div>
</div>
<div class="p-4">
<details class="plot-customize group mb-4">
<summary class="cursor-pointer list-none flex items-center justify-between px-3 py-2 rounded-lg bg-slate-50 dark:bg-slate-900 border border-slate-200 dark:border-slate-700 text-sm font-semibold text-slate-700 dark:text-slate-300">
<span><i class="fa-solid fa-sliders mr-2 text-indigo-500"></i> Customize plot</span>
<i class="fa-solid fa-chevron-down text-slate-400 group-open:rotate-180 transition-transform"></i>
</summary>
<div class="cz-grid">
<label class="cz-field cz-span2"><span>Chart title</span>
<input id="optTitle" type="text" placeholder="(optional)" class="cz-input">
</label>
<label class="cz-field cz-span2"><span>Y-axis label</span>
<input id="optYLabel" type="text" placeholder="Auto: Mean ± error" class="cz-input">
</label>
<label class="cz-field"><span>Bar style</span>
<select id="optBarStyle" class="cz-input">
<option value="fill">Filled</option>
<option value="outline">Outline</option>
</select>
</label>
<label class="cz-field"><span>Color palette</span>
<select id="optPalette" class="cz-input">
<option value="default">Default</option>
<option value="blue">Blues</option>
<option value="viridis">Viridis</option>
<option value="warm">Warm</option>
<option value="gray">Grayscale</option>
</select>
</label>
<label class="cz-field"><span>Bar width <b id="optBarWidthVal">55</b>%</span>
<input id="optBarWidth" type="range" min="20" max="95" value="55" class="cz-range">
</label>
<label class="cz-field"><span>Corner radius <b id="optBarRadiusVal">3</b></span>
<input id="optBarRadius" type="range" min="0" max="16" value="3" class="cz-range">
</label>
<label class="cz-field"><span>Bar opacity <b id="optBarOpacityVal">85</b>%</span>
<input id="optBarOpacity" type="range" min="20" max="100" value="85" class="cz-range">
</label>
<label class="cz-field"><span>Error cap width <b id="optCapWidthVal">12</b></span>
<input id="optCapWidth" type="range" min="0" max="30" value="12" class="cz-range">
</label>
<label class="cz-field"><span>Y-axis min</span>
<input id="optYMin" type="text" placeholder="auto" class="cz-input">
</label>
<label class="cz-field"><span>Y-axis max</span>
<input id="optYMax" type="text" placeholder="auto" class="cz-input">
</label>
<div class="cz-toggles cz-span2">
<label class="cz-check"><input id="optGridlines" type="checkbox" checked> Gridlines</label>
<label class="cz-check"><input id="optShowN" type="checkbox" checked> n counts</label>
<label class="cz-check"><input id="optShowValues" type="checkbox"> Value labels</label>
<label class="cz-check"><input id="optShowLegend" type="checkbox"> Legend</label>
</div>
<div class="cz-span2 flex justify-end">
<button id="resetPlotBtn" class="text-xs font-semibold text-slate-500 dark:text-slate-400 hover:text-indigo-600 transition-colors"><i class="fa-solid fa-rotate-left mr-1"></i> Reset style</button>
</div>
</div>
</details>
<div id="plotEmpty" class="py-20 text-center text-slate-400 text-sm">
<i class="fa-solid fa-chart-column text-3xl mb-3 opacity-40"></i>
<p>Calculate metrics to render the error-bar plot.</p>
</div>
<div id="plotHost" class="w-full"></div>
<div id="sigNote" class="sig-note" style="display:none;"></div>
</div>
</div>
<!-- TABLE PANEL -->
<div class="bg-white dark:bg-slate-950 border border-slate-200 dark:border-slate-800 rounded-2xl shadow-sm flex flex-col flex-grow overflow-hidden">
<div class="bg-slate-50 dark:bg-slate-900 border-b border-slate-200 dark:border-slate-800 p-4 flex justify-between items-center">
<h2 class="text-sm font-bold text-slate-700 dark:text-slate-300 uppercase tracking-wider">Computed Statistics</h2>
<button id="exportCsvBtn" class="px-4 py-1.5 bg-white dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-md text-xs font-bold text-slate-600 dark:text-slate-300 hover:text-indigo-600 transition-colors shadow-sm disabled:opacity-50" disabled>
<i class="fa-solid fa-download mr-1"></i> Export CSV
</button>
</div>
<div class="table-container overflow-auto flex-grow relative bg-white dark:bg-slate-950">
<table class="w-full text-left text-sm whitespace-nowrap">
<thead class="bg-slate-100 dark:bg-slate-800 sticky top-0 shadow-sm z-10">
<tr>
<th class="px-3 py-3 font-semibold text-slate-700 dark:text-slate-300 border-r border-slate-200 dark:border-slate-700">Label</th>
<th class="px-3 py-3 font-semibold text-slate-700 dark:text-slate-300">N</th>
<th class="px-3 py-3 font-semibold text-slate-700 dark:text-slate-300">Mean</th>
<th class="px-3 py-3 font-semibold text-slate-700 dark:text-slate-300" title="Standard Deviation">SD</th>
<th class="px-3 py-3 font-semibold text-slate-700 dark:text-slate-300" title="Standard Error of the Mean">SEM</th>
<th class="px-3 py-3 font-semibold text-slate-700 dark:text-slate-300" title="Median">Median</th>
<th class="px-3 py-3 font-semibold text-slate-700 dark:text-slate-300" title="Interquartile range (Q3 − Q1)">IQR</th>
<th class="px-3 py-3 font-semibold text-slate-700 dark:text-slate-300" title="Coefficient of variation (SD/mean)">CV</th>
<th class="px-3 py-3 font-semibold text-slate-700 dark:text-slate-300" title="Minimum / Maximum">Min/Max</th>
<th class="px-3 py-3 font-semibold text-slate-700 dark:text-slate-300" title="Student's t critical value (df = n-1)">t*</th>
<th id="ciHeader" class="px-3 py-3 font-semibold text-slate-700 dark:text-slate-300" title="Confidence interval half-width">95% CI (±)</th>
</tr>
</thead>
<tbody id="resultsBody" class="divide-y divide-slate-100 dark:divide-slate-800/50">
<tr>
<td colspan="11" class="px-4 py-16 text-center text-slate-400">
Paste data or upload a CSV to view metrics.
</td>
</tr>
</tbody>
</table>
</div>
<details class="group bg-slate-50 dark:bg-slate-900/50 border-t border-slate-200 dark:border-slate-700 transition-all mt-auto">
<summary class="px-4 py-3 text-sm font-bold text-slate-700 dark:text-slate-300 cursor-pointer list-none flex justify-between items-center">
<span><i class="fa-solid fa-square-root-variable mr-2 text-indigo-500"></i> Mathematical Theory</span>
<i class="fa-solid fa-chevron-down text-slate-400 group-open:rotate-180 transition-transform"></i>
</summary>
<div class="px-4 pb-4 pt-2 border-t border-slate-200 dark:border-slate-700 text-sm text-slate-600 dark:text-slate-400">
<div id="theoryContainer" class="overflow-x-auto py-2"></div>
<div id="theoryDefs"></div>
</div>
</details>
</div>
</div>
</div>
<section class="stk-section" id="how-to-use" aria-label="How to use this tool">
<div class="stk-wrap">
<span class="stk-chip"><i class="fa-solid fa-chart-column"></i> How-To Guide</span>
<h2 class="stk-h2">How to compute error bars</h2>
<p class="stk-lead">Paste replicate measurements (or upload a CSV) with one group per row, and get the mean, SD, SEM, median, IQR and a Student-t confidence interval per group, plus a publication-ready error-bar plot.</p>
<div class="stk-grid stk-grid-2"><div class="stk-step"><span class="stk-num">1</span><div><h3>Arrange your data</h3><p>One group per row: a text label in the first column, then its replicate measurements across the remaining columns. Or click an example chip (Basic, Overlapping CIs, Many groups…) to load sample data.</p></div></div><div class="stk-step"><span class="stk-num">2</span><div><h3>Set options</h3><p>Leave <em>First row is a header</em> on <strong>Auto-detect</strong> (it figures out whether your top row names the columns), then choose a confidence level (90/95/99%) and the number of decimals.</p></div></div><div class="stk-step"><span class="stk-num">3</span><div><h3>Calculate & plot</h3><p>Click <strong>Calculate Metrics</strong> for the full stats table and the error-bar plot. Toggle the bars between <strong>SD</strong>, <strong>SEM</strong> and <strong>CI</strong>; non-overlapping CIs are flagged as a significance cue.</p></div></div><div class="stk-step"><span class="stk-num">4</span><div><h3>Export</h3><p>Download the plot as <strong>PNG</strong> or <strong>SVG</strong> for papers and slides, or the full table (with CI bounds) as <strong>CSV</strong>.</p></div></div></div>
</div>
</section>
<section class="stk-section" id="how-it-works" aria-label="How it works">
<div class="stk-wrap">
<h2 class="stk-h2">How the calculation works</h2>
<div class="stk-grid stk-grid-2"><div class="stk-card"><h3 style="font-weight:700;margin-bottom:.4rem;">Per-group pooling</h3><p style="font-size:.88rem;color:#64748b;line-height:1.6;">Each row's numeric values are pooled as replicates of that group. Statistics use the <em>sample</em> standard deviation (dividing by n−1), matching how experimental replicates are normally summarised.</p></div><div class="stk-card"><h3 style="font-weight:700;margin-bottom:.4rem;">Student-t intervals</h3><p style="font-size:.88rem;color:#64748b;line-height:1.6;">Confidence intervals use the two-tailed Student-t critical value with n−1 degrees of freedom, appropriate for the small samples typical in the lab, and wider (more honest) than a normal-approximation interval.</p></div></div>
<div class="stk-note" style="margin-top:1rem;"><i class="fa-solid fa-circle-info" style="margin-top:.15rem;"></i><div>Choose deliberately: <strong>SD</strong> shows the scatter of the raw data, <strong>SEM</strong> shows how precisely the mean is estimated, and the <strong>CI</strong> indicates where the true mean plausibly lies. SEM is always smaller than SD and should never be used to imply low variability.</div></div>
</div>
</section>
<section class="stk-section" id="method" aria-label="Method and equations">
<div class="stk-wrap" style="max-width:52rem;">
<span class="stk-chip"><i class="fa-solid fa-square-root-variable"></i> Method & Equations</span>
<h2 class="stk-h2">The statistics behind the error bars</h2>
<p class="stk-lead">For each group the tool pools the replicate values and computes the mean, the <em>sample</em> standard deviation, the standard error of the mean, and a Student-<em>t</em> confidence interval.</p>
<p class="stk-eqn-label">Mean of <math><mi>n</mi></math> replicates:</p>
<div class="stk-math"><math display="block"><mover><mi>x</mi><mo>¯</mo></mover><mo>=</mo><mfrac><mn>1</mn><mi>n</mi></mfrac><munderover><mo>∑</mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mrow><mi>n</mi></mrow></munderover><msub><mi>x</mi><mi>i</mi></msub></math></div>
<p class="stk-eqn-label">Sample standard deviation (Bessel-corrected, dividing by <math><mi>n</mi><mo>−</mo><mn>1</mn></math>):</p>
<div class="stk-math"><math display="block"><mi>s</mi><mo>=</mo><msqrt><mfrac><mrow><munderover><mo>∑</mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mrow><mi>n</mi></mrow></munderover><msup><mrow><mo>(</mo><msub><mi>x</mi><mi>i</mi></msub><mo>−</mo><mover><mi>x</mi><mo>¯</mo></mover><mo>)</mo></mrow><mn>2</mn></msup></mrow><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow></mfrac></msqrt></math></div>
<p class="stk-eqn-label">Standard error of the mean:</p>
<div class="stk-math"><math display="block"><mi>SE</mi><mo>=</mo><mfrac><mi>s</mi><msqrt><mi>n</mi></msqrt></mfrac></math></div>
<p class="stk-eqn-label">Confidence interval (default 95%; selectable 90/95/99%):</p>
<div class="stk-math"><math display="block"><mtext>CI</mtext><mo>=</mo><mover><mi>x</mi><mo>¯</mo></mover><mo>±</mo><msub><mi>t</mi><mrow><mi>α</mi><mo>/</mo><mn>2</mn><mo>,</mo><mspace width="0.15em"/><mi>n</mi><mo>−</mo><mn>1</mn></mrow></msub><mo>·</mo><mi>SE</mi></math></div>
<p class="stk-where">where <math><mover><mi>x</mi><mo>¯</mo></mover></math> is the group mean, <math><mi>s</mi></math> the sample standard deviation, <math><mi>SE</mi></math> the standard error, and <math><msub><mi>t</mi><mrow><mi>α</mi><mo>/</mo><mn>2</mn><mo>,</mo><mi>n</mi><mo>−</mo><mn>1</mn></mrow></msub></math> the two-tailed Student-<em>t</em> critical value with <math><mi>n</mi><mo>−</mo><mn>1</mn></math> degrees of freedom. Groups with <math><mi>n</mi><mo>=</mo><mn>1</mn></math> report zero spread. Use <strong>SD</strong> to show data scatter, <strong>SEM</strong> for the precision of the mean, and the <strong>CI</strong> for inference about the true mean.</p>
<p class="stk-eqn-label" style="margin-top:1.5rem;">Robust spread statistics (reported alongside the mean-based measures):</p>
<p class="stk-where">The <strong>median</strong> (<math><mover><mi>x</mi><mo>~</mo></mover></math>) is the middle value once sorted, unlike the mean, it is unaffected by a single extreme replicate. The <strong>interquartile range</strong>, <math><mi>IQR</mi><mo>=</mo><msub><mi>Q</mi><mn>3</mn></msub><mo>−</mo><msub><mi>Q</mi><mn>1</mn></msub></math>, measures the spread of the central 50% of the data (quartiles computed by linear interpolation). The <strong>coefficient of variation</strong>, <math><mi>CV</mi><mo>=</mo><mfrac><mi>s</mi><mrow><mo>|</mo><mover><mi>x</mi><mo>¯</mo></mover><mo>|</mo></mrow></mfrac><mo>×</mo><mn>100</mn><mo>%</mo></math>, expresses variability relative to the mean, letting you compare scatter across groups measured on different scales. The <strong>min/max</strong> give the raw range of replicates. Together these let you check whether a group's mean-based error bars might be distorted by skew or outliers, if the mean and median diverge sharply, prefer the robust measures.</p>
<h3 class="stk-refs-h">References & documentation</h3>
<ol class="stk-refs-list">
<li>Altman, D. G., & Bland, J. M. (2005). Standard deviations and standard errors. <em>BMJ</em>, 331(7521), 903.</li>
<li>Cumming, G., Fidler, F., & Vaux, D. L. (2007). Error bars in experimental biology. <em>Journal of Cell Biology</em>, 177(1), 7–11.</li>
<li>Heckert, N. A., Filliben, J. J., Croarkin, C., et al. (2002). <em>NIST/SEMATECH e-Handbook of Statistical Methods</em>, §7.2. <a href="https://www.itl.nist.gov/div898/handbook/" target="_blank" rel="noopener">itl.nist.gov/div898/handbook</a>.</li>
<li>Cumming, G., & Finch, S. (2005). Inference by eye: Confidence intervals and how to read pictures of data. <em>American Psychologist</em>, 60(2), 170–180. <span style="opacity:.8">(basis for the non-overlapping-CI cue and its caveats)</span></li>
<li>Software: <a href="https://jstat.github.io/" target="_blank" rel="noopener">jStat</a> (t-distribution quantiles), <a href="https://www.papaparse.com/" target="_blank" rel="noopener">PapaParse</a> (CSV parsing), and <a href="https://katex.org/" target="_blank" rel="noopener">KaTeX</a> (equation typesetting). Plot rendered as dependency-free SVG.</li>
</ol>
</div>
</section>
<section class="stk-section" id="faq" aria-label="Frequently asked questions">
<div class="stk-wrap" style="max-width:52rem;">
<h2 class="stk-h2">Frequently asked questions</h2>
<div style="margin-top:1rem;"><details class="stk-faq"><summary>Is my data uploaded anywhere?</summary><div>No. Parsing and all statistics run locally in your browser via PapaParse and jStat.</div></details><details class="stk-faq"><summary>Which standard deviation is used?</summary><div>The sample standard deviation (Bessel's correction, dividing by n−1), the usual choice for summarising experimental replicates.</div></details><details class="stk-faq"><summary>How is the confidence interval computed?</summary><div>As mean ± t* × SEM, where t* is the two-tailed Student-t critical value for your chosen level with n−1 degrees of freedom.</div></details><details class="stk-faq"><summary>What data layout is expected?</summary><div>One group per row: a label in the first column followed by that group's replicate values. Wide (several replicate columns) and long (a single value column) layouts both work.</div></details><details class="stk-faq"><summary>Why is the CI blank or zero for a group?</summary><div>A group needs at least two values to estimate variability; single-measurement groups report zero SD/SEM/CI.</div></details></div>
<div class="stk-refs"><a href="https://www.itl.nist.gov/div898/handbook/" target="_blank" rel="noopener"><i class="fa-solid fa-book"></i> NIST e-Handbook</a><a href="https://en.wikipedia.org/wiki/Confidence_interval" target="_blank" rel="noopener"><i class="fa-solid fa-arrows-left-right"></i> Confidence interval</a><a href="https://en.wikipedia.org/wiki/Student%27s_t-distribution" target="_blank" rel="noopener"><i class="fa-solid fa-chart-area"></i> Student's t-distribution</a></div>
<p class="stk-credit">Statistics run entirely in your browser, no data leaves your device.</p>
</div>
</section>
</main>
<footer class="mt-auto border-t border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-950 py-12">
<div class="max-w-7xl mx-auto px-6">
<div class="stk-dir mb-12">
<div>
<h4><i class="fa-solid fa-chart-pie text-indigo-500 text-xs"></i> Data & Stats</h4>
<ul>
<li><a href="plot-digitizer.html">Plot Digitizer</a></li>
<li><a href="data-cleaner.html">Data Cleaner</a></li>
<li><a href="stats-calculator.html">Stat Calculator</a></li>
<li><a href="error-bar-generator.html">Error Bar Gen</a></li>
<li><a href="outlier-detector.html">Outlier Detector</a></li>
<li><a href="curve-fitter.html">Curve Fitter</a></li>
<li><a href="plot-builder.html">Plot Builder</a></li>
<li><a href="xvg-visualizer.html">XVG Visualizer</a></li>
</ul>
</div>
<div>
<h4><i class="fa-solid fa-microchip text-orange-500 text-xs"></i> Compute</h4>
<ul>
<li><a href="structure-inspector.html">3D Inspector</a></li>
<li><a href="coordinate-manipulator.html">Coordinate Manipulator</a></li>
<li><a href="scientific-converter.html">Energy Conversions</a></li>
<li><a href="script-generator.html">HPC Script Gen</a></li>
</ul>
</div>
<div>
<h4><i class="fa-solid fa-book-open text-teal-500 text-xs"></i> Writing & Citations</h4>
<ul>
<li><a href="latex-formatter.html">Equation Formatter</a></li>
<li><a href="latex-tables.html">Visual LaTeX Tables</a></li>
<li><a href="doi-fetcher.html">DOI to BibTeX</a></li>
<li><a href="bibtex-deduplicator.html">BibTeX Deduplicator</a></li>
<li><a href="bibtex-sanitizer.html">BibTeX Sanitizer</a></li>
<li><a href="journal-abbreviator.html">Journal Abbrev</a></li>
</ul>
</div>
<div>
<h4><i class="fa-solid fa-headphones text-fuchsia-500 text-xs"></i> Focus & Flow</h4>
<ul>
<li><a href="pomodoro.html">Ambient Pomodoro</a></li>
<li><a href="decision.html">Decision Matrix</a></li>
<li><a href="sandbox.html">Kinetic Sandbox</a></li>
</ul>
</div>
</div>
<div class="border-t border-slate-200 dark:border-slate-800 pt-8 flex flex-col md:flex-row items-center justify-between text-slate-500 dark:text-slate-400 gap-4">
<div class="flex items-center gap-2">
<i class="fa-solid fa-flask text-xl text-slate-300 dark:text-slate-700"></i>
<span class="font-bold text-slate-700 dark:text-slate-300">STEMKit</span>
</div>
<div class="text-center text-sm font-medium">© 2026 STEMKit. Built by <a href="https://github.com/LD-Shell" target="_blank" rel="noopener" class="font-semibold hover:text-indigo-500 transition-colors">Olanrewaju M. Daramola</a>.</div>
<div class="flex gap-6 text-sm font-medium">
<a href="privacy.html#privacy" class="hover:text-indigo-500 transition-colors">Privacy Policy</a>
<a href="privacy.html#terms" class="hover:text-indigo-500 transition-colors">Terms of Service</a>
</div>
</div>
</div>
</footer>
<div id="toastContainer" class="fixed bottom-6 right-6 z-50 flex flex-col gap-3"></div>
<script>
// 1. Theme toggle logic (Mobile & Desktop)
document.querySelectorAll('.themeToggle').forEach(btn => {
btn.addEventListener('click', () => {
document.documentElement.classList.toggle('dark');
localStorage.theme = document.documentElement.classList.contains('dark') ? 'dark' : 'light';
});
});
// 2. Mobile menu logic
const mobileMenuBtn = document.getElementById('mobile-menu-btn');
const mobileMenu = document.getElementById('mobile-menu');
const menuIcon = document.getElementById('menu-icon');
if(mobileMenuBtn) {
mobileMenuBtn.addEventListener('click', () => {
mobileMenu.classList.toggle('hidden');
if(mobileMenu.classList.contains('hidden')) {
menuIcon.classList.remove('fa-xmark');
menuIcon.classList.add('fa-bars');
} else {
menuIcon.classList.remove('fa-bars');
menuIcon.classList.add('fa-xmark');
}
});
document.querySelectorAll('.mobile-link').forEach(link => {
link.addEventListener('click', () => {
mobileMenu.classList.add('hidden');
menuIcon.classList.remove('fa-xmark');
menuIcon.classList.add('fa-bars');
});
});
}
</script>
<script type="module" src="js/error-bar-generator.js"></script>
</body>
</html>