diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..24bbfc9
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,7 @@
+language: java
+jdk:
+  - oraclejdk8
+install: mvn install -DskipTests=true -Dgpg.skip=true
+script: "mvn cobertura:cobertura"
+after_success:
+- bash <(curl -s https://codecov.io/bash)
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..7d0d8e7
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,25 @@
+BSD 2-Clause License
+
+Copyright (c) 2021, Yann Richet
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
index 99a1f1d..cebbfe8 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,8 @@
-# JMathPlot: interactive 2D and 3D plots #
+[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.yannrichet/JMathPlot/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.yannrichet/JMathPlot)
+[![Build Status](https://travis-ci.org/yannrichet/jmathplot.png)](https://travis-ci.org/yannrichet/jmathplot)
+[![codecov](https://codecov.io/gh/yannrichet/jmathplot/branch/master/graph/badge.svg)](https://codecov.io/gh/yannrichet/jmathplot)
+
+# JMathPlot: interactive 2D and 3D plots
 
 Provides interactive 2D/3D plot (without openGL) :
 
@@ -54,3 +58,5 @@ Then
 - create a new PlotPanel instance: `PlotPanel plot = new Plot2DPanel();`
 - add a plot inside `plot.addLinePlot("my plot", x, y);`
 - use the PlotPanel as any Swing component (all PlotPanel extends JPanel, in fact) 
+
+![Analytics](https://ga-beacon.appspot.com/UA-109580-20/jmathplot)
diff --git a/pom.xml b/pom.xml
index c3a5ee2..aab25ce 100644
--- a/pom.xml
+++ b/pom.xml
@@ -114,6 +114,18 @@
 					<autoReleaseAfterClose>true</autoReleaseAfterClose>
 				</configuration>
 			</plugin>
+			<plugin>
+                		<groupId>org.codehaus.mojo</groupId>
+                		<artifactId>cobertura-maven-plugin</artifactId>
+                		<version>2.7</version>
+                		<configuration>
+                		    <formats>
+                		        <format>html</format>
+                		        <format>xml</format>
+                		    </formats>
+                		    <check />
+                		</configuration>
+			</plugin>
 		</plugins>
 		<finalName>jmathplot</finalName>
 	</build>
diff --git a/src/main/java/org/math/plot/PlotPanel.java b/src/main/java/org/math/plot/PlotPanel.java
index ac169d0..189d8d5 100644
--- a/src/main/java/org/math/plot/PlotPanel.java
+++ b/src/main/java/org/math/plot/PlotPanel.java
@@ -94,7 +94,7 @@ public void addLegend(String location) {
             plotLegend = new LegendPanel(this, LegendPanel.INVISIBLE);
             // add(legends, BorderLayout.NORTH);
         } else {
-            System.err.println("Orientation " + location + " is unknonw.");
+            System.err.println("Orientation " + location + " is unknown.");
         }
     }
 
@@ -150,7 +150,7 @@ public void addPlotToolBar(String location) {
             plotToolBar.setFloatable(false);
             add(plotToolBar, NORTH);
         } else {
-            System.err.println("Location " + location + " is unknonw.");
+            System.err.println("Location " + location + " is unknown.");
         }
     }
 
diff --git a/src/main/java/org/math/plot/components/PlotToolBar.java b/src/main/java/org/math/plot/components/PlotToolBar.java
index 19ee39d..1202635 100644
--- a/src/main/java/org/math/plot/components/PlotToolBar.java
+++ b/src/main/java/org/math/plot/components/PlotToolBar.java
@@ -6,13 +6,14 @@
 
 import javax.swing.*;
 import javax.swing.filechooser.FileFilter;
+import javax.imageio.ImageIO;
 
 import org.math.plot.*;
 import org.math.plot.canvas.*;
 
 /**
  * BSD License
- * 
+ *
  * @author Yann RICHET
  */
 public class PlotToolBar extends JToolBar {
@@ -32,7 +33,9 @@ public class PlotToolBar extends JToolBar {
     protected JButton buttonAdjustBounds;
     private boolean denySaveSecurity;
     private JFileChooser pngFileChooser;
-    /** the currently selected PlotPanel */
+    /**
+     * the currently selected PlotPanel
+     */
     private PlotCanvas plotCanvas;
     private PlotPanel plotPanel;
 
@@ -56,157 +59,155 @@ public String getDescription() {
             denySaveSecurity = true;
         }
 
-        buttonGroup = new ButtonGroup();
-
-        buttonCenter = new JToggleButton(new ImageIcon(PlotPanel.class.getResource("icons/center.png")));
-        buttonCenter.setToolTipText("Center axis");
-        buttonCenter.setSelected(plotCanvas.ActionMode == PlotCanvas.TRANSLATION);
-
-        buttonZoom = new JToggleButton(new ImageIcon(PlotPanel.class.getResource("icons/zoom.png")));
-        buttonZoom.setToolTipText("Zoom");
-        buttonZoom.setSelected(plotCanvas.ActionMode == PlotCanvas.ZOOM);
-
-        //buttonEdit = new JToggleButton(new ImageIcon(PlotPanel.class.getResource("icons/edit.png")));
-        //buttonEdit.setToolTipText("Edit mode");
-
-        //buttonViewCoords = new JToggleButton(new ImageIcon(PlotPanel.class.getResource("icons/position.png")));
-        //buttonViewCoords.setToolTipText("Highlight coordinates / Highlight plot");
-
-        buttonSetScales = new JButton(new ImageIcon(PlotPanel.class.getResource("icons/scale.png")));
-        buttonSetScales.setToolTipText("Edit axis scales");
-
-        buttonDatas = new JButton(new ImageIcon(PlotPanel.class.getResource("icons/data.png")));
-        buttonDatas.setToolTipText("Get data");
-
-        buttonSavePNGFile = new JButton(new ImageIcon(PlotPanel.class.getResource("icons/topngfile.png")));
-        buttonSavePNGFile.setToolTipText("Save graphics in a .PNG File");
-
-        buttonReset = new JButton(new ImageIcon(PlotPanel.class.getResource("icons/back.png")));
-        buttonReset.setToolTipText("Reset zoom & axis");
+        try {
+            buttonGroup = new ButtonGroup();
 
-        buttonAdjustBounds = new JButton(new ImageIcon(PlotPanel.class.getResource(plotCanvas.getAdjustBounds() ? "icons/adjustbounds.png" : "icons/noadjustbounds.png")));
-        buttonAdjustBounds.setToolTipText("Auto-update/fix bounds");
+            buttonCenter = new JToggleButton(new ImageIcon(ImageIO.read(PlotPanel.class.getResourceAsStream("icons/center.png"))));
+            buttonCenter.setToolTipText("Center axis");
+            buttonCenter.setSelected(plotCanvas.ActionMode == PlotCanvas.TRANSLATION);
 
-        /*buttonEdit.addActionListener(new ActionListener() {
-        public void actionPerformed(ActionEvent e) {
-        plotCanvas.ActionMode = PlotCanvas.EDIT;
-        }
-        });*/
+            buttonZoom = new JToggleButton(new ImageIcon(ImageIO.read(PlotPanel.class.getResourceAsStream("icons/zoom.png"))));
+            buttonZoom.setToolTipText("Zoom");
+            buttonZoom.setSelected(plotCanvas.ActionMode == PlotCanvas.ZOOM);
 
-        buttonZoom.setSelected(true);
-        buttonZoom.addActionListener(new ActionListener() {
+		//buttonEdit = new JToggleButton(new ImageIcon(PlotPanel.class.getResource("icons/edit.png")));
+            //buttonEdit.setToolTipText("Edit mode");
+		//buttonViewCoords = new JToggleButton(new ImageIcon(PlotPanel.class.getResource("icons/position.png")));
+            //buttonViewCoords.setToolTipText("Highlight coordinates / Highlight plot");
+            buttonSetScales = new JButton(new ImageIcon(ImageIO.read(PlotPanel.class.getResourceAsStream("icons/scale.png"))));
+            buttonSetScales.setToolTipText("Edit axis scales");
 
-            public void actionPerformed(ActionEvent e) {
-                plotCanvas.ActionMode = PlotCanvas.ZOOM;
-            }
-        });
+            buttonDatas = new JButton(new ImageIcon(ImageIO.read(PlotPanel.class.getResourceAsStream("icons/data.png"))));
+            buttonDatas.setToolTipText("Get data");
 
-        buttonCenter.addActionListener(new ActionListener() {
+            buttonSavePNGFile = new JButton(new ImageIcon(ImageIO.read(PlotPanel.class.getResourceAsStream("icons/topngfile.png"))));
+            buttonSavePNGFile.setToolTipText("Save graphics in a .PNG File");
 
-            public void actionPerformed(ActionEvent e) {
-                plotCanvas.ActionMode = PlotCanvas.TRANSLATION;
-            }
-        });
+            buttonReset = new JButton(new ImageIcon(PlotPanel.class.getResource("icons/back.png")));
+            buttonReset.setToolTipText("Reset zoom & axis");
 
-        /*buttonViewCoords.addActionListener(new ActionListener() {
-        public void actionPerformed(ActionEvent e) {
-        plotCanvas.setNoteCoords(buttonViewCoords.isSelected());
-        }
-        });*/
+            buttonAdjustBounds = new JButton(new ImageIcon(ImageIO.read(PlotPanel.class.getResourceAsStream(plotCanvas.getAdjustBounds() ? "icons/adjustbounds.png" : "icons/noadjustbounds.png"))));
+            buttonAdjustBounds.setToolTipText("Auto-update/fix bounds");
 
-        buttonSetScales.addActionListener(new ActionListener() {
+            /*buttonEdit.addActionListener(new ActionListener() {
+             public void actionPerformed(ActionEvent e) {
+             plotCanvas.ActionMode = PlotCanvas.EDIT;
+             }
+             });*/
+            buttonZoom.setSelected(true);
+            buttonZoom.addActionListener(new ActionListener() {
 
-            public void actionPerformed(ActionEvent e) {
-                plotCanvas.displayScalesFrame();
-            }
-        });
+                public void actionPerformed(ActionEvent e) {
+                    plotCanvas.ActionMode = PlotCanvas.ZOOM;
+                }
+            });
 
-        buttonDatas.addActionListener(new ActionListener() {
+            buttonCenter.addActionListener(new ActionListener() {
 
-            public void actionPerformed(ActionEvent e) {
-                plotCanvas.displayDataFrame();
-            }
-        });
+                public void actionPerformed(ActionEvent e) {
+                    plotCanvas.ActionMode = PlotCanvas.TRANSLATION;
+                }
+            });
 
-        buttonSavePNGFile.addActionListener(new ActionListener() {
+            /*buttonViewCoords.addActionListener(new ActionListener() {
+             public void actionPerformed(ActionEvent e) {
+             plotCanvas.setNoteCoords(buttonViewCoords.isSelected());
+             }
+             });*/
+            buttonSetScales.addActionListener(new ActionListener() {
 
-            public void actionPerformed(ActionEvent e) {
-                choosePNGFile();
-            }
-        });
+                public void actionPerformed(ActionEvent e) {
+                    plotCanvas.displayScalesFrame();
+                }
+            });
 
-        buttonReset.addActionListener(new ActionListener() {
+            buttonDatas.addActionListener(new ActionListener() {
 
-            public void actionPerformed(ActionEvent e) {
-                plotCanvas.resetBase();
-            }
-        });
+                public void actionPerformed(ActionEvent e) {
+                    plotCanvas.displayDataFrame();
+                }
+            });
 
-        buttonAdjustBounds.addActionListener(new ActionListener() {
+            buttonSavePNGFile.addActionListener(new ActionListener() {
 
-            public void actionPerformed(ActionEvent e) {
-                plotCanvas.setAdjustBounds(!plotCanvas.getAdjustBounds());
-                ajustBoundsChanged();
-            }
-        });
-
-        buttonGroup.add(buttonCenter);
-        buttonGroup.add(buttonZoom);
-        //buttonGroup.add(buttonEdit);
-
-        add(buttonCenter, null);
-        add(buttonZoom, null);
-        add(buttonReset, null);
-        //add(buttonViewCoords, null);
-        add(buttonSetScales, null);
-        if (adjustBoundsVisible) {
-            add(buttonAdjustBounds, null);
-        }
-        //add(buttonEdit, null);
-        add(buttonSavePNGFile, null);
-        add(buttonDatas, null);
+                public void actionPerformed(ActionEvent e) {
+                    choosePNGFile();
+                }
+            });
 
-        if (!denySaveSecurity) {
-            pngFileChooser.addActionListener(new ActionListener() {
+            buttonReset.addActionListener(new ActionListener() {
 
                 public void actionPerformed(ActionEvent e) {
-                    saveGraphicFile();
+                    plotCanvas.resetBase();
                 }
             });
-        } else {
-            buttonSavePNGFile.setEnabled(false);
-        }
 
-        //buttonEdit.setEnabled(plotCanvas.getEditable());
+            buttonAdjustBounds.addActionListener(new ActionListener() {
 
-        //buttonViewCoords.setEnabled(plotCanvas.getNotable());
+                public void actionPerformed(ActionEvent e) {
+                    plotCanvas.setAdjustBounds(!plotCanvas.getAdjustBounds());
+                    ajustBoundsChanged();
+                }
+            });
 
-        // allow mixed (2D/3D) plots managed by one toolbar
-        if (plotCanvas instanceof Plot3DCanvas) {
-            if (buttonRotate == null) {
-                buttonRotate = new JToggleButton(new ImageIcon(PlotPanel.class.getResource("icons/rotation.png")));
-                buttonRotate.setToolTipText("Rotate axes");
+            buttonGroup.add(buttonCenter);
+            buttonGroup.add(buttonZoom);
+            //buttonGroup.add(buttonEdit);
+
+            add(buttonCenter, null);
+            add(buttonZoom, null);
+            add(buttonReset, null);
+            //add(buttonViewCoords, null);
+            add(buttonSetScales, null);
+            if (adjustBoundsVisible) {
+                add(buttonAdjustBounds, null);
+            }
+            //add(buttonEdit, null);
+            add(buttonSavePNGFile, null);
+            add(buttonDatas, null);
 
-                buttonRotate.addActionListener(new ActionListener() {
+            if (!denySaveSecurity) {
+                pngFileChooser.addActionListener(new ActionListener() {
 
                     public void actionPerformed(ActionEvent e) {
-                        plotCanvas.ActionMode = Plot3DCanvas.ROTATION;
+                        saveGraphicFile();
                     }
                 });
-                buttonGroup.add(buttonRotate);
-                add(buttonRotate, null, 2);
-                buttonRotate.setSelected(plotCanvas.ActionMode == Plot3DCanvas.ROTATION);
             } else {
-                buttonRotate.setEnabled(true);
+                buttonSavePNGFile.setEnabled(false);
             }
-        } else {
-            if (buttonRotate != null) {
-                // no removal/disabling just disable
-                if (plotCanvas.ActionMode == Plot3DCanvas.ROTATION) {
-                    plotCanvas.ActionMode = PlotCanvas.ZOOM;
+
+		//buttonEdit.setEnabled(plotCanvas.getEditable());
+		//buttonViewCoords.setEnabled(plotCanvas.getNotable());
+            // allow mixed (2D/3D) plots managed by one toolbar
+            if (plotCanvas instanceof Plot3DCanvas) {
+                if (buttonRotate == null) {
+                    buttonRotate = new JToggleButton(new ImageIcon(ImageIO.read(PlotPanel.class.getResourceAsStream("icons/rotation.png"))));
+                    buttonRotate.setToolTipText("Rotate axes");
+
+                    buttonRotate.addActionListener(new ActionListener() {
+
+                        public void actionPerformed(ActionEvent e) {
+                            plotCanvas.ActionMode = Plot3DCanvas.ROTATION;
+                        }
+                    });
+                    buttonGroup.add(buttonRotate);
+                    add(buttonRotate, null, 2);
+                    buttonRotate.setSelected(plotCanvas.ActionMode == Plot3DCanvas.ROTATION);
+                } else {
+                    buttonRotate.setEnabled(true);
+                }
+            } else {
+                if (buttonRotate != null) {
+                    // no removal/disabling just disable
+                    if (plotCanvas.ActionMode == Plot3DCanvas.ROTATION) {
+                        plotCanvas.ActionMode = PlotCanvas.ZOOM;
+                    }
+                    buttonRotate.setEnabled(false);
                 }
-                buttonRotate.setEnabled(false);
             }
+        } catch (Exception e) {
+            e.printStackTrace();
         }
     }
 
@@ -237,6 +238,10 @@ public void viewAdjustBounds(boolean visible) {
     }
 
     public void ajustBoundsChanged() {
-        buttonAdjustBounds.setIcon(new ImageIcon(PlotPanel.class.getResource(plotCanvas.getAdjustBounds() ? "icons/adjustbounds.png" : "icons/noadjustbounds.png")));
+        try {
+            buttonAdjustBounds.setIcon(new ImageIcon(ImageIO.read(PlotPanel.class.getResourceAsStream(plotCanvas.getAdjustBounds() ? "icons/adjustbounds.png" : "icons/noadjustbounds.png"))));
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/math/plot/icons/adjustbounds.png b/src/main/java/org/math/plot/icons/adjustbounds.png
deleted file mode 100644
index 075f531..0000000
Binary files a/src/main/java/org/math/plot/icons/adjustbounds.png and /dev/null differ
diff --git a/src/main/java/org/math/plot/icons/back.png b/src/main/java/org/math/plot/icons/back.png
deleted file mode 100644
index 825c6f7..0000000
Binary files a/src/main/java/org/math/plot/icons/back.png and /dev/null differ
diff --git a/src/main/java/org/math/plot/icons/center.png b/src/main/java/org/math/plot/icons/center.png
deleted file mode 100644
index 37db0f6..0000000
Binary files a/src/main/java/org/math/plot/icons/center.png and /dev/null differ
diff --git a/src/main/java/org/math/plot/icons/data.png b/src/main/java/org/math/plot/icons/data.png
deleted file mode 100644
index b437f5b..0000000
Binary files a/src/main/java/org/math/plot/icons/data.png and /dev/null differ
diff --git a/src/main/java/org/math/plot/icons/edit.png b/src/main/java/org/math/plot/icons/edit.png
deleted file mode 100644
index 67f56f1..0000000
Binary files a/src/main/java/org/math/plot/icons/edit.png and /dev/null differ
diff --git a/src/main/java/org/math/plot/icons/noadjustbounds.png b/src/main/java/org/math/plot/icons/noadjustbounds.png
deleted file mode 100644
index f7e362a..0000000
Binary files a/src/main/java/org/math/plot/icons/noadjustbounds.png and /dev/null differ
diff --git a/src/main/java/org/math/plot/icons/position.png b/src/main/java/org/math/plot/icons/position.png
deleted file mode 100644
index ef53c24..0000000
Binary files a/src/main/java/org/math/plot/icons/position.png and /dev/null differ
diff --git a/src/main/java/org/math/plot/icons/rotation.png b/src/main/java/org/math/plot/icons/rotation.png
deleted file mode 100644
index ba7772a..0000000
Binary files a/src/main/java/org/math/plot/icons/rotation.png and /dev/null differ
diff --git a/src/main/java/org/math/plot/icons/scale.png b/src/main/java/org/math/plot/icons/scale.png
deleted file mode 100644
index 9f1d555..0000000
Binary files a/src/main/java/org/math/plot/icons/scale.png and /dev/null differ
diff --git a/src/main/java/org/math/plot/icons/toclipboard.png b/src/main/java/org/math/plot/icons/toclipboard.png
deleted file mode 100644
index b24a6f6..0000000
Binary files a/src/main/java/org/math/plot/icons/toclipboard.png and /dev/null differ
diff --git a/src/main/java/org/math/plot/icons/tofile.png b/src/main/java/org/math/plot/icons/tofile.png
deleted file mode 100644
index 41b3f43..0000000
Binary files a/src/main/java/org/math/plot/icons/tofile.png and /dev/null differ
diff --git a/src/main/java/org/math/plot/icons/topngfile.png b/src/main/java/org/math/plot/icons/topngfile.png
deleted file mode 100644
index 7208496..0000000
Binary files a/src/main/java/org/math/plot/icons/topngfile.png and /dev/null differ
diff --git a/src/main/java/org/math/plot/icons/zoom.png b/src/main/java/org/math/plot/icons/zoom.png
deleted file mode 100644
index 1b0ef4f..0000000
Binary files a/src/main/java/org/math/plot/icons/zoom.png and /dev/null differ
diff --git a/src/main/java/org/math/plot/plotObjects/Axis.java b/src/main/java/org/math/plot/plotObjects/Axis.java
index 34934fc..17893ec 100644
--- a/src/main/java/org/math/plot/plotObjects/Axis.java
+++ b/src/main/java/org/math/plot/plotObjects/Axis.java
@@ -238,13 +238,15 @@ public void plot(AbstractDrawer draw) {
                                 );
 
 			for (int i = 0; i < lightLabels.length; i=i+inc) {
-        			lightLabels[i].plot(draw);
+                                if(lightLabels[i]!=null)
+        			    lightLabels[i].plot(draw);
                         }
                         
                         draw.setLineType(AbstractDrawer.DOTTED_LINE);
                         for (int i = 0; i < lightLines.length; i++) {
                                  for (int j = base.getAxeScale(index).equalsIgnoreCase(Base.STRINGS) ? 0 : 1; j < lightLines[i].length; j=j+inc) {
-					lightLines[i][j].plot(draw);
+                                     if(lightLines[i][j]!=null)
+				         lightLines[i][j].plot(draw);
 				}
 			}
 		}
@@ -633,4 +635,4 @@ public static void main(String[] args) {
 			System.out.println(it.next());
 		}
 	}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/math/plot/plots/LinePlot.java b/src/main/java/org/math/plot/plots/LinePlot.java
index cf1c309..4bd8690 100644
--- a/src/main/java/org/math/plot/plots/LinePlot.java
+++ b/src/main/java/org/math/plot/plots/LinePlot.java
@@ -33,9 +33,17 @@ public void plot(AbstractDrawer draw, Color c) {
 		draw.setColor(c);
 		draw.setLineType(AbstractDrawer.CONTINOUS_LINE);
 		for (int i = 0; i < XY.length - 1; i++)
+                    if (!anyNaN(XY[i]) && !anyNaN(XY[i+1]))
 			draw.drawLine(XY[i], XY[i + 1]);
 	}
 
+        boolean anyNaN(double[] xy) {
+            for (int i = 0; i < xy.length; i++) {
+                if(Double.isNaN(xy[i])) return true;
+            }
+            return false;
+        }
+        
 	public static void main(String[] args) {
 		Plot2DPanel p2 = new Plot2DPanel();
 
@@ -44,6 +52,7 @@ public static void main(String[] args) {
 				XYZ[j][0] = 2*Math.PI*(double)j/XYZ.length;
 				XYZ[j][1] = Math.sin(XYZ[j][0]);
 			}
+                        XYZ[50][0] = Double.NaN;
 			p2.addLinePlot("sin" , XYZ);
 		
 
diff --git a/src/main/java/org/math/plot/render/Projection.java b/src/main/java/org/math/plot/render/Projection.java
index 5019a19..d3d3e01 100644
--- a/src/main/java/org/math/plot/render/Projection.java
+++ b/src/main/java/org/math/plot/render/Projection.java
@@ -28,7 +28,9 @@ public void initBaseCoordsProjection(boolean reset) {
         }
         for (int i = 0; i < draw.canvas.base.dimension + 1; i++) {
             // Compute the basis extremity coordinates in the normed-centered screen (ie [-0.5,0.5]x[-0.5,0.5] screen)
-            double[] ratio = baseCoordsScreenProjectionRatio(draw.canvas.base.baseCoords[i]);
+            double[] ratio = new double[]{1,1};
+            if (draw.canvas.base.baseCoords!=null)
+               ratio = baseCoordsScreenProjectionRatio(draw.canvas.base.baseCoords[i]);
             // Compute the basis extremity coordinates in the true screen (ie in px: [0,400]x[0,400])
             baseScreenCoords[i][0] = (int) (draw.canvas.getWidth() * (.5 + (borderCoeff * ratio[0] / totalScreenRatio[0])));
             baseScreenCoords[i][1] = (int) (draw.canvas.getHeight() * (.5 - (borderCoeff * ratio[1] / totalScreenRatio[1])));
@@ -89,7 +91,8 @@ public int[] screenProjection(double... pC) {
             if (draw.canvas.base.axesScales[i].equalsIgnoreCase(Base.LOGARITHM)) {
                 normdist_pC_baseCoords = ((FastMath.log(pC[i]) - FastMath.log(draw.canvas.base.baseCoords[0][i])) / (FastMath.log(draw.canvas.base.baseCoords[i + 1][i]) - FastMath.log(draw.canvas.base.baseCoords[0][i])));
             } else if (draw.canvas.base.axesScales[i].equalsIgnoreCase(Base.LINEAR) || draw.canvas.base.axesScales[i].equalsIgnoreCase(Base.STRINGS)) {
-                normdist_pC_baseCoords = ((pC[i] - draw.canvas.base.baseCoords[0][i]) / (draw.canvas.base.baseCoords[i + 1][i] - draw.canvas.base.baseCoords[0][i]));
+                if(pC!=null && draw.canvas.base.baseCoords!=null && draw.canvas.base.baseCoords[i+1] != null)
+                    normdist_pC_baseCoords = ((pC[i] - draw.canvas.base.baseCoords[0][i]) / (draw.canvas.base.baseCoords[i + 1][i] - draw.canvas.base.baseCoords[0][i]));
             }
             sC[0] += normdist_pC_baseCoords * (baseScreenCoords[i + 1][0] - baseScreenCoords[0][0]);
             sC[1] += normdist_pC_baseCoords * (baseScreenCoords[i + 1][1] - baseScreenCoords[0][1]);
diff --git a/src/main/java/org/math/plot/utils/Array.java b/src/main/java/org/math/plot/utils/Array.java
index 6a013c2..6dc0eb4 100644
--- a/src/main/java/org/math/plot/utils/Array.java
+++ b/src/main/java/org/math/plot/utils/Array.java
@@ -448,7 +448,9 @@ public static double[] min(double[][] M) {
         for (int j = 0; j < min.length; j++) {
             min[j] = M[0][j];
             for (int i = 1; i < M.length; i++) {
-                min[j] = FastMath.min(min[j], M[i][j]);
+                if (!Double.isNaN(M[i][j])) {
+                    min[j] = FastMath.min(min[j], M[i][j]);
+                }
             }
         }
         return min;
@@ -473,7 +475,9 @@ public static int max(int... M) {
     public static double min(double... M) {
         double min = M[0];
         for (int i = 1; i < M.length; i++) {
-            min = FastMath.min(min, M[i]);
+            if (!Double.isNaN(M[i])) {
+                min = FastMath.min(min, M[i]);
+            }
         }
         return min;
     }
@@ -483,7 +487,9 @@ public static double[] max(double[][] M) {
         for (int j = 0; j < max.length; j++) {
             max[j] = M[0][j];
             for (int i = 1; i < M.length; i++) {
-                max[j] = FastMath.max(max[j], M[i][j]);
+                if (!Double.isNaN(M[i][j])) {
+                    max[j] = FastMath.max(max[j], M[i][j]);
+                }
             }
         }
         return max;
@@ -492,7 +498,9 @@ public static double[] max(double[][] M) {
     public static double max(double... M) {
         double max = M[0];
         for (int i = 1; i < M.length; i++) {
-            max = FastMath.max(max, M[i]);
+            if (!Double.isNaN(M[i])) {
+                max = FastMath.max(max, M[i]);
+            }
         }
         return max;
     }
diff --git a/src/main/java/org/math/plot/utils/Histogram.java b/src/main/java/org/math/plot/utils/Histogram.java
index 651f10d..dd47d1b 100644
--- a/src/main/java/org/math/plot/utils/Histogram.java
+++ b/src/main/java/org/math/plot/utils/Histogram.java
@@ -26,8 +26,10 @@ public static double[] histogram(double[] values, double[] bounds) {
 		double[] h = new double[bounds.length - 1];
 		for (int i = 0; i < values.length; i++) {
 			for (int j = 0; j < h.length; j++) {
-				if (((bounds[j + 1] - values[i]) * (bounds[j] - values[i]) < 0) || ((bounds[j] == values[i])))
+				if (((bounds[j + 1] - values[i]) * (bounds[j] - values[i]) <= 0) || ((bounds[j] == values[i]))) {
 					h[j]++;
+					break;
+				}
 			}
 		}
 		return h;