Search code examples
pythonaltair

How can I make one chart "span" the height / width of multiple charts in concatenated plots?


In the following example, I'd like to have exp fill the entire width of the plot (so, as wide as sin and cos combined). By default, exp fills only one column.

How can I do this, ideally using some "auto" setting (without explicitly setting a width= to a number)?

import altair as alt
import numpy as np
import pandas as pd

x = np.linspace(0, 20, 100)
source = pd.DataFrame({
  'x': x,
  'sin': np.sin(x),
  'cos': np.cos(x),
  'exp': np.exp(x),
})

base = alt.Chart(source).mark_line().encode(x='x')
sin = base.encode(y='sin')
cos = base.encode(y='cos')
exp = base.encode(y='exp')
(sin | cos) & exp

enter image description here


Solution

  • As far as I am aware, there is no way of automatically specifying the size of a chart to fill the entire layout of multiple concatenated charts (but if you find one it could help solve part of https://github.com/vega/vega-lite/issues/7194).

    If you want to avoid manually estimating a number, you could compute the the height programatically by accessing the height of each chart object and adding 60 pixels for each level of concatenation (I include a breakdown of where most of these 60 pixels come from in the code below). This is naturally not as convenient as an "auto" value, but maybe it is at least somewhat helpful.

    Unfortunately this is not as straightforward for the width, since this depends on the number of digits in the y-axis of all charts in the top row of concatenation (except the left most chart, which expands the ticklabels into the padding space to the left without increasing the overall width of the figure).

    height = (
        sin.to_dict()['config']['view']['continuousHeight']  # 300
        + exp.to_dict()['config']['view']['continuousHeight']  # 300
        + 5  # The default bottom padding of chart top-left chart
        + 5  # The default top padding of the bottom-left chart
        + 11  # The default x-axis labels font size (+padding?) of the top-left chart
        + 15  # The default x-axis title font size (+padding?) of the top-left chart
        + 20  # The default spacing between concatenated charts
        + 3  # Not sure where these are from
    )
    
    # Notice that the concatenation ordering is different to avoid empty space under the `sin` plot
    (sin & exp) | cos.properties(height=height)
    

    enter image description here