Murtaza Ali
Murtaza Ali

Reputation: 152

Is there a way to customize the placement of concatenated charts in Altair?

I have the following chart in Altair, and I was wondering if there is a way to change the orientation of the map chart. I have tried using the "center" and "spacing" parameters, but to no avail. I want the map to appear under the legend to make the overall chart more concise.

enter image description here

This is the code used to generate the charts:

background = alt.Chart(states).mark_geoshape(
        fill='white',
        stroke='lightgray'
    ).properties(
        width=200,
        height=200
    ).project('albersUsa')

# Generate the points themselves
climate_points = alt.Chart(climate_with_temps).mark_circle(size=300).encode(
    alt.Longitude('lon:Q'),
    alt.Latitude('lat:Q'),
    alt.OpacityValue(0.25),
    alt.Color('city:N', scale=alt.Scale(scheme='dark2'), legend=None)
).properties(
    title=alt.TitleParams(
        ['Location of Coastal Cities'],
        baseline='bottom',
        orient='bottom',
        fontSize=15   
    )
)

map_chart = background + climate_points

temp_line_plot = alt.Chart(climate_with_temps).mark_line().encode(
    alt.X('month:O', axis=alt.Axis(title="Month"), sort=list(set(climate_with_temps.city))),
    alt.Y('avg_temp:Q', axis=alt.Axis(title="Average Temperature in Fahrenheit"), scale=alt.Scale(domain=[30, 95])),
    alt.Color('city:N'),
    alt.OpacityValue(1)
).properties(
    height=500,
    width=700
)

sun_square_plot = alt.Chart(climate_with_temps).mark_square().encode(
    alt.X('month:O', axis=alt.Axis(title="Month"), sort=list(set(climate_with_temps.city))),
    alt.Y('avg_temp:Q', axis=alt.Axis(title="Average Temperature in Fahrenheit"), scale=alt.Scale(domain=[30, 95])),
    alt.Color('city:N', scale=alt.Scale(scheme='dark2'), legend=alt.Legend(title='City')),
    alt.Size('sun_bin:O', sort=['0 - 50', '50 - 99', '100 - 149', '150 - 199', '200 - 249', '250 - 299', '300 - 350'], legend=alt.Legend(title='Average Hours of Sunshine')),
    alt.OpacityValue(1)
).properties(
    height=500,
    width=700
)

left_chart = sun_square_plot + temp_line_plot
final = alt.hconcat(left_chart, map_chart, center=False, spacing=0)

Upvotes: 1

Views: 1115

Answers (1)

joelostblom
joelostblom

Reputation: 48929

I don't think there is a straightforward to achieve this, although you could do something like this:

import altair as alt
from vega_datasets import data

source = data.cars()

chart1 = alt.Chart(source, height=400).mark_circle(size=60).encode(
    x='Horsepower',
    y='Miles_per_Gallon',
    color='Origin',
    size='Cylinders'
)
chart2 = alt.Chart(source, height=200, width=200).mark_circle(size=60).encode(
    x='Horsepower',
    y='Miles_per_Gallon',
    color='Origin',
)

# Empty chart for spacing
chart3 = alt.Chart(height=180, width=180).mark_circle(opacity=0)

(chart1 | (chart3 & chart2)).configure_legend(
    orient='right',
    direction='vertical',
    offset=-220,
    symbolDirection='vertical'
)

enter image description here

But the simplest might be to create a horizontal legend above both charts instead:

import altair as alt
from vega_datasets import data

source = data.cars()

chart1 = alt.Chart(source).mark_circle(size=60).encode(
    x='Horsepower',
    y='Miles_per_Gallon',
    color='Origin',
    size='Cylinders'
)

chart2 = alt.Chart(source).mark_circle(size=60).encode(
    x='Horsepower',
    y='Miles_per_Gallon',
    color='Origin'
)

(chart1 | chart2).configure_legend(
    orient='top'
)

enter image description here

Upvotes: 1

Related Questions