diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LCircle.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LCircle.java
new file mode 100644
index 0000000000000000000000000000000000000000..e4aee832004c117348eaa9b543f9004df154eca6
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LCircle.java
@@ -0,0 +1,64 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (C) 2001-3 Paul Murrell
+ * Copyright (c) 1998-2013, The R Core Team
+ * Copyright (c) 2017, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+package com.oracle.truffle.r.library.fastrGrid;
+
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.abstractVectorValue;
+
+import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.r.library.fastrGrid.Unit.UnitConversionContext;
+import com.oracle.truffle.r.library.fastrGrid.ViewPortContext.VPContextFromVPNode;
+import com.oracle.truffle.r.library.fastrGrid.ViewPortTransform.GetViewPortTransformNode;
+import com.oracle.truffle.r.library.fastrGrid.device.DrawingContext;
+import com.oracle.truffle.r.library.fastrGrid.device.GridDevice;
+import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode;
+import com.oracle.truffle.r.runtime.data.RList;
+import com.oracle.truffle.r.runtime.data.RNull;
+import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
+
+public abstract class LCircle extends RExternalBuiltinNode.Arg3 {
+    @Child private Unit.UnitToInchesNode unitToInches = Unit.createToInchesNode();
+    @Child private Unit.UnitLengthNode unitLength = Unit.createLengthNode();
+    @Child private GetViewPortTransformNode getViewPortTransform = new GetViewPortTransformNode();
+    @Child private VPContextFromVPNode vpContextFromVP = new VPContextFromVPNode();
+
+    static {
+        Casts casts = new Casts(LCircle.class);
+        casts.arg(0).mustBe(abstractVectorValue());
+        casts.arg(1).mustBe(abstractVectorValue());
+        casts.arg(2).mustBe(abstractVectorValue());
+    }
+
+    public static LCircle create() {
+        return LCircleNodeGen.create();
+    }
+
+    @Specialization
+    Object doCircle(RAbstractVector xVec, RAbstractVector yVec, RAbstractVector radiusVec) {
+        GridContext ctx = GridContext.getContext();
+        GridDevice dev = ctx.getCurrentDevice();
+
+        RList currentVP = ctx.getGridState().getViewPort();
+        DrawingContext drawingCtx = GPar.asDrawingContext(ctx.getGridState().getGpar());
+        ViewPortTransform vpTransform = getViewPortTransform.execute(currentVP);
+        ViewPortContext vpContext = vpContextFromVP.execute(currentVP);
+        UnitConversionContext conversionCtx = new UnitConversionContext(vpTransform.size, vpContext, drawingCtx);
+
+        int length = GridUtils.maxLength(unitLength, xVec, yVec, radiusVec);
+        for (int i = 0; i < length; i++) {
+            double radius = unitToInches.convertX(radiusVec, i, conversionCtx);
+            Point origLoc = Point.fromUnits(unitToInches, xVec, yVec, i, conversionCtx);
+            Point loc = TransformMatrix.transLocation(origLoc, vpTransform.transform);
+            dev.drawCircle(drawingCtx, loc.x, loc.y, radius);
+        }
+        return RNull.instance;
+    }
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/GridDevice.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/GridDevice.java
index 278e25ff3d6d6b287652bf18bec551e0a90e492b..3d878b99c0103650a980b52c5e58726b38df61f2 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/GridDevice.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/GridDevice.java
@@ -33,9 +33,15 @@ public interface GridDevice {
 
     void drawRect(DrawingContext ctx, double leftX, double topY, double heigh, double width);
 
+    /**
+     * Connects given points with a line, there has to be at least two points in order to actually
+     * draw somethig.
+     */
     void drawPolyLines(DrawingContext ctx, double[] x, double[] y, int startIndex, int length);
 
-    void drawString(DrawingContext ctx, double x, double y, double rotation, String text);
+    void drawCircle(DrawingContext ctx, double centerX, double centerY, double radius);
+
+    void drawString(DrawingContext ctx, double leftX, double bottomY, double rotation, String text);
 
     /**
      * @return The width of the device in inches.
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/JFrameDevice.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/JFrameDevice.java
index aee82b61324b09871f059c925bb425f264f84d84..cf13bfd2328bef0a2ea44f65eb82af69864431ab 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/JFrameDevice.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/JFrameDevice.java
@@ -25,7 +25,9 @@ package com.oracle.truffle.r.library.fastrGrid.device;
 import java.awt.BasicStroke;
 import java.awt.Color;
 import java.awt.Graphics2D;
+import java.awt.RenderingHints;
 import java.awt.geom.AffineTransform;
+import java.awt.geom.Ellipse2D;
 import java.awt.geom.Path2D;
 import java.awt.geom.Rectangle2D;
 import java.util.function.Supplier;
@@ -51,6 +53,8 @@ public class JFrameDevice implements GridDevice {
             graphics.translate(0, currentFrame.getHeight());
             graphics.scale(72, -72); // doc: 72 points ~ 1 inch
             graphics.setStroke(new BasicStroke(1f / 72f));
+            graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+            graphics.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
         } else {
             noTranform(() -> {
                 graphics.clearRect(0, 0, currentFrame.getWidth(), currentFrame.getHeight());
@@ -79,11 +83,17 @@ public class JFrameDevice implements GridDevice {
     }
 
     @Override
-    public void drawString(DrawingContext ctx, double x, double y, double rotation, String text) {
+    public void drawCircle(DrawingContext ctx, double centerX, double centerY, double radius) {
+        setContext(ctx);
+        graphics.draw(new Ellipse2D.Double(centerX - radius, centerY - radius, radius * 2d, radius * 2d));
+    }
+
+    @Override
+    public void drawString(DrawingContext ctx, double leftX, double bottomY, double rotation, String text) {
         setContext(ctx);
         noTranform(() -> {
             graphics.rotate(rotation);
-            graphics.drawString(text, (float) x * 72f, (float) (currentFrame.getContentPane().getHeight() - y * 72f));
+            graphics.drawString(text, (float) leftX * 72f, (float) (currentFrame.getContentPane().getHeight() - bottomY * 72f));
             return null;
         });
     }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java
index 29c9cc4d625a3aab0b9371d8c0bb84f3980ddd11..f5e5f53006eef22525b622fa99be8f9feac1812f 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java
@@ -25,6 +25,7 @@ import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.r.library.fastrGrid.GridStateGetNode;
 import com.oracle.truffle.r.library.fastrGrid.GridStateSetNode;
 import com.oracle.truffle.r.library.fastrGrid.IgnoredGridExternal;
+import com.oracle.truffle.r.library.fastrGrid.LCircle;
 import com.oracle.truffle.r.library.fastrGrid.LGridDirty;
 import com.oracle.truffle.r.library.fastrGrid.LInitGrid;
 import com.oracle.truffle.r.library.fastrGrid.LInitViewPortStack;
@@ -696,6 +697,8 @@ public class CallAndExternalFunctions {
                     return LText.create();
                 case "L_segments":
                     return LSegments.create();
+                case "L_circle":
+                    return LCircle.create();
 
                 // Simple grid state access
                 case "L_getGPar":
diff --git a/mx.fastr/copyrights/overrides b/mx.fastr/copyrights/overrides
index b9a4e7de5c3a1b693b7eb5ced22a2739f83b77e9..86618d197ae52cb4283b5053f27ece09aae742a3 100644
--- a/mx.fastr/copyrights/overrides
+++ b/mx.fastr/copyrights/overrides
@@ -787,3 +787,4 @@ com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LLines.j
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/ViewPortTransform.java,gnu_r_murrel_core.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LGridDirty.java,gnu_r_murrel_core.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/ColorNames.java,gnu_r.copyright
+com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/LCircle.java,gnu_r_murrel_core.copyright