Repository: jtablesaw/tablesaw
Pull request #480 (2019-03-07 05:22:05)

Reduce code duplication
Thanks for contributing.

- [X] Tick to sign-off your agreement to the [Developer Certificate of Origin (DCO) 1.1](https://developercertificate.org)

## Description

Added additional `builder` methods to speed `Layout.Builder` creation


Patch:
diff --git a/core/src/main/java/tech/tablesaw/io/csv/CsvReadOptions.java b/core/src/main/java/tech/tablesaw/io/csv/CsvReadOptions.java
index dd195132..3b02687f 100644
--- a/core/src/main/java/tech/tablesaw/io/csv/CsvReadOptions.java
+++ b/core/src/main/java/tech/tablesaw/io/csv/CsvReadOptions.java
@@ -30,6 +30,7 @@ public class CsvReadOptions extends ReadOptions {
     private final Character separator;
     private final String lineEnding;
     private final Integer maxNumberOfColumns;
+    private final Character commentPrefix;
 
     private CsvReadOptions(CsvReadOptions.Builder builder) {
 	super(builder);
@@ -38,6 +39,7 @@ public class CsvReadOptions extends ReadOptions {
         separator = builder.separator;
         lineEnding = builder.lineEnding;
         maxNumberOfColumns = builder.maxNumberOfColumns;
+        commentPrefix = builder.commentPrefix;
     }
 
     public static Builder builder(File file) {
@@ -139,13 +141,18 @@ public class CsvReadOptions extends ReadOptions {
         return maxNumberOfColumns;
     }
 
+    public Character commentPrefix() {
+        return commentPrefix;
+    }
+
     public static class Builder extends ReadOptions.Builder {
 
         private Character separator = ',';
         private String lineEnding;
         private ColumnType[] columnTypes;
         private Integer maxNumberOfColumns = 10_000;
-
+        private Character commentPrefix;
+        
         public Builder(File file) {
             super(file);
         }
@@ -244,6 +251,11 @@ public class CsvReadOptions extends ReadOptions {
             return this;
         }
 
+        public Builder commentPrefix(char commentPrefix) {
+            this.commentPrefix = commentPrefix;
+            return this;
+        }
+
         public CsvReadOptions build() {
             return new CsvReadOptions(this);
         }
diff --git a/core/src/main/java/tech/tablesaw/io/csv/CsvReader.java b/core/src/main/java/tech/tablesaw/io/csv/CsvReader.java
index ae1b0e16..5063febd 100644
--- a/core/src/main/java/tech/tablesaw/io/csv/CsvReader.java
+++ b/core/src/main/java/tech/tablesaw/io/csv/CsvReader.java
@@ -19,13 +19,15 @@ import com.univocity.parsers.common.AbstractParser;
 import com.univocity.parsers.csv.CsvFormat;
 import com.univocity.parsers.csv.CsvParser;
 import com.univocity.parsers.csv.CsvParserSettings;
-import org.apache.commons.lang3.tuple.Pair;
 import tech.tablesaw.api.ColumnType;
 import tech.tablesaw.api.Table;
 import tech.tablesaw.io.FileReader;
 import tech.tablesaw.io.TableBuildingUtils;
 
 import javax.annotation.concurrent.Immutable;
+
+import org.apache.commons.math3.util.Pair;
+
 import java.io.IOException;
 import java.io.Reader;
 import java.util.List;
@@ -67,7 +69,7 @@ public class CsvReader extends FileReader {
             types = detectColumnTypes(reader, options);
         }
 
-        return Pair.of(TableBuildingUtils.createReader(options, bytesCache), types);
+        return Pair.create(TableBuildingUtils.createReader(options, bytesCache), types);
     }
 
     public Table read(CsvReadOptions options) throws IOException {
@@ -76,8 +78,8 @@ public class CsvReader extends FileReader {
 
     private Table read(CsvReadOptions options, boolean headerOnly) throws IOException {
         Pair<Reader, ColumnType[]> pair = getReaderAndColumnTypes(options);
-        Reader reader = pair.getLeft();
-        ColumnType[] types = pair.getRight();
+        Reader reader = pair.getKey();
+        ColumnType[] types = pair.getValue();
 
         AbstractParser<?> parser = csvParser(options);
 
@@ -161,6 +163,9 @@ public class CsvReader extends FileReader {
         if (options.lineEnding() != null) {
             format.setLineSeparator(options.lineEnding());
         }
+        if(options.commentPrefix() != null) {
+            format.setComment(options.commentPrefix());
+        }
         return format;
     }
 
diff --git a/core/src/main/java/tech/tablesaw/io/fixed/FixedWidthReader.java b/core/src/main/java/tech/tablesaw/io/fixed/FixedWidthReader.java
index deedd606..59d2c66a 100644
--- a/core/src/main/java/tech/tablesaw/io/fixed/FixedWidthReader.java
+++ b/core/src/main/java/tech/tablesaw/io/fixed/FixedWidthReader.java
@@ -19,13 +19,15 @@ import com.univocity.parsers.common.AbstractParser;
 import com.univocity.parsers.fixed.FixedWidthFormat;
 import com.univocity.parsers.fixed.FixedWidthParser;
 import com.univocity.parsers.fixed.FixedWidthParserSettings;
-import org.apache.commons.lang3.tuple.Pair;
 import tech.tablesaw.api.ColumnType;
 import tech.tablesaw.api.Table;
 import tech.tablesaw.io.FileReader;
 import tech.tablesaw.io.TableBuildingUtils;
 
 import javax.annotation.concurrent.Immutable;
+
+import org.apache.commons.math3.util.Pair;
+
 import java.io.IOException;
 import java.io.Reader;
 import java.util.List;
@@ -67,7 +69,7 @@ public class FixedWidthReader extends FileReader {
             types = detectColumnTypes(reader, options);
         }
 
-        return Pair.of(TableBuildingUtils.createReader(options, bytesCache), types);
+        return Pair.create(TableBuildingUtils.createReader(options, bytesCache), types);
     }
 
     public Table read(FixedWidthReadOptions options) throws IOException {
@@ -76,8 +78,8 @@ public class FixedWidthReader extends FileReader {
 
     private Table read(FixedWidthReadOptions options, boolean headerOnly) throws IOException {
         Pair<Reader, ColumnType[]> pair = getReaderAndColumnTypes(options);
-        Reader reader = pair.getLeft();
-        ColumnType[] types = pair.getRight();
+        Reader reader = pair.getKey();
+        ColumnType[] types = pair.getValue();
 
         FixedWidthParser parser = fixedWidthParser(options);
 
diff --git a/data/with_comments.csv b/data/with_comments.csv
new file mode 100644
index 00000000..45330b85
--- /dev/null
+++ b/data/with_comments.csv
@@ -0,0 +1,11 @@
+#comment1
+#comment2
+Products,Sales,Market_Share
+# comment3
+a,5500,3
+# comment,with,some,rows
+#comment5
+b,12200,4
+c,60000,33
+#comment,with,rows
+#footer comment
\ No newline at end of file
diff --git a/jsplot/src/main/java/tech/tablesaw/plotly/api/AreaPlot.java b/jsplot/src/main/java/tech/tablesaw/plotly/api/AreaPlot.java
index adbab843..dfb3f120 100644
--- a/jsplot/src/main/java/tech/tablesaw/plotly/api/AreaPlot.java
+++ b/jsplot/src/main/java/tech/tablesaw/plotly/api/AreaPlot.java
@@ -1,7 +1,6 @@
 package tech.tablesaw.plotly.api;
 
 import tech.tablesaw.api.Table;
-import tech.tablesaw.plotly.components.Axis;
 import tech.tablesaw.plotly.components.Figure;
 import tech.tablesaw.plotly.components.Layout;
 import tech.tablesaw.plotly.traces.ScatterTrace;
@@ -11,14 +10,10 @@ import java.util.List;
 
 public class AreaPlot {
 
-    private static final int HEIGHT = 600;
-    private static final int WIDTH = 800;
-
     public static Figure create(String title, Table table, String xCol, String yCol, String groupCol) {
-
         TableSliceGroup tables = table.splitOn(table.categoricalColumn(groupCol));
 
-        Layout layout = standardLayout(title, xCol, yCol).build();
+        Layout layout = Layout.builder(title, xCol, yCol).showLegend(true).build();
 
         ScatterTrace[] traces  = new ScatterTrace[tables.size()];
         for (int i = 0; i < tables.size(); i++) {
@@ -35,24 +30,8 @@ public class AreaPlot {
         return new Figure(layout, traces);
     }
 
-    private static Layout.LayoutBuilder standardLayout(String title, String xCol, String yCol) {
-        return Layout.builder()
-                    .title(title)
-                    .height(HEIGHT)
-                    .width(WIDTH)
-                    .showLegend(true)
-                    .xAxis(Axis.builder()
-                            .title(xCol)
-                            .build())
-                    .yAxis(Axis.builder()
-                            .title(yCol)
-                            .build());
-    }
-
     public static Figure create(String title, Table table, String xCol, String yCol) {
-
-        Layout layout = standardLayout(title, xCol, yCol).build();
-
+        Layout layout = Layout.builder(title, xCol, yCol).showLegend(true).build();
         ScatterTrace trace = ScatterTrace.builder(
                 table.numberColumn(xCol),
                 table.numberColumn(yCol))
diff --git a/jsplot/src/main/java/tech/tablesaw/plotly/api/BubblePlot.java b/jsplot/src/main/java/tech/tablesaw/plotly/api/BubblePlot.java
index da0356ba..9de6f444 100644
--- a/jsplot/src/main/java/tech/tablesaw/plotly/api/BubblePlot.java
+++ b/jsplot/src/main/java/tech/tablesaw/plotly/api/BubblePlot.java
@@ -1,7 +1,6 @@
 package tech.tablesaw.plotly.api;
 
 import tech.tablesaw.api.Table;
-import tech.tablesaw.plotly.components.Axis;
 import tech.tablesaw.plotly.components.Figure;
 import tech.tablesaw.plotly.components.Layout;
 import tech.tablesaw.plotly.components.Marker;
@@ -12,24 +11,10 @@ import java.util.List;
 
 public class BubblePlot {
 
-    private static final int HEIGHT = 600;
-    private static final int WIDTH = 800;
-
     public static Figure create(String title, Table table, String xCol, String yCol, String sizeColumn, String groupCol) {
 
         TableSliceGroup tables = table.splitOn(table.categoricalColumn(groupCol));
-        Layout layout = Layout.builder()
-                .title(title)
-                .height(HEIGHT)
-                .width(WIDTH)
-                .showLegend(true)
-                .xAxis(Axis.builder()
-                        .title(xCol)
-                        .build())
-                .yAxis(Axis.builder()
-                        .title(yCol)
-                        .build())
-                .build();
+        Layout layout = Layout.builder(title, xCol, yCol).showLegend(true).build();
 
         ScatterTrace[] traces  = new ScatterTrace[tables.size()];
         for (int i = 0; i < tables.size(); i++) {
@@ -52,18 +37,7 @@ public class BubblePlot {
     }
 
     public static Figure create(String title, Table table, String xCol, String yCol, String sizeColumn) {
-
-        Layout layout = Layout.builder()
-                .title(title)
-                .height(HEIGHT)
-                .width(WIDTH)
-                .xAxis(Axis.builder()
-                        .title(xCol)
-                        .build())
-                .yAxis(Axis.builder()
-                        .title(yCol)
-                        .build())
-                .build();
+        Layout layout = Layout.builder(title, xCol, yCol).build();
 
         Marker marker = Marker.builder()
                 .size(table.numberColumn(sizeColumn))
@@ -79,19 +53,7 @@ public class BubblePlot {
     }
 
     public static Figure create(String title, String xTitle, double[] xCol, String yTitle, double[] yCol) {
-
-        Layout layout = Layout.builder()
-                .title(title)
-                .height(HEIGHT)
-                .width(WIDTH)
-                .xAxis(Axis.builder()
-                        .title(xTitle)
-                        .build())
-                .yAxis(Axis.builder()
-                        .title(yTitle)
-                        .build())
-                .build();
-
+        Layout layout = Layout.builder(title, xTitle, yTitle).build();
         ScatterTrace trace = ScatterTrace.builder(xCol, yCol).build();
         return new Figure(layout, trace);
     }
diff --git a/jsplot/src/main/java/tech/tablesaw/plotly/api/CandlestickPlot.java b/jsplot/src/main/java/tech/tablesaw/plotly/api/CandlestickPlot.java
index 2a66ca52..e492a084 100644
--- a/jsplot/src/main/java/tech/tablesaw/plotly/api/CandlestickPlot.java
+++ b/jsplot/src/main/java/tech/tablesaw/plotly/api/CandlestickPlot.java
@@ -1,27 +1,14 @@
 package tech.tablesaw.plotly.api;
 
 import tech.tablesaw.api.Table;
-import tech.tablesaw.plotly.components.Axis;
 import tech.tablesaw.plotly.components.Figure;
 import tech.tablesaw.plotly.components.Layout;
 import tech.tablesaw.plotly.traces.ScatterTrace;
 
 public class CandlestickPlot {
 
-    private static final int HEIGHT = 600;
-    private static final int WIDTH = 800;
-
     public static Figure create(String title, Table table, String xCol, String openCol, String highCol, String lowCol, String closeCol) {
-
-        Layout layout = Layout.builder()
-                .title(title)
-                .height(HEIGHT)
-                .width(WIDTH)
-                .xAxis(Axis.builder()
-                        .title(xCol)
-                        .build())
-                .build();
-
+        Layout layout = Layout.builder(title, xCol).build();
         ScatterTrace trace = ScatterTrace.builder(
                 table.dateColumn(xCol),
                 table.numberColumn(openCol),
diff --git a/jsplot/src/main/java/tech/tablesaw/plotly/api/Heatmap.java b/jsplot/src/main/java/tech/tablesaw/plotly/api/Heatmap.java
index 69e3e137..e00ccb66 100644
--- a/jsplot/src/main/java/tech/tablesaw/plotly/api/Heatmap.java
+++ b/jsplot/src/main/java/tech/tablesaw/plotly/api/Heatmap.java
@@ -10,17 +10,11 @@ import tech.tablesaw.util.DoubleArrays;
 import java.util.List;
 
 public class Heatmap {
-    private static final int HEIGHT = 600;
-    private static final int WIDTH = 800;
 
     private Heatmap() {}
 
     public static Figure create(String title, Table table, String categoryCol1, String categoryCol2) {
-        Layout layout = Layout.builder()
-                .title(title)
-                .height(HEIGHT)
-                .width(WIDTH)
-                .build();
+        Layout layout = Layout.builder(title).build();
 
         Table counts = table.xTabCounts(categoryCol1, categoryCol2);
         counts = counts.dropRows(counts.rowCount() - 1);
diff --git a/jsplot/src/main/java/tech/tablesaw/plotly/api/Histogram.java b/jsplot/src/main/java/tech/tablesaw/plotly/api/Histogram.java
index 3993701e..dbfe8715 100644
--- a/jsplot/src/main/java/tech/tablesaw/plotly/api/Histogram.java
+++ b/jsplot/src/main/java/tech/tablesaw/plotly/api/Histogram.java
@@ -8,9 +8,6 @@ import tech.tablesaw.plotly.traces.HistogramTrace;
 
 public class Histogram {
 
-    private static final int HEIGHT = 600;
-    private static final int WIDTH = 800;
-
     public static Figure create(String title, NumberColumn<?> data) {
         return create(title, data.asDoubleArray());
     }
@@ -21,14 +18,7 @@ public class Histogram {
 
     public static Figure create(String title, double[] data) {
         HistogramTrace trace = HistogramTrace.builder(data).build();
-        return new Figure(standardLayout(title), trace);
+        return new Figure(Layout.builder(title).build(), trace);
     }
 
-    private static Layout standardLayout(String title) {
-        return Layout.builder()
-                .title(title)
-                .height(HEIGHT)
-                .width(WIDTH)
-                .build();
-    }
 }
diff --git a/jsplot/src/main/java/tech/tablesaw/plotly/api/Histogram2D.java b/jsplot/src/main/java/tech/tablesaw/plotly/api/Histogram2D.java
index 8c1d0365..bee71029 100644
--- a/jsplot/src/main/java/tech/tablesaw/plotly/api/Histogram2D.java
+++ b/jsplot/src/main/java/tech/tablesaw/plotly/api/Histogram2D.java
@@ -1,31 +1,17 @@
 package tech.tablesaw.plotly.api;
 
 import tech.tablesaw.api.Table;
-import tech.tablesaw.plotly.components.Axis;
 import tech.tablesaw.plotly.components.Figure;
 import tech.tablesaw.plotly.components.Layout;
 import tech.tablesaw.plotly.traces.Histogram2DTrace;
 
 public class Histogram2D {
 
-    private static final int HEIGHT = 600;
-    private static final int WIDTH = 800;
-
     public static Figure create(String title, Table table, String xCol, String yCol) {
-
         Histogram2DTrace trace = Histogram2DTrace.builder(table.numberColumn(xCol), table.numberColumn(yCol))
                 .build();
 
-        return new Figure(standardLayout(title, xCol, yCol), trace);
+        return new Figure(Layout.builder(title, xCol, yCol).build(), trace);
     }
 
-    private static Layout standardLayout(String title, String xCol, String yCol) {
-        return Layout.builder()
-                .title(title)
-                .height(HEIGHT)
-                .width(WIDTH)
-                .xAxis(Axis.builder().title(xCol).build())
-                .yAxis(Axis.builder().title(yCol).build())
-                .build();
-    }
 }
diff --git a/jsplot/src/main/java/tech/tablesaw/plotly/api/LinePlot.java b/jsplot/src/main/java/tech/tablesaw/plotly/api/LinePlot.java
index bfe7ce24..dd34c2da 100644
--- a/jsplot/src/main/java/tech/tablesaw/plotly/api/LinePlot.java
+++ b/jsplot/src/main/java/tech/tablesaw/plotly/api/LinePlot.java
@@ -1,7 +1,6 @@
 package tech.tablesaw.plotly.api;
 
 import tech.tablesaw.api.Table;
-import tech.tablesaw.plotly.components.Axis;
 import tech.tablesaw.plotly.components.Figure;
 import tech.tablesaw.plotly.components.Layout;
 import tech.tablesaw.plotly.traces.ScatterTrace;
@@ -11,25 +10,11 @@ import java.util.List;
 
 public class LinePlot {
 
-    private static final int HEIGHT = 600;
-    private static final int WIDTH = 800;
-
     public static Figure create(String title, Table table, String xCol, String yCol, String groupCol) {
 
         TableSliceGroup tables = table.splitOn(table.categoricalColumn(groupCol));
 
-        Layout layout = Layout.builder()
-                .title(title)
-                .height(HEIGHT)
-                .width(WIDTH)
-                .showLegend(true)
-                .xAxis(Axis.builder()
-                        .title(xCol)
-                        .build())
-                .yAxis(Axis.builder()
-                        .title(yCol)
-                        .build())
-                .build();
+        Layout layout = Layout.builder(title, xCol, yCol).showLegend(true).build();
 
         ScatterTrace[] traces  = new ScatterTrace[tables.size()];
         for (int i = 0; i < tables.size(); i++) {
@@ -46,19 +31,7 @@ public class LinePlot {
     }
 
     public static Figure create(String title, Table table, String xCol, String yCol) {
-
-        Layout layout = Layout.builder()
-                .title(title)
-                .height(HEIGHT)
-                .width(WIDTH)
-                .xAxis(Axis.builder()
-                        .title(xCol)
-                        .build())
-                .yAxis(Axis.builder()
-                        .title(yCol)
-                        .build())
-                .build();
-
+        Layout layout = Layout.builder(title, xCol, yCol).build();
         ScatterTrace trace = ScatterTrace.builder(
                 table.numberColumn(xCol),
                 table.numberColumn(yCol))
@@ -68,19 +41,7 @@ public class LinePlot {
     }
 
     public static Figure create(String title, String xTitle, double[] xCol, String yTitle, double[] yCol) {
-
-        Layout layout = Layout.builder()
-                .title(title)
-                .height(HEIGHT)
-                .width(WIDTH)
-                .xAxis(Axis.builder()
-                        .title(xTitle)
-                        .build())
-                .yAxis(Axis.builder()
-                        .title(yTitle)
-                        .build())
-                .build();
-
+        Layout layout = Layout.builder(title, xTitle, yTitle).build();
         ScatterTrace trace = ScatterTrace.builder(xCol, yCol)
                 .mode(ScatterTrace.Mode.LINE)
                 .build();
diff --git a/jsplot/src/main/java/tech/tablesaw/plotly/api/OHLCPlot.java b/jsplot/src/main/java/tech/tablesaw/plotly/api/OHLCPlot.java
index 9a595ebd..e367422a 100644
--- a/jsplot/src/main/java/tech/tablesaw/plotly/api/OHLCPlot.java
+++ b/jsplot/src/main/java/tech/tablesaw/plotly/api/OHLCPlot.java
@@ -1,27 +1,14 @@
 package tech.tablesaw.plotly.api;
 
 import tech.tablesaw.api.Table;
-import tech.tablesaw.plotly.components.Axis;
 import tech.tablesaw.plotly.components.Figure;
 import tech.tablesaw.plotly.components.Layout;
 import tech.tablesaw.plotly.traces.ScatterTrace;
 
 public class OHLCPlot {
 
-    private static final int HEIGHT = 600;
-    private static final int WIDTH = 800;
-
     public static Figure create(String title, Table table, String xCol, String openCol, String highCol, String lowCol, String closeCol) {
-
-        Layout layout = Layout.builder()
-                .title(title)
-                .height(HEIGHT)
-                .width(WIDTH)
-                .xAxis(Axis.builder()
-                        .title(xCol)
-                        .build())
-                .build();
-
+        Layout layout = Layout.builder(title, xCol).build();
         ScatterTrace trace = ScatterTrace.builder(
                 table.dateColumn(xCol),
                 table.numberColumn(openCol),
diff --git a/jsplot/src/main/java/tech/tablesaw/plotly/api/PiePlot.java b/jsplot/src/main/java/tech/tablesaw/plotly/api/PiePlot.java
index c7582825..ed58c367 100644
--- a/jsplot/src/main/java/tech/tablesaw/plotly/api/PiePlot.java
+++ b/jsplot/src/main/java/tech/tablesaw/plotly/api/PiePlot.java
@@ -7,16 +7,9 @@ import tech.tablesaw.plotly.traces.PieTrace;
 
 public class PiePlot {
 
-    private static final int HEIGHT = 600;
-    private static final int WIDTH = 800;
-
     public static Figure create(String title, Table table, String groupColName, String numberColName) {
 
-        Layout layout = Layout.builder()
-                .title(title)
-                .height(HEIGHT)
-                .width(WIDTH)
-                .build();
+        Layout layout = Layout.builder(title).build();
 
         PieTrace trace = PieTrace.builder(
                 table.column(groupColName),
diff --git a/jsplot/src/main/java/tech/tablesaw/plotly/api/ScatterPlot.java b/jsplot/src/main/java/tech/tablesaw/plotly/api/ScatterPlot.java
index af1f32b2..ffa5fbac 100644
--- a/jsplot/src/main/java/tech/tablesaw/plotly/api/ScatterPlot.java
+++ b/jsplot/src/main/java/tech/tablesaw/plotly/api/ScatterPlot.java
@@ -1,7 +1,6 @@
 package tech.tablesaw.plotly.api;
 
 import tech.tablesaw.api.Table;
-import tech.tablesaw.plotly.components.Axis;
 import tech.tablesaw.plotly.components.Figure;
 import tech.tablesaw.plotly.components.Layout;
 import tech.tablesaw.plotly.components.Marker;
@@ -12,26 +11,13 @@ import java.util.List;
 
 public class ScatterPlot {
 
-    private static final int HEIGHT = 600;
-    private static final int WIDTH = 800;
     private static final double OPACITY = .75;
 
     public static Figure create(String title, Table table, String xCol, String yCol, String groupCol) {
 
         TableSliceGroup tables = table.splitOn(table.categoricalColumn(groupCol));
 
-        Layout layout = Layout.builder()
-                .title(title)
-                .height(HEIGHT)
-                .width(WIDTH)
-                .showLegend(true)
-                .xAxis(Axis.builder()
-                        .title(xCol)
-                        .build())
-                .yAxis(Axis.builder()
-                        .title(yCol)
-                        .build())
-                .build();
+        Layout layout = Layout.builder(title, xCol, yCol).showLegend(true).build();
 
         ScatterTrace[] traces  = new ScatterTrace[tables.size()];
         Marker marker = Marker.builder().opacity(OPACITY).build();
@@ -49,19 +35,7 @@ public class ScatterPlot {
     }
 
     public static Figure create(String title, Table table, String xCol, String yCol) {
-
-        Layout layout = Layout.builder()
-                .title(title)
-                .height(HEIGHT)
-                .width(WIDTH)
-                .xAxis(Axis.builder()
-                        .title(xCol)
-                        .build())
-                .yAxis(Axis.builder()
-                        .title(yCol)
-                        .build())
-                .build();
-
+        Layout layout = Layout.builder(title, xCol, yCol).build();
         ScatterTrace trace = ScatterTrace.builder(
                 table.numberColumn(xCol),
                 table.numberColumn(yCol))
@@ -70,20 +44,9 @@ public class ScatterPlot {
     }
 
     public static Figure create(String title, String xTitle, double[] xCol, String yTitle, double[] yCol) {
-
-        Layout layout = Layout.builder()
-                .title(title)
-                .height(HEIGHT)
-                .width(WIDTH)
-                .xAxis(Axis.builder()
-                        .title(xTitle)
-                        .build())
-                .yAxis(Axis.builder()
-                        .title(yTitle)
-                        .build())
-                .build();
-
+        Layout layout = Layout.builder(title, xTitle, yTitle).build();
         ScatterTrace trace = ScatterTrace.builder(xCol, yCol).build();
         return new Figure(layout, trace);
     }
+
 }
diff --git a/jsplot/src/main/java/tech/tablesaw/plotly/api/TimeSeriesPlot.java b/jsplot/src/main/java/tech/tablesaw/plotly/api/TimeSeriesPlot.java
index c38cd53f..fc9fb889 100644
--- a/jsplot/src/main/java/tech/tablesaw/plotly/api/TimeSeriesPlot.java
+++ b/jsplot/src/main/java/tech/tablesaw/plotly/api/TimeSeriesPlot.java
@@ -3,7 +3,6 @@ package tech.tablesaw.plotly.api;
 import tech.tablesaw.api.DateColumn;
 import tech.tablesaw.api.NumberColumn;
 import tech.tablesaw.api.Table;
-import tech.tablesaw.plotly.components.Axis;
 import tech.tablesaw.plotly.components.Figure;
 import tech.tablesaw.plotly.components.Layout;
 import tech.tablesaw.plotly.traces.ScatterTrace;
@@ -13,14 +12,11 @@ import java.util.List;
 
 public class TimeSeriesPlot {
 
-    private static final int HEIGHT = 600;
-    private static final int WIDTH = 800;
-
     public static Figure create(String title, Table table, String dateColX, String yCol, String groupCol) {
 
         TableSliceGroup tables = table.splitOn(table.categoricalColumn(groupCol));
 
-        Layout layout = standardLayout(title, dateColX, yCol);
+        Layout layout = Layout.builder(title, dateColX, yCol).build();
 
         ScatterTrace[] traces  = new ScatterTrace[tables.size()];
         for (int i = 0; i < tables.size(); i++) {
@@ -38,9 +34,7 @@ public class TimeSeriesPlot {
     }
 
     public static Figure create(String title, Table table, String dateColXName, String yColName) {
-
-        Layout layout = standardLayout(title, dateColXName, yColName);
-
+        Layout layout = Layout.builder(title, dateColXName, yColName).build();
         ScatterTrace trace = ScatterTrace.builder(
                 table.column(dateColXName),
                 table.numberColumn(yColName))
@@ -50,26 +44,11 @@ public class TimeSeriesPlot {
     }
 
     public static Figure create(String title, String xTitle, DateColumn xCol, String yTitle, NumberColumn<?> yCol) {
-
-        Layout layout = standardLayout(title, xTitle, yTitle);
-
+        Layout layout = Layout.builder(title, xTitle, yTitle).build();
         ScatterTrace trace = ScatterTrace.builder(xCol, yCol)
                 .mode(ScatterTrace.Mode.LINE)
                 .build();
         return new Figure(layout, trace);
     }
 
-    private static Layout standardLayout(String title, String xTitle, String yTitle) {
-        return Layout.builder()
-                .title(title)
-                .height(HEIGHT)
-                .width(WIDTH)
-                .xAxis(Axis.builder()
-                        .title(xTitle)
-                        .build())
-                .yAxis(Axis.builder()
-                        .title(yTitle)
-                        .build())
-                .build();
-    }
 }
diff --git a/jsplot/src/main/java/tech/tablesaw/plotly/components/Layout.java b/jsplot/src/main/java/tech/tablesaw/plotly/components/Layout.java
index e40fae37..830ddf22 100644
--- a/jsplot/src/main/java/tech/tablesaw/plotly/components/Layout.java
+++ b/jsplot/src/main/java/tech/tablesaw/plotly/components/Layout.java
@@ -13,6 +13,8 @@ import java.util.Map;
 
 public class Layout {
 
+    private static final int DEFAULT_HEIGHT = 600;
+    private static final int DEFAULT_WIDTH = 800;
     private final static String DEFAULT_TITLE = "";
     private final static String DEFAULT_PAPER_BG_COLOR = "#fff";
     private final static String DEFAULT_PLOT_BG_COLOR = "#fff";
@@ -287,6 +289,27 @@ public class Layout {
         return new LayoutBuilder();
     }
 
+    public static LayoutBuilder builder(String title) {
+      return Layout.builder()
+          .title(title)
+          .height(DEFAULT_HEIGHT)
+          .width(DEFAULT_WIDTH);
+    }
+
+    public static LayoutBuilder builder(String title, String xTitle) {
+      return Layout.builder(title)
+          .xAxis(Axis.builder()
+                  .title(xTitle)
+                  .build());
+    }
+
+    public static LayoutBuilder builder(String title, String xTitle, String yTitle) {
+      return Layout.builder(title, xTitle)
+          .yAxis(Axis.builder()
+                  .title(yTitle)
+                  .build());
+    }
+
     public static class LayoutBuilder {
 
         /**


Test patch:
diff --git a/core/src/test/java/tech/tablesaw/io/csv/CsvReaderTest.java b/core/src/test/java/tech/tablesaw/io/csv/CsvReaderTest.java
index b2bc9a78..3bb6b915 100644
--- a/core/src/test/java/tech/tablesaw/io/csv/CsvReaderTest.java
+++ b/core/src/test/java/tech/tablesaw/io/csv/CsvReaderTest.java
@@ -508,4 +508,13 @@ public class CsvReaderTest {
         assertEquals("1 rows X 10001 cols", table1.shape());
     }
 
+    @Test
+    public void testSkipLinesWithComments() throws Exception {
+        Table table1 = Table.read().csv(CsvReadOptions
+                .builder("../data/with_comments.csv")
+                .maxNumberOfColumns(3)
+                .commentPrefix('#')
+                .header(true));
+        assertEquals("3 rows X 3 cols", table1.shape());
+    }
 }