title: Is there a way to force geom_tile heatmap cells to be a specific size when generating a grid of heatmaps (using facet_wrap)?
body: <p>In my Shiny data quality assessment application, users upload datasets and can generate reports using RMarkdown. One of those reports is a visual summary of the dataset, rating each variable of the dataset on three metrics: % Compliance (how well the data match the data model), % Logic (is death date after birth date?), and % Completeness. Each patient in the dataset belongs to a GROUP, and the metrics are reported by GROUP. Each dataset includes multiple data tables, and so a separate grid of heatmaps (on a separate page) is created for each data table. Some users have lots of GROUPs in their data, while others have only a few. Similarly, the number of variables in a table vary as well. </p>
  
  <p><strong>How can I standardize the look of these faceted heatmaps across these different circumstances?</strong> I am looking for a way to specify the height and width in cm for each heatmap cell, but haven't found a good solution. The two plots below illustrate the problem.<br>
  1. Faceted Heatmap with small number of patient groups in dataset (cells are too big!):
  <a href="https://i.stack.imgur.com/gDuQA.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/gDuQA.png" alt="Small number of groups resulting in huge cells"></a></p>
  
  <ol start="2">
  <li>Faceted Heatmap with large number of patient groups in dataset:
  <a href="https://i.stack.imgur.com/pEHS7.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/pEHS7.png" alt="Large number of groups and variables resulting in small cells"></a></li>
  </ol>
  
  <p>Using <code>coord_fixed()</code> doesn't correct the issue nor does <code>coord_equal()</code>. It still results in large cells for the first scenario and even tinier ones for the second.</p>
  
  <p>Below is a reproducible example to generate fake data and the resulting faceted heatmaps for a variety of numbers of variables and patient groups. (e.g., <code>makeWrappedHeatmaps(numGroups = 20, numVars = 5)</code> will create faceted set of 20 heatmaps summarizing metrics for 5 variables)</p>
  
  <pre><code>library(tidyverse)
  library(data.table)
  
  createFakeVariableMetrics &lt;- function(varName, numGroups){
    tibble(GROUP = paste("Group", LETTERS[1:numGroups]), 
           Variable = rep(varName, numGroups),
           Compliant = round(runif(numGroups, 20, 100), 0), 
           Logic = round(runif(numGroups, 0, 100), 0), 
           Complete = round(runif(numGroups, 25, 100), 0) 
           )
  }
  
  # example possible variable names
  variableNames &lt;- c("PATIENT", "BIRTH_D", "MED_CODE", "DROP_Y", "DX_D", "VIS_D", "DX_CODE", "RS_CODE", "LAB_V")
  
  makeWrappedHeatmaps &lt;- function(numGroups, numVars){
    if (numVars &gt; length(variableNames)) return("Specify a number of variables less than 10")
    varNames &lt;- variableNames[1:numVars]
    dfList &lt;- lapply(varNames, createFakeVariableMetrics, numGroups)
    metricdf &lt;- rbindlist(dfList)
    forHeatmap &lt;- gather(metricdf, c("Compliant", "Logic", "Complete"), key = "Metric", value = "percent")
  
    ggplot(data = forHeatmap, aes(x = Metric, y = Variable)) +
      geom_tile(aes(fill = percent), colour = "white", size = 0.01) +
      facet_wrap("GROUP") +
      labs(x="",y="") +
      geom_text(aes(label = percent), size = 3) +
      scale_y_discrete(expand=c(0,0))+
      scale_x_discrete(expand=c(0,0), position = "top") +
      theme(
        axis.text.x = element_text(size = 8),
        plot.background = element_blank(),
        axis.ticks.y = element_blank(),
        axis.ticks.x = element_blank(),
        panel.border = element_blank(),
        legend.position = "none")
  }
  </code></pre>
  
  <p>Thank you!</p>