diff --git a/examples/image_example.py b/examples/image_example.py
index e4fdb344b759aded33faa13b2f7558bf9f297a9a..251429ff26fc43aac32ff76f4769da3c8dac5de2 100644
--- a/examples/image_example.py
+++ b/examples/image_example.py
@@ -25,7 +25,11 @@ IMGS_AS_LIST = [IMG1, IMG2]
 
 # Example for how to use tagplot with image files
 FIGS_AND_IDS = tagplot(
-    IMGS_AS_LIST, "image", prefix=PROJECT_ID, id_method="time", location="west"
+    IMGS_AS_LIST,
+    "image",
+    prefix=PROJECT_ID,
+    id_method="time",
+    qrcode=True,
 )
 # Required arguments: tagplot(images as list, desired plot engine)
 
diff --git a/examples/matplotlib_example.py b/examples/matplotlib_example.py
index db348a5ec21a6f1cdd33bdbcb3e91edfa276636f..e9a57f3e071cb03597fcb7f95821ae8b6c26495b 100644
--- a/examples/matplotlib_example.py
+++ b/examples/matplotlib_example.py
@@ -40,7 +40,12 @@ FIGS_AS_LIST = [FIG1, FIG2]
 
 # Example for how to use tagplot with matplotlib figures
 FIGS_AND_IDS = tagplot(
-    FIGS_AS_LIST, "matplotlib", location="west", id_method="random", prefix=PROJECT_ID
+    FIGS_AS_LIST,
+    "matplotlib",
+    location="west",
+    id_method="random",
+    prefix=PROJECT_ID,
+    qrcode=True,
 )
 # Required arguments: tagplot(images as list, desired plot engine)
 
diff --git a/plotid/plotoptions.py b/plotid/plotoptions.py
index 8d6abbede22da98257b1fe216ebb017fa2928d1c..274aa48abe92a7640a917741ce6154d870903a1a 100644
--- a/plotid/plotoptions.py
+++ b/plotid/plotoptions.py
@@ -49,12 +49,27 @@ class PlotOptions:
         Will be added as prefix to the ID.
     id_method : str, optional
         id_method for creating the ID. Create an ID by Unix time is referenced
-        as 'time', create a random ID with id_method='random'.
-        The default is 'time'.
+        as "time", create a random ID with id_method="random".
+        The default is "time".
     qrcode : bool, optional
-        Experimental status. Print qrcode on exported plot. Default: False.
+        Encode the ID in a QR code on the exported plot. Default: False.
+    qr_position : tuple, optional
+        Position of the bottom right corner of the QR Code on the plot in relative
+        (x, y) coordinates. Default: (1, 0).
+    qr_size: int or float, optional
+        Size of the QR code in arbitrary units. Default: 100.
     id_on_plot: bool, optional
         Print ID on the plot. Default: True.
+    font: str, optional
+        Font that will be used to print the ID. A path to an .otf or a .ttf
+        file has to be given. To use already installed fonts, you can search for the
+        standard path of fonts on your operating system and give then the path of the
+        desired font file to this parameter.
+    fontsize: int, optional
+        Fontsize for the displayed ID. Default: 12.
+    fontcolor: tuple, optional
+        Fontcolor for the ID. Must be given as tuple containing three rgb values with
+        each value between [0, 1]. Default: (0, 0, 0).
     """
 
     def __init__(
@@ -72,7 +87,14 @@ class PlotOptions:
         self.prefix = kwargs.get("prefix", "")
         self.id_method = kwargs.get("id_method", "time")
         self.qrcode = kwargs.get("qrcode", False)
+        self.qr_position = kwargs.get("qr_position", (1, 0))
+        self.qr_size = kwargs.get("qr_size", 100)
         self.id_on_plot = kwargs.get("id_on_plot", True)
+        self.font = kwargs.get("font", False)
+        if self.font:
+            self.font = os.path.abspath(self.font)
+        self.fontsize = kwargs.get("fontsize", 12)
+        self.fontcolor = kwargs.get("fontcolor", (0, 0, 0))
 
     def __str__(self) -> str:
         """Representation if an object of this class is printed."""
diff --git a/plotid/resources/OpenSans/OFL.txt b/plotid/resources/OpenSans/OFL.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9b448d4017f9233c21ae6db92c90bc2d229f56b2
--- /dev/null
+++ b/plotid/resources/OpenSans/OFL.txt
@@ -0,0 +1,93 @@
+Copyright 2020 The Open Sans Project Authors (https://github.com/googlefonts/opensans)
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded, 
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/plotid/resources/OpenSans/OpenSans-Bold.ttf b/plotid/resources/OpenSans/OpenSans-Bold.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..a1398b338084cbaf0e99d89cb6089715baa78a6d
Binary files /dev/null and b/plotid/resources/OpenSans/OpenSans-Bold.ttf differ
diff --git a/plotid/resources/OpenSans/OpenSans-Regular.ttf b/plotid/resources/OpenSans/OpenSans-Regular.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..1dc226ddc00a11a9813844b00fb5edaf87921c38
Binary files /dev/null and b/plotid/resources/OpenSans/OpenSans-Regular.ttf differ
diff --git a/plotid/resources/__init__.py b/plotid/resources/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/plotid/tagplot.py b/plotid/tagplot.py
index 25373320b4c6ed4228b543885b2b9e5164f1d480..f5dd420c5a53854fdb0b62abfa1a0e28724a484d 100644
--- a/plotid/tagplot.py
+++ b/plotid/tagplot.py
@@ -5,9 +5,6 @@ Tag your plot with an ID.
 
 For publishing the tagged plot along your research data have a look at the
 module publish.
-
-Functions:
-    tagplot(figure object, string) -> list
 """
 
 import warnings
@@ -23,7 +20,6 @@ from plotid.tagplot_image import tagplot_image
 def tagplot(
     figs: plt.Figure | Image | list[plt.Figure | Image],
     engine: Literal["matplotlib", "image"],
-    location: str = "east",
     **kwargs: Any,
 ) -> PlotIDTransfer:
     """
@@ -38,28 +34,54 @@ def tagplot(
         Figures that should be tagged.
     engine :
         Plot engine which should be used to tag the plot.
-    location : str, optional
-        Location for ID to be displayed on the plot. Default is 'east'.
     **kwargs : dict, optional
         Extra arguments for additional plot options.
 
     Other Parameters
     ----------------
+    location : str, optional
+        Location for ID to be displayed on the plot. Default is "east".
+    rotation: float or int, optional
+        Rotation of the printed ID in degree. Overwrites the value defined by location.
+    position: tuple of float, optional
+        Position of the ID given as (x,y). x and y are relative coordinates in respect
+        to the figure size and must be in the intervall [0,1]. Overwrites the value
+        defined by location.
     prefix : str, optional
         Will be added as prefix to the ID.
     id_method : str, optional
         id_method for creating the ID. Create an ID by Unix time is referenced
-        as 'time', create a random ID with id_method='random'.
-        The default is 'time'.
-    qrcode : boolean, optional
-        Experimental support for encoding the ID in a QR Code.
+        as "time", create a random ID with id_method="random".
+        The default is "time".
+    qrcode : bool, optional
+         Encode the ID in a QR code on the exported plot. Default: False.
+    qr_position : tuple, optional
+        Position of the bottom right corner of the QR Code on the plot in relative
+        (x, y) coordinates. Default: (1, 0).
+    qr_size: int or float, optional
+        Size of the QR code in arbitrary units. Default: 100.
+    id_on_plot: bool, optional
+         Print ID on the plot. Default: True.
+    font: str, optional
+        Font that will be used to print the ID. An absolute path to an .otf or a .ttf
+        file has to be given. To use already installed fonts, you can search for the
+        standard path of fonts on your operating system and give then the path of the
+        desired font file to this parameter.
+    fontsize: int, optional
+        Fontsize for the displayed ID. Default: 12.
+    fontcolor: tuple, optional
+        Fontcolor for the ID. Must be given as tuple containing three rgb values with
+        each value between [0, 1]. Default: (0, 0, 0).
 
     Raises
     ------
     TypeError
         If specified location is not given as string.
+        If rotation was not given as number.
+        If position was not given as tuple containing two floats.
     ValueError
         If an unsupported plot engine is given.
+        If position tuple does not contain two items.
 
     Returns
     -------
@@ -68,9 +90,8 @@ def tagplot(
         figures were given. The first list contains the tagged figures.
         The second list contains the corresponding IDs as strings.
     """
-    if isinstance(location, str):
-        pass
-    else:
+    location = kwargs.get("location", "east")
+    if not isinstance(location, str):
         raise TypeError("Location is not a string.")
 
     match location:
@@ -89,9 +110,6 @@ def tagplot(
         case "southeast":
             rotation = 0
             position = (0.75, 0.015)
-        case "custom":
-            # TODO: Get rotation and position from user input & check if valid
-            pass
         case _:
             warnings.warn(
                 f'Location "{location}" is not a defined '
@@ -101,6 +119,19 @@ def tagplot(
             rotation = 90
             position = (0.975, 0.35)
 
+    if "rotation" in kwargs:
+        rotation = kwargs.pop("rotation")
+        if not isinstance(rotation, (int, float)):
+            raise TypeError("Rotation is not a float or integer.")
+    if "position" in kwargs:
+        position = kwargs.pop("position")
+        if not isinstance(position, tuple):
+            raise TypeError("Position is not a tuple of floats.")
+        if not len(position) == 2:
+            raise ValueError("Position does not contain two items.")
+        if not all(isinstance(item, float) for item in position):
+            raise TypeError("Position is not a tuple of floats.")
+
     option_container = PlotOptions(figs, rotation, position, **kwargs)
     option_container.validate_input()
 
diff --git a/plotid/tagplot_image.py b/plotid/tagplot_image.py
index ca1b869ceddac31031abc795a6442361877b5122..86a92dce2dd61bae1fd1205b7f9c2d18931d93de 100644
--- a/plotid/tagplot_image.py
+++ b/plotid/tagplot_image.py
@@ -6,6 +6,8 @@ Functions:
     tagplot_image(PlotOptions instance) -> PlotIDTransfer instance
 """
 import os
+import warnings
+from importlib.resources import files
 from PIL import Image, ImageDraw, ImageFont, ImageOps
 from plotid.create_id import create_id, create_qrcode
 from plotid.plotoptions import PlotOptions, PlotIDTransfer
@@ -37,11 +39,22 @@ def tagplot_image(plotid_object: PlotOptions) -> PlotIDTransfer:
         if not isinstance(img, str):
             raise TypeError("Name of the image is not a string.")
         if not os.path.isfile(img):
-            raise TypeError("File does not exist.")
+            raise TypeError(f"Image '{img}' does not exist.")
             # Check if figs is a valid file is done by pillow internally
 
-    color = (128, 128, 128)  # grey
-    font = ImageFont.load_default()
+    color = tuple(rgb_value * 255 for rgb_value in plotid_object.fontcolor)
+    # font = ImageFont.load_default()
+    font_path = (
+        files("plotid.resources").joinpath("OpenSans").joinpath("OpenSans-Regular.ttf")
+    )
+    font = ImageFont.truetype(str(font_path), plotid_object.fontsize)
+
+    if plotid_object.font:
+        try:
+            # Absolute path to font file (.ttf or .otf) has to be given
+            font = ImageFont.truetype(plotid_object.font, plotid_object.fontsize)
+        except OSError:
+            warnings.warn("Font was not found.\nplotID continues with fallback font.")
 
     for i, img in enumerate(plotid_object.figs):
         img_id = plotid_object.prefix + create_id(plotid_object.id_method)
@@ -64,8 +77,21 @@ def tagplot_image(plotid_object: PlotOptions) -> PlotIDTransfer:
 
         if plotid_object.qrcode:
             qrcode = create_qrcode(img_id)
-            qrcode.thumbnail((100, 100), Image.ANTIALIAS)
-            img.paste(qrcode, box=(img.width - 100, img.height - 100))
+            qrcode.thumbnail(
+                (plotid_object.qr_size, plotid_object.qr_size), Image.ANTIALIAS
+            )
+            img.paste(
+                qrcode,
+                box=(
+                    int(
+                        img.width * plotid_object.qr_position[0] - plotid_object.qr_size
+                    ),
+                    int(
+                        img.height * (1 - plotid_object.qr_position[1])
+                        - plotid_object.qr_size
+                    ),
+                ),
+            )
         plotid_object.figs[i] = img
 
     figs_and_ids = PlotIDTransfer(plotid_object.figs, plotid_object.figure_ids)
diff --git a/plotid/tagplot_matplotlib.py b/plotid/tagplot_matplotlib.py
index 8d83baf82cc44fc2f9495060b99a79002a77a2bc..1da6cce9e058d1586f51047c9db0935b3abf053c 100644
--- a/plotid/tagplot_matplotlib.py
+++ b/plotid/tagplot_matplotlib.py
@@ -1,6 +1,7 @@
 # -*- coding: utf-8 -*-
 """Tag your matplotlib plot with an ID."""
 
+from importlib.resources import files
 import matplotlib
 import matplotlib.pyplot as plt
 from PIL import Image
@@ -35,8 +36,18 @@ def tagplot_matplotlib(plotid_object: PlotOptions) -> PlotIDTransfer:
         if not isinstance(figure, matplotlib.figure.Figure):
             raise TypeError("Figure is not a valid matplotlib-figure.")
 
-    fontsize = "small"
-    color = "grey"
+    if plotid_object.font:
+        # Load custom font into matplotlib
+        matplotlib.font_manager.fontManager.addfont(plotid_object.font)
+        font = matplotlib.font_manager.FontProperties(fname=plotid_object.font)
+    else:
+        font = (
+            files("plotid.resources")
+            .joinpath("OpenSans")
+            .joinpath("OpenSans-Regular.ttf")
+        )
+        matplotlib.font_manager.fontManager.addfont(str(font))
+        font = matplotlib.font_manager.FontProperties(fname=font)
 
     # Loop to create and position the IDs
     for fig in plotid_object.figs:
@@ -46,6 +57,7 @@ def tagplot_matplotlib(plotid_object: PlotOptions) -> PlotIDTransfer:
         plt.figure(fig)
 
         if plotid_object.id_on_plot:
+
             plt.figtext(
                 x=plotid_object.position[0],
                 y=plotid_object.position[1],
@@ -53,14 +65,22 @@ def tagplot_matplotlib(plotid_object: PlotOptions) -> PlotIDTransfer:
                 ha="left",
                 wrap=True,
                 rotation=plotid_object.rotation,
-                fontsize=fontsize,
-                color=color,
+                fontsize=plotid_object.fontsize,
+                color=plotid_object.fontcolor,
+                font=font,
             )
 
         if plotid_object.qrcode:
             qrcode = create_qrcode(fig_id)
-            qrcode.thumbnail((100, 100), Image.ANTIALIAS)
-            fig.figimage(qrcode, fig.bbox.xmax - 100, 0, cmap="bone")
+            qrcode.thumbnail(
+                (plotid_object.qr_size, plotid_object.qr_size), Image.ANTIALIAS
+            )
+            fig.figimage(
+                qrcode,
+                fig.bbox.xmax * plotid_object.qr_position[0] - plotid_object.qr_size,
+                fig.bbox.ymax * plotid_object.qr_position[1],
+                cmap="bone",
+            )
             fig.tight_layout()
 
     figs_and_ids = PlotIDTransfer(plotid_object.figs, plotid_object.figure_ids)
diff --git a/tests/test_plotoptions.py b/tests/test_plotoptions.py
index b9ba6504d18b8875fd8c4278190957d6e165e997..8d3f5e1f91a59212a85b050a57a418fdb1e5073a 100644
--- a/tests/test_plotoptions.py
+++ b/tests/test_plotoptions.py
@@ -48,10 +48,11 @@ class TestTagplot(unittest.TestCase):
         )
         self.assertEqual(
             str(plot_obj),
-            "<class 'plotid.plotoptions.PlotOptions'>: {'figs': "
-            "'FIG', 'figure_ids': [], 'rotation': 270, 'position'"
-            ": (100, 200), 'prefix': 'xyz', 'id_method': "
-            "'random', 'qrcode': False, 'id_on_plot': False}",
+            "<class 'plotid.plotoptions.PlotOptions'>: {'figs': 'FIG', 'figure_ids': "
+            "[], 'rotation': 270, 'position': (100, 200), 'prefix': 'xyz', 'id_method':"
+            " 'random', 'qrcode': False, 'qr_position': (1, 0), 'qr_size': 100, "
+            "'id_on_plot': False, 'font': False, 'fontsize': 12, 'fontcolor': "
+            "(0, 0, 0)}",
         )
 
     def test_str_plotidtransfer(self) -> None:
diff --git a/tests/test_tagplot.py b/tests/test_tagplot.py
index 5754f2b72332adfbd24bd29b10a0144103e77657..22bd8980ccd7ff754ef4877647a0b8d395a3d72a 100644
--- a/tests/test_tagplot.py
+++ b/tests/test_tagplot.py
@@ -36,8 +36,23 @@ class TestTagplot(unittest.TestCase):
         Test if tagplot runs successful.
         """
         tagplot(FIGS_AS_LIST, PLOT_ENGINE, prefix=PROJECT_ID, id_method=METHOD)
+        tagplot(FIGS_AS_LIST, PLOT_ENGINE, rotation=42, position=(0.3, 0.14))
         tagplot(IMGS_AS_LIST, "image", location="north")
 
+    def test_rotation(self) -> None:
+        """Test if Error is raised if rotation is not a number."""
+        with self.assertRaises(TypeError):
+            tagplot(FIGS_AS_LIST, PLOT_ENGINE, rotation="42")
+
+    def test_position(self) -> None:
+        """Test if Error is raised if position is not a tuple containing two numbers."""
+        with self.assertRaises(ValueError):
+            tagplot(FIGS_AS_LIST, PLOT_ENGINE, position=(0.3, 0.14, 5))
+        with self.assertRaises(TypeError):
+            tagplot(FIGS_AS_LIST, PLOT_ENGINE, position=0.3)
+        with self.assertRaises(TypeError):
+            tagplot(FIGS_AS_LIST, PLOT_ENGINE, position=(0.3, True))
+
     def test_prefix(self) -> None:
         """Test if Error is raised if prefix is not a string."""
         with self.assertRaises(TypeError):
diff --git a/tests/test_tagplot_image.py b/tests/test_tagplot_image.py
index 1dea02dc55d5e0a3adde55f1b1fae25bfaa598c6..727243fada6612c2a87a084646c199f38d10ee01 100644
--- a/tests/test_tagplot_image.py
+++ b/tests/test_tagplot_image.py
@@ -46,6 +46,9 @@ class TestTagplotImage(unittest.TestCase):
             prefix=PROJECT_ID,
             id_method=METHOD,
             qrcode=True,
+            fontsize=10,
+            font="plotid/resources/OpenSans/OpenSans-Bold.ttf",
+            fontcolor=(0, 1, 0),
         )
         options.validate_input()
         figs_and_ids = tagplot_image(options)
@@ -85,6 +88,13 @@ class TestTagplotImage(unittest.TestCase):
         with self.assertRaises(TypeError):
             tagplot_image("wrong_object")
 
+    def test_font_file_not_defined(self) -> None:
+        """Test if a Warning is raised if an invalid font file was specified."""
+        options = PlotOptions(IMG1, ROTATION, POSITION, font="font")
+        options.validate_input()
+        with self.assertWarns(Warning):
+            tagplot_image(options)
+
     def tearDown(self) -> None:
         os.remove(IMG1)
         os.remove(IMG2)
diff --git a/tests/test_tagplot_matplotlib.py b/tests/test_tagplot_matplotlib.py
index 2142698b585d91ea194fe68ed6b53f614c04f865..d7e59d9f3825a465614f3179088a8b4d501106d9 100644
--- a/tests/test_tagplot_matplotlib.py
+++ b/tests/test_tagplot_matplotlib.py
@@ -36,6 +36,9 @@ class TestTagplotMatplotlib(unittest.TestCase):
             prefix=PROJECT_ID,
             id_method=METHOD,
             qrcode=True,
+            fontsize=10,
+            font="plotid/resources/OpenSans/OpenSans-Bold.ttf",
+            fontcolor=(0, 0, 1),
         )
         options.validate_input()
         figs_and_ids = tagplot_matplotlib(options)