PageSourceSearch

https://d3-graph-gallery.com/boxplot.html

html d3-graph-gallery.com collected 2026-10-02 05:06:36 UTC 19,842 bytes, 587 lines download raw bytes

1<!DOCTYPE html>
2<html lang="en">
3  <head>
4
5    <!-- Global site tag (gtag.js) - Google Analytics -->
vendor: 81 bytes, lines 5-9
5
6
7    <script
8      async
9      src="https://www.googletagmanager.com/gtag/js?id=
9UA-79254642-6
vendor: 22 bytes, lines 9-12
9"
10    ></script>
11
12    
12<script>
13      
vendor: 163 bytes, lines 13-19
13window.dataLayer = window.dataLayer || [];
14      function gtag() {
15        dataLayer.push(arguments);
16      }
17      gtag("js", new Date());
18
19      gtag("config", "
19UA-79254642-6
vendor: 8 bytes, lines 19-20
19");
20    
20</script>
20
21
22    <meta charset="utf-8" />
23    <title>Boxplot &#124; the D3 Graph Gallery</title>
24
25    <meta
26      name="viewport"
27      content="width=device-width, initial-scale=1, shrink-to-fit=no"
28    />
29    <meta
30      name="description"
31      content="How to build a boxplot with Javascript and D3.js: from the most basic example to highly customized examples."
32    />
33    <meta
34      name="keywords"
35      content="Data,Dataviz,Datavisualization,Javascript,D3,D3.js,boxplot"
36    />
37    <meta name="author" content="Yan Holtz" />
38    <link rel="icon" href="img/logo/D3_single_small.png" />
39
40    <meta property="og:title" content="Boxplot &#124; the D3 Graph Gallery" />
41    <meta property="og:image" content="img/overview_RGG.png" />
42    <meta
43      property="og:description"
44      content="How to build a boxplot with Javascript and D3.js: from the most basic example to highly customized examples."
45    />
46
47    <!-- Bootstrap core CSS -->
48    <link href="vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
49
50    <!-- Custom fonts for this template -->
51    <link
52      href="vendor/font-awesome/css/font-awesome.min.css"
53      rel="stylesheet"
54      type="text/css"
55    />
56    <link
57      href="https://fonts.googleapis.com/css?family=Montserrat:400,700"
58      rel="stylesheet"
59      type="text/css"
60    />
61    <link
62      href="https://fonts.googleapis.com/css?family=Kaushan+Script"
63      rel="stylesheet"
64      type="text/css"
65    />
66    <link
67      href="https://fonts.googleapis.com/css?family=Droid+Serif:400,700,400italic,700italic"
68      rel="stylesheet"
69      type="text/css"
70    />
71    <link
72      href="https://fonts.googleapis.com/css?family=Roboto+Slab:400,100,300,700"
73      rel="stylesheet"
74      type="text/css"
75    />
76
77    <!-- Custom styles for this template -->
78    <link href="css/agency.css" rel="stylesheet" />
79
80    <!-- JQUERY -->
81    
81<script src="vendor/jquery/jquery.min.js"></script>
81
82
83    <!-- d3.v4 and Plugin for color scale -->
84    
84<script src="js/d3.v4.js"></script>
84
85    
85<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
85
86  </head>
87
88  <body id="page-top">
89    <!-- THIS ALLOWS TO INSERT THE MENU THAT IS STORED IN A MENU.HTML FILE-->
90    <nav class="navbar navbar-expand-lg fixed-top" id="mainNav"></nav>
91    
91<script>
92      $(function () {
93        $("#mainNav").load("html_chunk/menu.html");
94      });
95    </script>
95
96
97    <!-- THIS ALLOWS TO INSERT THE MODAL OF THE MENU THAT IS STORED IN A MENU_MODAL.HTML FILE-->
98    <div id="modal_menu_insertion"></div>
99    
99<script>
100      $(function () {
101        $("#modal_menu_insertion").load("html_chunk/menu_modal.html");
102      });
103    </script>
103
104
105    <!-- Header -->
106    <header class="masthead" style="padding-top: 150px; padding-bottom: 80px">
107      <div class="textlanding">
108        <h1>Boxplot</h1>
109        <hr class="short_hr" />
110        <br />
111        <ul class="list-inline social-buttons">
112          <li class="list-inline-item">
113            <a href="https://twitter.com/R_Graph_Gallery">
114              <i class="fa fa-twitter"></i>
115            </a>
116          </li>
117          <li class="list-inline-item social-buttons">
118            <a href="https://github.com/holtzy">
119              <i class="fa fa-github" style="color: white"></i>
120            </a>
121          </li>
122          <li class="list-inline-item social-buttons">
123            <a href="https://www.linkedin.com/in/yan-holtz-2477534a/">
124              <i class="fa fa-linkedin"></i>
125            </a>
126          </li>
127          <li class="list-inline-item social-buttons">
128            <a href="https://www.yan-holtz.com">
129              <i class="fa fa-home"></i>
130            </a>
131          </li>
132        </ul>
133        <br /><br />
134        <p style="max-width: 700px; margin: auto">
135          This is the
136          <a href="https://www.data-to-viz.com/caveat/boxplot.html">boxplot</a>
137          section of the gallery. If you want to know more about this kind of
138          chart, visit
139          <a href="https://www.data-to-viz.com/caveat/boxplot.html"
140            >data-to-viz.com</a
141          >. If you're looking for a simple way to implement it in d3.js, pick
142          an example below.
143        </p>
144      </div>
145    </header>
146
147
148    <!-- ======================== PORTFOLIO SECTION ============================ --><!-- Images must be 480 x 480, resize them with ./script_reformat_img.sh output_name.png -->
149    <section class="bg" id="portfolio" style="padding-top: 10px">
150      <div class="container">
151        <div class="mySeryTitle">Step by step</div>
152        <hr />
153        <div id="portfolio-items" class="row">
154          <div class="col-md-4 col-sm-6 portfolio-item">
155            <a class="portfolio-link" href="graph/boxplot_basic.html">
156              <div class="portfolio-hover">
157                <div class="portfolio-hover-content">
158                  <p>Most basic</p>
159                  <hr />
160                  <p class="explanation_portfolio">
161                    The most basic boxplot you can do in d3.js. Keeping only the
162                    core code. Starts with an array of data.
163                  </p>
164                </div>
165              </div>
166              <img class="img-fluid" src="img/graph/boxplot_basic.png" alt="" />
167            </a>
168          </div>
169          <div class="col-md-4 col-sm-6 portfolio-item">
170            <a class="portfolio-link" href="graph/boxplot_several_groups.html">
171              <div class="portfolio-hover">
172                <div class="portfolio-hover-content">
173                  <p>With several group</p>
174                  <hr />
175                  <p class="explanation_portfolio">
176                    A boxplot with several groups. It extends the technique used
177                    on the previous chart. The tricky part is to computed
178                    summary statistics for each group.
179                  </p>
180                </div>
181              </div>
182              <img
183                class="img-fluid"
184                src="img/graph/boxplot_several_groups.png"
185                alt=""
186              />
187            </a>
188          </div>
189          <div class="col-md-4 col-sm-6 portfolio-item">
190            <a
191              class="portfolio-link"
192              href="graph/boxplot_show_individual_points.html"
193            >
194              <div class="portfolio-hover">
195                <div class="portfolio-hover-content">
196                  <p>Show individual data points</p>
197                  <hr />
198                  <p class="explanation_portfolio">
199                    The major downside of boxplot is that it hides the
200                    underlying data points. It is a good practice to show them
201                    using jitter. Learn how with this example.
202                  </p>
203                </div>
204              </div>
205              <img
206                class="img-fluid"
207                src="img/graph/boxplot_show_individual_points.png"
208                alt=""
209              />
210            </a>
211          </div>
212        </div>
213
214        <br /><br />
215        <div class="mySeryTitle">Template</div>
216        <hr />
217        <p>
218          Here is the template I'm starting with when in need for a boxplot in
219          my work. See the code
220          <a href="graph/boxplot_horizontal.html">here</a>.
221        </p>
222        <div class="row">
223          <div class="col-lg-12">
224            <center><div id="boxplot_template"></div></center>
225          </div>
226        </div>
227
228        <br /><br />
229        <div class="mySeryTitle">Related blocks</div>
230        <hr />
231      </div>
232    </section>
233
234    <!-- ======================================================================= -->
235
236    <!-- ============================ JAVASCRIPT BOXPLOT TEMPLATE ============================ -->
237
238    <!-- Tooltip style -->
239    <style>
240      .tooltip {
241        background-color: black;
242        border: none;
243        border-radius: 5px;
244        padding: 15px;
245        min-width: 200px;
246        text-align: left;
247        color: white;
248      }
249
250      svg {
251        border: 1px solid #e8e8e8;
252        border-radius: 6px;
253      }
254    </style>
255
256    
256<script>
257      // set the dimensions and margins of the graph
258      var margin = { top: 10, right: 30, bottom: 50, left: 70 },
259        width = 760 - margin.left - margin.right,
260        height = 600 - margin.top - margin.bottom;
261
262      // append the svg object to the body of the page
263      var svg = d3
264        .select("#boxplot_template")
265        .append("svg")
266        .attr("width", width + margin.left + margin.right)
267        .attr("height", height + margin.top + margin.bottom)
268        .append("g")
269        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
270
271      // Read the data and compute summary statistics for each specie
272      d3.csv(
273        "https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/iris.csv",
274        function (data) {
275          // Compute quartiles, median, inter quantile range min and max --> these info are then used to draw the box.
276          var sumstat = d3
277            .nest() // nest function allows to group the calculation per level of a factor
278            .key(function (d) {
279              return d.Species;
280            })
281            .rollup(function (d) {
282              q1 = d3.quantile(
283                d
284                  .map(function (g) {
285                    return g.Sepal_Length;
286                  })
287                  .sort(d3.ascending),
288                0.25
289              );
290              median = d3.quantile(
291                d
292                  .map(function (g) {
293                    return g.Sepal_Length;
294                  })
295                  .sort(d3.ascending),
296                0.5
297              );
298              q3 = d3.quantile(
299                d
300                  .map(function (g) {
301                    return g.Sepal_Length;
302                  })
303                  .sort(d3.ascending),
304                0.75
305              );
306              interQuantileRange = q3 - q1;
307              min = q1 - 1.5 * interQuantileRange;
308              max = q3 + 1.5 * interQuantileRange;
309              return {
310                q1: q1,
311                median: median,
312                q3: q3,
313                interQuantileRange: interQuantileRange,
314                min: min,
315                max: max,
316              };
317            })
318            .entries(data);
319
320          // Show the Y scale
321          var y = d3
322            .scaleBand()
323            .range([height, 0])
324            .domain(["setosa", "versicolor", "virginica"])
325            .padding(0.4);
326          svg
327            .append("g")
328            .call(d3.axisLeft(y).tickSize(0))
329            .select(".domain")
330            .remove();
331
332          // Show the X scale
333          var x = d3.scaleLinear().domain([4, 8]).range([0, width]);
334          svg
335            .append("g")
336            .attr("transform", "translate(0," + height + ")")
337            .call(d3.axisBottom(x).ticks(5))
338            .select(".domain")
339            .remove();
340
341          // Color scale
342          var myColor = d3
343            .scaleSequential()
344            .interpolator(d3.interpolateInferno)
345            .domain([4, 8]);
346
347          // Add X axis label:
348          svg
349            .append("text")
350            .attr("text-anchor", "end")
351            .attr("x", width)
352            .attr("y", height + margin.top + 30)
353            .text("Sepal Length");
354
355          // Show the main vertical line
356          svg
357            .selectAll("vertLines")
358            .data(sumstat)
359            .enter()
360            .append("line")
361            .attr("x1", function (d) {
362              return x(d.value.min);
363            })
364            .attr("x2", function (d) {
365              return x(d.value.max);
366            })
367            .attr("y1", function (d) {
368              return y(d.key) + y.bandwidth() / 2;
369            })
370            .attr("y2", function (d) {
371              return y(d.key) + y.bandwidth() / 2;
372            })
373            .attr("stroke", "black")
374            .style("width", 40);
375
376          // rectangle for the main box
377          svg
378            .selectAll("boxes")
379            .data(sumstat)
380            .enter()
381            .append("rect")
382            .attr("x", function (d) {
383              return x(d.value.q1);
384            }) // console.log(x(d.value.q1)) ;
385            .attr("width", function (d) {
386              return x(d.value.q3) - x(d.value.q1);
387            }) //console.log(x(d.value.q3)-x(d.value.q1))
388            .attr("y", function (d) {
389              return y(d.key);
390            })
391            .attr("height", y.bandwidth())
392            .attr("stroke", "black")
393            .style("fill", "#69b3a2")
394            .style("opacity", 0.3);
395
396          // Show the median
397          svg
398            .selectAll("medianLines")
399            .data(sumstat)
400            .enter()
401            .append("line")
402            .attr("y1", function (d) {
403              return y(d.key) + y.bandwidth() / 2;
404            })
405            .attr("y2", function (d) {
406              return y(d.key) + y.bandwidth() / 2;
407            })
408            .attr("x1", function (d) {
409              return x(d.value.median);
410            })
411            .attr("x2", function (d) {
412              return x(d.value.median);
413            })
414            .attr("stroke", "black")
415            .style("width", 80);
416
417          // create a tooltip
418          var tooltip = d3
419            .select("#boxplot_template")
420            .append("div")
421            .style("opacity", 0)
422            .attr("class", "tooltip")
423            .style("font-size", "16px");
424          // Three function that change the tooltip when user hover / move / leave a cell
425          var mouseover = function (d) {
426            tooltip.transition().duration(200).style("opacity", 1);
427            tooltip
428              .html(
429                "<span style='color:grey'>Sepal length: </span>" +
430                  d.Sepal_Length
431              ) // + d.Prior_disorder + "<br>" + "HR: " +  d.HR)
432              .style("left", d3.mouse(this)[0] + 30 + "px")
433              .style("top", d3.mouse(this)[1] + 30 + "px");
434          };
435          var mousemove = function (d) {
436            tooltip
437              .style("left", d3.mouse(this)[0] + 30 + "px")
438              .style("top", d3.mouse(this)[1] + 30 + "px");
439          };
440          var mouseleave = function (d) {
441            tooltip.transition().duration(200).style("opacity", 0);
442          };
443
444          // Add individual points with jitter
445          var jitterWidth = 60;
446          svg
447            .selectAll("indPoints")
448            .data(data)
449            .enter()
450            .append("circle")
451            .attr("cx", function (d) {
452              return x(d.Sepal_Length);
453            })
454            .attr("cy", function (d) {
455              return (
456                y(d.Species) +
457                y.bandwidth() / 2 -
458                jitterWidth / 2 +
459                Math.random() * jitterWidth
460              );
461            })
462            .attr("r", 6)
463            .style("fill", function (d) {
464              return myColor(+d.Sepal_Length);
465            })
466            .attr("stroke", "black")
467            .on("mouseover", mouseover)
468            .on("mousemove", mousemove)
469            .on("mouseleave", mouseleave);
470        }
471      );
472    </script>
472
473
474    <!-- ============================ RELATED SECTION ============================ -->
475    <section
476      class="bg-light"
477      id="portfolio_landing"
478      style="padding-top: 30px; padding-bottom: 30px"
479    >
480      <div class="container">
481        <p class="mySeryTitle">Related chart types</p>
482        <hr />
483        <div class="row">
484          <div class="col-md-2 col-sm-4 portfolio-item">
485            <a class="portfolio-link" href="violin.html">
486              <div class="portfolio-hover">
487                <div class="portfolio-hover-content">
488                  <i class="fa fa-plus fa-3x"></i>
489                </div>
490              </div>
491              <img class="img-fluid" src="img/section/Violin150.png" alt="" />
492            </a>
493            <div class="captionPortfolio">Violin</div>
494          </div>
495          <div class="col-md-2 col-sm-4 portfolio-item">
496            <a class="portfolio-link" href="density.html">
497              <div class="portfolio-hover">
498                <div class="portfolio-hover-content">
499                  <i class="fa fa-plus fa-3x"></i>
500                </div>
501              </div>
502              <img class="img-fluid" src="img/section/Density150.png" alt="" />
503            </a>
504            <div class="captionPortfolio">Density</div>
505          </div>
506          <div class="col-md-2 col-sm-4 portfolio-item">
507            <a class="portfolio-link" href="histogram.html">
508              <div class="portfolio-hover">
509                <div class="portfolio-hover-content">
510                  <i class="fa fa-plus fa-3x"></i>
511                </div>
512              </div>
513              <img
514                class="img-fluid"
515                src="img/section/Histogram150.png"
516                alt=""
517              />
518            </a>
519            <div class="captionPortfolio">Histogram</div>
520          </div>
521          <div class="col-md-2 col-sm-4 portfolio-item">
522            <a class="portfolio-link" href="boxplot.html">
523              <div class="portfolio-hover">
524                <div class="portfolio-hover-content">
525                  <i class="fa fa-plus fa-3x"></i>
526                </div>
527              </div>
528              <img class="img-fluid" src="img/section/Box1150.png" alt="" />
529            </a>
530            <div class="captionPortfolio">Boxplot</div>
531          </div>
532          <div class="col-md-2 col-sm-4 portfolio-item">
533            <a class="portfolio-link" href="ridgeline.html">
534              <div class="portfolio-hover">
535                <div class="portfolio-hover-content">
536                  <i class="fa fa-plus fa-3x"></i>
537                </div>
538              </div>
539              <img class="img-fluid" src="img/section/Joyplot150.png" alt="" />
540            </a>
541            <div class="captionPortfolio">Ridgeline</div>
542          </div>
543        </div>
544      </div>
545    </section>
546
547    <!-- ============================ CONTACT SECTION ============================ -->
548
549
550    <section id="contact" class="bg" style="background-color: white"></section>
551
552    <!-- THIS ALLOWS TO INSERT THE NEWSLETTER CHUNK THAT IS STORED IN A NEWSLETTER_SECTION.HTML FILE-->
553    
553<script>
554      $(function () {
555        $("#contact").load("html_chunk/newsletter_section.html");
556      });
557    </script>
557
558
559    <!-- ============================ FOOTER SECTION ============================ -->
560    <footer class="bg-light" id="myFooter"></footer>
561
562
563    <!-- THIS ALLOWS TO INSERT THE FOOTER THAT IS STORED IN A FOOTER.HTML FILE-->
564    
564<script>
565      $(function () {
566        $("#myFooter").load("html_chunk/footer.html");
567      });
568    </script>
568
569
570    <!-- ============================ -->
571
572    <!-- =============== JAVASCRIPT SECTION =============== -->
573
574    <!-- Bootstrap core JavaScript -->
575    
575<script src="vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
575
576
577    <!-- Plugin JavaScript -->
578    
578<script src="vendor/jquery-easing/jquery.easing.min.js"></script>
578
579
580    <!-- Custom scripts for this template -->
581    
581<script src="js/agency.min.js"></script>
581
582
583    <!--============================== -->
584    <!-- Newsletter toast (pops bottom-right after a few seconds). Content lives in js/newsletter-toast.js -->
585    
585<script src="js/newsletter-toast.js"></script>
585
586  </body>
587</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.