diff --git a/plotting/roofline.py b/plotting/roofline.py
new file mode 100644
index 0000000000000000000000000000000000000000..19e1c71928ab4c4c4e4ea7d445a158a3bbf5b551
--- /dev/null
+++ b/plotting/roofline.py
@@ -0,0 +1,85 @@
+import plotly.graph_objs as go
+from dataclasses import dataclass
+
+
+@dataclass
+class CPUInfo:
+    name: str
+    max_perf: float  # MFLOP/s
+    max_band: float  # MByte/s
+
+
+SKYLAKE = CPUInfo("Intel(R) Xeon(R) Gold 6148 CPU @ 2.40GHz",
+                  max_perf=5582274.03,
+                  max_band=159321.74)
+
+DEFAULT_MARKER = dict(size=10, color='green')
+
+
+def add_rooflines(fig, peak_perf, max_bw, max_x):
+    # Calculate maximum flops/byte value
+    ridge_point = peak_perf / max_bw
+
+    # Add horizontal bandwidth roofline
+    x_bw = [ridge_point, max_x]
+    y_bw = [peak_perf, peak_perf]
+    fig.add_trace(go.Scatter(x=x_bw, y=y_bw, mode='lines+text',
+                             name="Compute Roofline",
+                             text=[f'Peak Performance {peak_perf/1e9} GFlop/s',],
+                             textposition="top right",
+                  line=dict(color='blue', width=2)))
+
+    # Add diagonal compute roofline
+    x_compute = [0, ridge_point]
+    y_compute = [0, peak_perf]
+    fig.add_trace(go.Scatter(x=x_compute, y=y_compute, mode='lines+text',
+                             name="Memory Roofline",
+                             text=["", f"Memory bandwidth : {max_bw/1e9} GB/s",],
+                             textposition="bottom left",
+                  line=dict(color='green', width=2)))
+
+    return fig
+
+
+def add_data_point(fig, x, y, *,
+                   name="",
+                   marker=DEFAULT_MARKER,
+                   ):
+    fig.add_trace(go.Scatter(
+        x=[x],
+        y=[y],
+        mode='markers',
+        marker=marker,
+        name=name
+    ))
+    return fig
+
+
+def set_axis(fig):
+    # Add roofline axes labels
+    fig.update_layout(
+        xaxis=dict(
+            type='log',
+            title='Operational Intensity (Flop/Byte)',
+            zeroline=True
+        ),
+        yaxis=dict(
+            type='log',
+            title='Performance (Flop/s)',
+            zeroline=True
+        )
+    )
+    return fig
+
+
+def create_plot(peak_perf, max_band):
+    fig = go.Figure()
+    fig = add_rooflines(fig, peak_perf, max_band, 100)
+    fig = set_axis(fig)
+    return fig
+
+
+def add_data_points(fig, data_points, marker=DEFAULT_MARKER):
+    for oi, perf, name in data_points:
+        fig = add_data_point(fig, oi, perf, name=name, marker=marker)
+    return fig
diff --git a/setup.py b/setup.py
index 653668b2cb101cbf0866935f7fa57dd132e1fed6..0b81b7340c70e918be36129df335d0305d303ac0 100644
--- a/setup.py
+++ b/setup.py
@@ -8,13 +8,16 @@ setup(name="cb-util",
       author_email="Christoph.alt@fau.de",
       packages=find_packages(include=["cbutil",
                                       "cbutil.postprocessing",
-                                      "dashboards"]),
+                                      "dashboards",
+                                      "plotting"]),
       install_requires=[
           "python-dotenv",
           "influxdb",
           "gitpython",
           "grafanalib",
           "requests",
+          "plotly",
+          "kaleido",
       ],
       setup_requires=['pytest-runner'],
       tests_require=['pytest']