Tracking multiple tags or categories

You can follow different approaches, I will show you a simple one, that hooks into wp_footer action. The lack of this approach is that it slows down the page loading.
To avoid this lack you can use the same logic but implemented via ajax.

So, you can use an option to store category popularity, it will be stored as array where keys are category ids and values are numeric values: bigger this value, bigger popularity.

Please note that all following code is not tested.

First of all use wp_footer to ‘launch’ the count

add_action('wp_footer', 'count_category_popularity');

and related function:

function count_category_popularity() {
  if ( is_single() ) {
    global $post;
    update_category_popularity( get_the_terms( $post->ID, 'category' ) );
  } elseif ( is_category() )  {
    // 3 is the multiplier
    update_category_popularity( get_queried_object(), 3 );
  }
}

As you can see, the function above call another function update_category_popularity passing all the categories of a single post or the category itself if in the taxonomy archive. In this case second param is passed to function, it is a “multiplier” because I think that if an user require a category archive this must contribute more to the category popularity than viewing an article in that category. This is my opinion, you can delete that param if you want.

Now, the update_category_popularity function will be something like this:

function update_category_popularity ( $cat = NULL, $count = 1 ) {
  if ( empty($cat) )  return;
  $old = get_option('cat_popularity');
  if ( empty ($old) ) $old = array();
  $new = $old;
  if ( is_array($cat) && ! empty($cat) ) {
    foreach( $cat as $term ) {
    $new[$term->term_id] = ( isset($old[$term->term_id]) ) ? (int)$old[$term->term_id] + $count : $count;
    }
 } elseif( is_object ($cat) )  {
    $new[$cat->term_id] = ( isset($old[$cat->term_id]) ) ? (int)$old[$cat->term_id]+$count : $count;
 }
 if ( $old != $new ) update_option('cat_popularity', $new);
}

The function sets the option ‘cat_popularity’ and you can use it to handle category popularity.

Do you want to know a category popularity? Do:

$pop = get_option('cat_popularity');
$cat_popularity = $pop[$cat_id];

Do you want all categories ordered by popularity? Do:

$pop = get_option('cat_popularity');
// this will sort in reverse order (high to low), for low to high ordering use asort()
arsort($pop);
foreach ( $pop as $cat_id => $popularity ) {
  echo '<li>Category ' . $cat_id . ' popularity is' . $popularity . '</li>';
}

Probably is useful for you having a function that return popularity in percentual values instead of absolute ones: if you retrieve that a category popularity is 125, this value stands for high or low popularity?

Using function below you will retrieve popularity of categories in percentual values, help you easy understanding how a category is more or less popular compared with the others, even if you have a single value:

function get_categories_perc_popularity() {
   $pop = get_option('cat_popularity');
   arsort($pop);
   $total = array_sum( arry_map('intval', $pop) );
   $out = array();
   foreach ( $pop as $catid => $popularity ) {
     $out[$catid] = ( 100 * $popularity ) / $total;
   }
   return $out;
}

Now you can use:

$pop = (array) get_categories_perc_popularity();
if ( ! isset($pop[32]) ) $pop[32] = '0';
echo 'Category 32 popularity is ' . $pop[32] . '%';