How to compare and rank Radar (Spider) Charts?

70 Views Asked by At

Say I have a bunch of radar charts, how do I compare them?

What I want to do is 'rank' a bunch of spider charts by their overall 'coverage'. Each chart is a Pentagonal spider chart.

My first guess was to compare areas, since that's what coverage is, but there isn't an easy formula to do that.

One I know of is $$ S = \frac{p \star r} 2 $$

where $ r $ is the radius of an inscribed circle and $ p $ is the perimeter of the pentagon.

The problem with this is you cannot really do (or at least I don't know how to do) that with raw data like this

1 0.1
2 0.98
3 0.53
4 0.01
5 0.6

where the first column is the 'vertex' of the chart and the second column is the point to draw on the chart. Points will always be between 0 and 1.

Something like this

enter image description here

So I was wondering, is there a better way of comparing spider/radar charts?

1

There are 1 best solutions below

0
On

Following script (should) calculates area of the coverage given points on lines from origin of circumcircle to vertices.

The idea is to calculate areas of each triangles in each quadrant and returning the summation.

This is not meant as a complete answer. Just as a 'helper' script.

#include <vector>
#include <numeric>
#include <iostream>
#include <tuple>
#include <cmath>

double area_of_a_triangle (double base, double height) {

  return (0.5 * base * height);

}

double area_of_spider_chart (std::vector<double> list_of_points) {

  double angle_of_triangles = (360 / list_of_points.size()) * 0.0174533;
  // angle between each sides in radians

  std::vector<std::tuple<double, double>> sides_pairs;
  // stores paris of two sides of each triangle in each quadrant of the spider chart.
  // angle between each sides would be equal to "angle_of_triangles"

  double areas = 0;
  // stores the areas of each triangle

  // -------------------------------------------------------------------------------------------

  // Following generates pairs of sides

  for (unsigned short i = 0; i < list_of_points.size() - 1; i++) {

    sides_pairs.push_back(std::make_tuple(list_of_points[i], list_of_points[i + 1]));

  }

  sides_pairs.push_back(std::make_tuple(list_of_points[list_of_points.size() - 1], list_of_points[0]));

  // Pairs generation complete

  // -------------------------------------------------------------------------------------------

  // Following calculates area of triangle from given pairs

  for (auto x : sides_pairs) {

    double base_of_triangle = 0;
    double smaller_side_of_triangle = 0;

    // making sure base is the longer one just to keep it clean
    if (std::get<0>(x) > std::get<1>(x)) {

      base_of_triangle = std::get<0>(x);
      smaller_side_of_triangle = std::get<1>(x);

      }
    else {

      base_of_triangle = std::get<1>(x);
      smaller_side_of_triangle = std::get<0>(x);
    }


    auto height_of_triangle = std::sin(angle_of_triangles) * smaller_side_of_triangle;

    areas += area_of_a_triangle(base_of_triangle, height_of_triangle);

  }

  // -------------------------------------------------------------------------------------------

  return areas;
  // returns area of the "coverage" in SpiderChart

}

int main () {

  std::vector<double> input = {1, 1, 1, 1, 1, 1};

  std::cout << area_of_spider_chart(input) << std::endl;

  // this returns area of hexagon with circumcircle radius of 1

}