diff --git a/.gitignore b/.gitignore
index ed444c0ce60790240ee8ec62f24b6b8475010158..391b49d59820a17e3c99b2315449c5e0d86dbd12 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,8 @@
 *.pot
 *.py[co]
 .tox/
+*.ipynb
+.ipynb_checkpoints/
 __pycache__
 MANIFEST
 .coverage
diff --git a/core/urls.py b/core/urls.py
index ecdca6469797922d942ac56662e7cae62901f6c8..980b803769fe1cf7ae497d738fd44908048b09eb 100644
--- a/core/urls.py
+++ b/core/urls.py
@@ -23,6 +23,7 @@ router.register('assignment', views.AssignmentApiViewSet)
 router.register('statistics', views.StatisticsEndpoint, basename='statistics')
 router.register('user', views.UserAccountViewSet, basename='user')
 router.register('label', views.LabelApiViewSet, basename='label')
+router.register('label-statistics', views.LabelStatistics, basename='label-statistics')
 
 schema_view = get_schema_view(
     openapi.Info(
diff --git a/core/views/__init__.py b/core/views/__init__.py
index 96c0465ab8f4b28b174100e09cbed5c0a8a43ab2..64f568df3ea9115cdb646beec0cefb017d6d9855 100644
--- a/core/views/__init__.py
+++ b/core/views/__init__.py
@@ -2,4 +2,4 @@ from .feedback import FeedbackApiView, FeedbackCommentApiView  # noqa
 from .subscription import SubscriptionApiViewSet, AssignmentApiViewSet  # noqa
 from .common_views import *  # noqa
 from .export import StudentJSONExport, InstanceExport  # noqa
-from .label import LabelApiViewSet  # noqa
+from .label import LabelApiViewSet, LabelStatistics  # noqa
diff --git a/core/views/common_views.py b/core/views/common_views.py
index c4a84262962a9f32813a6e20ce7886f3fc738f9b..3c945d76c3790b81bcdd282483d3c454f4343f82 100644
--- a/core/views/common_views.py
+++ b/core/views/common_views.py
@@ -127,9 +127,11 @@ class SubmissionTypeApiView(viewsets.ReadOnlyModelViewSet):
     """ Gets a list or a detail view of a single SubmissionType """
     queryset = SubmissionType.objects.all()
     serializer_class = SubmissionTypeSerializer
+    permission_classes = (IsTutorOrReviewer, )
 
 
 class StatisticsEndpoint(viewsets.ViewSet):
+    permission_classes = (IsTutorOrReviewer, )
 
     def list(self, request, *args, **kwargs):
         first_sub_type = models.SubmissionType.objects.first()
diff --git a/core/views/label.py b/core/views/label.py
index c1b4a02a6266a4056d6234bf3b9997b5afbe98e5..e7ffa3928d5931fd28d5660e5093dc66dcee944b 100644
--- a/core/views/label.py
+++ b/core/views/label.py
@@ -1,8 +1,12 @@
 import logging
 
+from django.db.models import Case, When, IntegerField, Sum, Q
+
 from rest_framework import mixins, viewsets
+from rest_framework.response import Response
 
 from core import models, permissions, serializers
+from core.models import SubmissionType, FeedbackLabel
 
 log = logging.getLogger(__name__)
 
@@ -14,3 +18,32 @@ class LabelApiViewSet(viewsets.GenericViewSet,
     permission_classes = (permissions.IsTutorOrReviewer, )
     queryset = models.FeedbackLabel.objects.all()
     serializer_class = serializers.LabelSerializer
+
+
+class LabelStatistics(viewsets.ViewSet):
+
+    permission_classes = (permissions.IsTutorOrReviewer, )
+
+    def list(self, *args, **kwargs):
+        # TODO This is horribly ugly and should be killed with fire
+        # however, i'm unsure whether there is a better way to retrieve the
+        # information that hits the database less often
+        labels = FeedbackLabel.objects.all()
+
+        counts = list(SubmissionType.objects.annotate(
+            **{str(label.pk): Sum(
+                Case(
+                    # if the feedback has a label or there is a visible comment with that
+                    # label add 1 to the count
+                    When(
+                        Q(submissions__feedback__labels=label) |
+                        Q(submissions__feedback__feedback_lines__labels=label) &
+                        Q(submissions__feedback__feedback_lines__visible_to_student=True),
+                        then=1),
+                    output_field=IntegerField(),
+                    default=0
+                )
+            ) for label in labels}
+        ).values('pk', *[str(label.pk) for label in labels]))
+
+        return Response(list(counts))
diff --git a/frontend/src/api.ts b/frontend/src/api.ts
index a96d779f563aa4eec09f9a14733999aaeb3a7985..e34d47a3196f4b44edef05ac91be395ae492ac03 100644
--- a/frontend/src/api.ts
+++ b/frontend/src/api.ts
@@ -11,7 +11,8 @@ import {
   Submission,
   SubmissionNoType, SubmissionType,
   Subscription,
-  Tutor, UserAccount, FeedbackLabel
+  Tutor, UserAccount, LabelStatisticsForSubType,
+  FeedbackLabel
 } from '@/models'
 
 function getInstanceBaseUrl (): string {
@@ -113,6 +114,11 @@ export async function fetchStatistics (): Promise<Statistics> {
   return (await ax.get(url)).data
 }
 
+export async function fetchLabelStatistics (): Promise<LabelStatisticsForSubType  []> {
+  const url = '/api/label-statistics'
+  return (await ax.get(url)).data
+}
+
 interface SubscriptionCreatePayload {
     queryType: Subscription.QueryTypeEnum
     queryKey?: string
diff --git a/frontend/src/components/CorrectionStatistics.vue b/frontend/src/components/CorrectionStatistics.vue
index b720c8525dfda37fb90940199d3964f89fd893a7..fe55e9fa8483cf674d6dcc068d127b74d7d854a4 100644
--- a/frontend/src/components/CorrectionStatistics.vue
+++ b/frontend/src/components/CorrectionStatistics.vue
@@ -1,34 +1,34 @@
 <template>
-    <v-card class="py-2" id="correction-statistics">
-      <v-card-title>
-        <span class="title">Statistics</span>
-      </v-card-title>
-      <div v-if="loaded">
-        <ul class="inline-list mx-3">
-          <li>Submissions per participant: <span>{{statistics.submissionsPerStudent}}</span></li>
-          <li>Submissions per type: <span>{{statistics.submissionsPerType}}</span></li>
-          <li>Curr. mean score:
-            <span>
-              {{statistics.currentMeanScore === null ? 'N.A.' : statistics.currentMeanScore.toFixed(2)}}
-            </span>
-          </li>
-        </ul>
-        <v-divider class="mx-2 my-2"></v-divider>
-        <div v-for="(progress, index) in statistics.submissionTypeProgress" :key="index">
-          <v-card-title class="py-0">
-            {{progress.name}}
-          </v-card-title>
-          <div class="mx-3">
-            <v-progress-linear
-              :value="progress.feedbackFinal / progress.submissionCount * 100"
-              buffer
-              :buffer-value="(progress.feedbackInValidation + progress.feedbackFinal) * 100 / progress.submissionCount"
-              :color="progress.feedbackFinal === progress.submissionCount ? 'green' : 'blue'"
-            />
-          </div>
+  <v-card class="py-2" id="correction-statistics">
+    <v-card-title>
+      <span class="title">Statistics</span>
+    </v-card-title>
+    <div v-if="loaded">
+      <ul class="inline-list mx-3">
+        <li>Submissions per participant: <span>{{statistics.submissionsPerStudent}}</span></li>
+        <li>Submissions per type: <span>{{statistics.submissionsPerType}}</span></li>
+        <li>Curr. mean score:
+          <span>
+            {{statistics.currentMeanScore === null ? 'N.A.' : statistics.currentMeanScore.toFixed(2)}}
+          </span>
+        </li>
+      </ul>
+      <v-divider class="mx-2 my-2"></v-divider>
+      <div v-for="(progress, index) in statistics.submissionTypeProgress" :key="index">
+        <v-card-title class="py-0">
+          {{progress.name}}
+        </v-card-title>
+        <div class="mx-3">
+          <v-progress-linear
+            :value="progress.feedbackFinal / progress.submissionCount * 100"
+            buffer
+            :buffer-value="(progress.feedbackInValidation + progress.feedbackFinal) * 100 / progress.submissionCount"
+            :color="progress.feedbackFinal === progress.submissionCount ? 'green' : 'blue'"
+          />
         </div>
       </div>
-    </v-card>
+    </div>
+  </v-card>
 </template>
 
 <script>
diff --git a/frontend/src/components/LabelStatistics.vue b/frontend/src/components/LabelStatistics.vue
new file mode 100644
index 0000000000000000000000000000000000000000..d7c4a23205f3a4a77ac2feebb48499e2d7cc1250
--- /dev/null
+++ b/frontend/src/components/LabelStatistics.vue
@@ -0,0 +1,131 @@
+<template>
+  <v-card>
+    <v-card-title class="title">Accumulated Label Statistics</v-card-title>
+    <v-data-table
+      :headers=headers
+      :pagination="pagination"
+      :loading="loading"
+      :items="summedLabelCounts"
+    >
+      <template slot="items" slot-scope="props">
+        <td>{{ props.item[0] }}</td>
+        <td class="text-xs-center">{{ props.item[1] }}</td>
+      </template>
+    </v-data-table>
+
+    <div v-for="([subType, labelCounts]) in mappedLabelCounts" :key="subType">
+      <v-card-title class="title">
+        Statistics for: {{ subType }}
+      </v-card-title>
+      <v-data-table
+      :headers=headers
+      :pagination="pagination"
+      :loading="loading"
+      :items="labelCounts"
+    >
+      <template slot="items" slot-scope="props">
+        <td>{{ props.item[0] }}</td>
+        <td class="text-xs-center">{{ props.item[1] }}</td>
+      </template>
+    </v-data-table>
+
+    </div>
+  </v-card>
+</template>
+
+
+<script lang="ts">
+import Vue from 'vue'
+import Component from 'vue-class-component'
+import * as api from '@/api'
+import { LabelStatisticsForSubType } from '../models';
+import { getters } from '../store/getters';
+import { FeedbackLabels } from '../store/modules/feedback-labels';
+
+
+@Component
+export default class LabelStatistics extends Vue{
+  labelStatistics: LabelStatisticsForSubType[] = []
+  timer = 0
+
+  pagination = {
+    descending: true,
+    sortBy: '[1]',
+    rowsPerPage: -1
+  }
+
+  headers = [
+    {
+      text: 'Label',
+      align: 'left',
+      sortable: true,
+      value: '[0]'
+    },
+    {
+      text: 'Count',
+      align: 'center',
+      sortable: true,
+      value: '[1]'
+    }
+  ]
+
+  get loading(): boolean {
+    return this.labelStatistics.length == 0
+  }
+
+  get summedLabelCounts () {
+    const summedLabelCounts = this.labelStatistics
+    .reduce((acc: {[labelPk: string]: number}, curr) => {
+      Object.entries(curr)
+        .filter(([key, val]) => key !== 'pk')
+        .forEach(([labelPk, count]: [string, number]) => {
+          if (!acc[labelPk]) {
+            acc[labelPk] = 0
+          }
+          acc[labelPk] += count
+        })
+      return acc
+    }, {})
+    // TODO map label pks to names
+    const mappedLabelCounts = this.mapLabelList(Object
+      .entries(summedLabelCounts))
+    return mappedLabelCounts
+  }
+
+  get mappedLabelCounts () {
+    return this.labelStatistics.map(labelStatistics => {
+      const labelValues = Object
+        .entries(labelStatistics)
+        .filter(([key, val]) => key !== 'pk')
+      const subTypeName = getters.submissionType(labelStatistics.pk).name
+      return [subTypeName, this.mapLabelList(labelValues)]
+    })
+  }
+
+  mapLabelList (labelList: [string, number][]) {
+    return labelList.map(entry => {
+        const label = FeedbackLabels.state.labels.find(label => {
+          return String(label.pk) === entry[0]
+        })
+        const labelName = label ? label.name : 'Unknown label'
+        return [labelName, entry[1]]
+      })
+  }
+
+  async loadLabelStatistics () {
+    this.labelStatistics = await api.fetchLabelStatistics()
+  }
+
+  created () {
+    this.timer = setInterval(() => {
+      this.loadLabelStatistics()
+    }, 10 * 1e3)
+    this.loadLabelStatistics()
+  }
+
+  beforeDestroy () {
+    clearInterval(this.timer)
+  }
+
+}
+</script>
diff --git a/frontend/src/components/student_list/StudentList.vue b/frontend/src/components/student_list/StudentList.vue
index 3e7d1c055d5434aa28c3e4a312944fe59b58d2fb..7a119300874abf9d7f7e8164bfdd24e30f94076f 100644
--- a/frontend/src/components/student_list/StudentList.vue
+++ b/frontend/src/components/student_list/StudentList.vue
@@ -123,7 +123,7 @@ export default {
       search: '',
       pagination: {
         sortBy: 'name',
-        rowsPerPage: Infinity
+        rowsPerPage: -1
       },
       staticHeaders: [
         {
diff --git a/frontend/src/components/subscriptions/SubscriptionList.vue b/frontend/src/components/subscriptions/SubscriptionList.vue
index ebe70f12da4de1e0498dd2aad94922c0a1710bcc..07dc0daee503539481dde18330fb0271f0dfe738 100644
--- a/frontend/src/components/subscriptions/SubscriptionList.vue
+++ b/frontend/src/components/subscriptions/SubscriptionList.vue
@@ -70,12 +70,6 @@ export default class SubscriptionList extends Vue {
     return subscriptions
   }
 
-  mounted() {
-    this.timer = setInterval(() => {
-      this.getSubscriptions(true)
-    }, 30 * 1e3)
-  }
-
   beforeDestroy() {
     clearInterval(this.timer)
   }
@@ -83,6 +77,11 @@ export default class SubscriptionList extends Vue {
   created() {
     const submissionTypes = actions.updateSubmissionTypes()
     const subscriptions = Subscriptions.getSubscriptions()
+
+    this.timer = setInterval(() => {
+      this.getSubscriptions(true)
+    }, 30 * 1e3)
+
     Promise.all([submissionTypes, subscriptions]).then(() => {
       Subscriptions.subscribeToAll()
       Subscriptions.cleanAssignmentsFromSubscriptions(true)
diff --git a/frontend/src/models.ts b/frontend/src/models.ts
index 6186106764718d559b974315ffe6aaf09bcc0b8e..302089d313ff93ad633dc27f50a2c0572effc8a6 100644
--- a/frontend/src/models.ts
+++ b/frontend/src/models.ts
@@ -230,6 +230,13 @@ export interface Statistics {
     submissionTypeProgress: Array<SubmissionTypeProgress>
 }
 
+export interface LabelStatisticsForSubType {
+    /** Contains the count of the different labels under their pk */
+    [label_pk: number]: number,
+    /** The pk of the corresponding SubmissionType */
+    pk: string
+}
+
 /**
  *
  * @export
diff --git a/frontend/src/pages/Statistics.vue b/frontend/src/pages/Statistics.vue
new file mode 100644
index 0000000000000000000000000000000000000000..92a69ce16e905e971a9588935b5e298154c9bc0c
--- /dev/null
+++ b/frontend/src/pages/Statistics.vue
@@ -0,0 +1,29 @@
+<template>
+  <div>
+    <v-layout row class="ma-2">
+      <v-flex xs5>
+        <label-statistics/>
+      </v-flex>
+      <v-flex offset-xs1 xs5>
+        <correction-statistics/>
+      </v-flex>
+    </v-layout>
+  </div>
+</template>
+
+<script lang="ts">
+import Vue from 'vue'
+import Component from 'vue-class-component'
+
+import CorrectionStatistics from '@/components/CorrectionStatistics.vue'
+import LabelStatistics from '@/components/LabelStatistics.vue'
+
+
+@Component({
+  components: {CorrectionStatistics, LabelStatistics}
+})
+export default class Statistics extends Vue {
+
+
+}
+</script>
diff --git a/frontend/src/pages/base/TutorReviewerBaseLayout.vue b/frontend/src/pages/base/TutorReviewerBaseLayout.vue
index 5f4899ffab4b2f98314c7ac5cd69133ba446d5eb..68ceaf80e679c7250cf30cc5626a33db86668cc6 100644
--- a/frontend/src/pages/base/TutorReviewerBaseLayout.vue
+++ b/frontend/src/pages/base/TutorReviewerBaseLayout.vue
@@ -51,6 +51,11 @@ export default {
           name: 'Feedback History',
           icon: 'feedback',
           route: '/feedback'
+        },
+        {
+          name: 'Statistics',
+          icon: 'bar_chart',
+          route: 'statistics'
         }
       ]
     }
diff --git a/frontend/src/router/index.ts b/frontend/src/router/index.ts
index a93b5d8068c08f9d8b5b133d5444b25be6849c84..a7e8d4fbc18889e70be0307253194f5b0c4b69bf 100644
--- a/frontend/src/router/index.ts
+++ b/frontend/src/router/index.ts
@@ -8,6 +8,7 @@ import SubscriptionWorkPage from '@/pages/SubscriptionWorkPage.vue'
 import SubscriptionEnded from '@/components/subscriptions/SubscriptionEnded.vue'
 import PageNotFound from '@/pages/PageNotFound.vue'
 import StartPageSelector from '@/pages/StartPageSelector.vue'
+import Statistics from '@/pages/Statistics.vue'
 import LayoutSelector from '@/pages/LayoutSelector.vue'
 import StudentSubmissionSideView from '@/pages/StudentSubmissionSideView.vue'
 import StudentListHelpCard from '@/components/student_list/StudentListHelpCard.vue'
@@ -91,6 +92,11 @@ const router = new Router({
           name: 'subscription-ended',
           component: SubscriptionEnded
         },
+        {
+          path: 'statistics',
+          name: 'statistics',
+          component: Statistics
+        },
         {
           path: 'feedback',
           beforeEnter: tutorOrReviewerOnly,
diff --git a/frontend/yarn.lock b/frontend/yarn.lock
index dc391a2453ff7cb2e473d8c468e24f711190be98..57fa3fd913d56cd8c7421ca7bb8f3bd1cff2c17a 100644
--- a/frontend/yarn.lock
+++ b/frontend/yarn.lock
@@ -7772,11 +7772,6 @@ vue-style-loader@^4.1.0:
     hash-sum "^1.0.2"
     loader-utils "^1.0.2"
 
-vue-swatches@^1.0.3:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/vue-swatches/-/vue-swatches-1.0.3.tgz#84eb23ba99bbbb0d56698f3a8bdb1b340203d33b"
-  integrity sha512-3J+Nc3bisvhhp0BW0pfTbQvdl3i+dhwoPjoM+2D6R6hW65KNpXOA+sJwcSg2j1Xd6fLcOV7LMb2sz6s4vKSWRg==
-
 vue-template-compiler@^2.5.16:
   version "2.5.22"
   resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.5.22.tgz#c3d3c02c65f1908205c4fbd3b0ef579e51239955"