Splitting the main query in multiple loops with query_posts and/or pre_get_posts?

Don’t use query_posts(). Don’t modify the main loop query from within the template.

You may be able to get a single query to provide what you need (e.g. by filtering pre_get_posts and groupby), but more than likely, you will need to iterate 12 custom loops using WP_Query(). Perhaps something like this:

// Get all the months
$months = get_terms( $calendar );

// Set up the base query args
$events_query_args = array(
    'post_type' => 'events',
    'post_per_page' => 10,
    'tax_query' => array(
        array(
            'taxonomy' => 'calendar',
            'field' => 'slug',
            'terms' => ''
        )
    )
);

// Loop through the months, and
// output a custom query and loop
// for each
foreach ( $months as $month ) {

    // Add $month to the query args
    $events_query_args['tax_query']['terms'] = $month['slug'];

    // Build the query
    $events_query = new WP_Query( $events_query_args );

    // Open the query loop
    if ( $events_query->have_posts() ) : while ( $events_query->have_posts() ) : $events_query->the_post();

        // YOUR LOOP CODE GOES HERE

    // Close the loop
    endwhile; endif;

    // Clean up
    $events_query = null;
    wp_reset_postdata()
}

You’ll have to add the actual Loop output markup, of course.