diff --git a/horizon/templates/horizon/common/_limit_summary.html b/horizon/templates/horizon/common/_limit_summary.html
index 9cc96dea4d..494fbb998c 100644
--- a/horizon/templates/horizon/common/_limit_summary.html
+++ b/horizon/templates/horizon/common/_limit_summary.html
@@ -3,30 +3,33 @@
 {% spaceless %}
   <div class="quota-dynamic limit-summary">
     <h3 class="quota-heading">{% trans "Limit Summary" %}</h3>
-     {% for chart in charts %}
-       {% if forloop.first or forloop.counter0|divisibleby:6 %}
-         <div class="row">
-       {% endif %}
-        <div class="d3_quota_bar col-lg-2 col-md-4 col-sm-4 col-xs-6">
-          <div class="pie-chart-usage" data-used="{% quotapercent chart.used chart.quota %}"></div>
-          <div class="quota_title" title="{{ chart.name }}" data-toggle="tooltip"> {{ chart.name }}</div>
-          <div class="quota_subtitle">
-            {% if chart.quota|quotainf != '-1' %}
-              {% blocktrans trimmed with usedphrase=chart.text used=chart.used_display available=chart.quota_display %}
-                {{ usedphrase }} {{ used }} of {{ available }}
-              {% endblocktrans %}
-            {% else %}
-              {% blocktrans trimmed with usedphrase=chart.text used=chart.used_display %}
-                {{ usedphrase }} {{ used }} (No Limit)
-              {% endblocktrans %}
-            {% endif %}
+    {% for section in charts %}
+      <h4>{{ section.title }}</h4>
+      {% for chart in section.charts %}
+        {% if forloop.first or forloop.counter0|divisibleby:6 %}
+          <div class="row">
+        {% endif %}
+            <div class="d3_quota_bar col-lg-2 col-md-4 col-sm-4 col-xs-6">
+              <div class="pie-chart-usage" data-used="{% quotapercent chart.used chart.quota %}"></div>
+              <div class="quota_title" title="{{ chart.name }}" data-toggle="tooltip"> {{ chart.name }}</div>
+              <div class="quota_subtitle">
+                {% if chart.quota|quotainf != '-1' %}
+                  {% blocktrans trimmed with usedphrase=chart.text used=chart.used_display available=chart.quota_display %}
+                    {{ usedphrase }} {{ used }} of {{ available }}
+                  {% endblocktrans %}
+                {% else %}
+                  {% blocktrans trimmed with usedphrase=chart.text used=chart.used_display %}
+                    {{ usedphrase }} {{ used }} (No Limit)
+                  {% endblocktrans %}
+                {% endif %}
+              </div>
+            </div>
+        {% if forloop.last or forloop.counter|divisibleby:6 %}
+          {% if not forloop.first %}
           </div>
-        </div>
-       {% if forloop.last or forloop.counter|divisibleby:6 %}
-         {% if not forloop.first %}
-           </div>
-         {% endif %}
-       {% endif %}
-     {% endfor %}
+          {% endif %}
+        {% endif %}
+      {% endfor %}
+    {% endfor %}
   </div>
 {% endspaceless %}
diff --git a/openstack_dashboard/dashboards/project/overview/tests.py b/openstack_dashboard/dashboards/project/overview/tests.py
index 947b62c3c6..d01f136860 100644
--- a/openstack_dashboard/dashboards/project/overview/tests.py
+++ b/openstack_dashboard/dashboards/project/overview/tests.py
@@ -266,8 +266,40 @@ class UsageViewTests(test.TestCase):
         return res
 
     def test_usage_charts_created(self):
-        res = self._test_usage_charts()
+        res = self._test_usage_charts(
+            quota_usage_overrides={'floatingip': {'quota': -1, 'used': 1234}})
         self.assertIn('charts', res.context)
+        charts = res.context['charts']
+
+        self.assertEqual(['Compute', 'Volume', 'Network'],
+                         [c['title'] for c in charts])
+
+        compute_charts = [c for c in charts if c['title'] == 'Compute'][0]
+        chart_ram = [c for c in compute_charts['charts']
+                     if c['type'] == 'ram'][0]
+        # Check mb_float_format filter is applied
+        self.assertEqual(10000, chart_ram['quota'])
+        self.assertEqual('9.8GB', chart_ram['quota_display'])
+        self.assertEqual(0, chart_ram['used'])
+        self.assertEqual('0Bytes', chart_ram['used_display'])
+
+        volume_charts = [c for c in charts if c['title'] == 'Volume'][0]
+        chart_gigabytes = [c for c in volume_charts['charts']
+                           if c['type'] == 'gigabytes'][0]
+        # Check diskgbformat filter is applied
+        self.assertEqual(1000, chart_gigabytes['quota'])
+        self.assertEqual('1000GB', chart_gigabytes['quota_display'])
+        self.assertEqual(0, chart_gigabytes['used'])
+        self.assertEqual('0Bytes', chart_gigabytes['used_display'])
+
+        network_charts = [c for c in charts if c['title'] == 'Network'][0]
+        chart_fip = [c for c in network_charts['charts']
+                     if c['type'] == 'floatingip'][0]
+        # Check intcomma default filter is applied
+        self.assertEqual(float('inf'), chart_fip['quota'])
+        self.assertEqual(float('inf'), chart_fip['quota_display'])
+        self.assertEqual(1234, chart_fip['used'])
+        self.assertEqual('1,234', chart_fip['used_display'])
 
     def test_usage_charts_infinite_quota(self):
         res = self._test_usage_charts(
diff --git a/openstack_dashboard/usage/views.py b/openstack_dashboard/usage/views.py
index f010f606e0..5d1ea8f201 100644
--- a/openstack_dashboard/usage/views.py
+++ b/openstack_dashboard/usage/views.py
@@ -100,21 +100,37 @@ ChartDef = collections.namedtuple(
 #   If None is specified, the default filter 'intcomma' will be applied.
 #   if you want to apply no filters, specify an empty tuple or list.
 CHART_DEFS = [
-    ChartDef("instances", _("Instances"), None, None),
-    ChartDef("cores", _("VCPUs"), None, None),
-    ChartDef("ram", _("RAM"), None, (sizeformat.mb_float_format,)),
-    ChartDef("volumes", _("Volumes"), None, None),
-    ChartDef("snapshots", _("Volume Snapshots"), None, None),
-    ChartDef("gigabytes", _("Volume Storage"), None,
-             (sizeformat.diskgbformat,)),
-    ChartDef("floatingip", _("Floating IPs"),
-             pgettext_lazy('Label in the limit summary', "Allocated"),
-             None),
-    ChartDef("security_group", _("Security Groups"), None, None),
-    ChartDef("security_group_rule", _("Security Group Rules"), None, None),
-    ChartDef("network", _("Networks"), None, None),
-    ChartDef("port", _("Ports"), None, None),
-    ChartDef("router", _("Routers"), None, None),
+    {
+        'title': _("Compute"),
+        'charts': [
+            ChartDef("instances", _("Instances"), None, None),
+            ChartDef("cores", _("VCPUs"), None, None),
+            ChartDef("ram", _("RAM"), None, (sizeformat.mb_float_format,)),
+        ]
+    },
+    {
+        'title': _("Volume"),
+        'charts': [
+            ChartDef("volumes", _("Volumes"), None, None),
+            ChartDef("snapshots", _("Volume Snapshots"), None, None),
+            ChartDef("gigabytes", _("Volume Storage"), None,
+                     (sizeformat.diskgbformat,)),
+        ]
+    },
+    {
+        'title': _("Network"),
+        'charts': [
+            ChartDef("floatingip", _("Floating IPs"),
+                     pgettext_lazy('Label in the limit summary', "Allocated"),
+                     None),
+            ChartDef("security_group", _("Security Groups"), None, None),
+            ChartDef("security_group_rule", _("Security Group Rules"),
+                     None, None),
+            ChartDef("network", _("Networks"), None, None),
+            ChartDef("port", _("Ports"), None, None),
+            ChartDef("router", _("Routers"), None, None),
+        ]
+    },
 ]
 
 
@@ -129,8 +145,18 @@ def _apply_filters(value, filters):
 class ProjectUsageView(UsageView):
 
     def _get_charts_data(self):
+        chart_sections = []
+        for section in CHART_DEFS:
+            chart_data = self._process_chart_section(section['charts'])
+            chart_sections.append({
+                'title': section['title'],
+                'charts': chart_data
+            })
+        return chart_sections
+
+    def _process_chart_section(self, chart_defs):
         charts = []
-        for t in CHART_DEFS:
+        for t in chart_defs:
             if t.quota_key not in self.usage.limits:
                 continue
             key = t.quota_key
@@ -149,6 +175,8 @@ class ProjectUsageView(UsageView):
             quota_display = None
             if quota != float('inf'):
                 quota_display = _apply_filters(quota, filters)
+            else:
+                quota_display = quota
 
             charts.append({
                 'type': key,