Search code examples
altair

color and size variation for single line - Altair


I'm trying to change color and size of a line, basing on attributes variations. I tried with trail because it's the only example i found in the doc.
My test:

datas = pd.DataFrame({'num': range(10),
                      'value': [5, 5, 10, 10, 3, 3, 9, 9, 7, 7],
                      'size': [0.5, 0.5, 1, 1, 0.3, 0.3, 0.9, 0.9, 0.7, 0.7],
                      'otherMarker': ['foo']*2 + ['bar']*2 + ['foo']*2 + ['bar']*2 + ['egg']*2}
alt.Chart(datas).mark_trail.encode(
    x='num',
    y='value',
    size='size:Q',
    color='otherMarker:N')

gives me
enter image description here
instead i'd like
enter image description here
.
How can i achieve this ?


Solution

  • Using impute=alt.ImputeParams(value=None) will help you avoid that joining. You can also look at the detail parameter for this.

    plt =alt.Chart(datas).mark_trail().encode(
        x='num',
        y=alt.Y('value', 
                impute=alt.ImputeParams(value=None)
            ),
        size='size:Q',
        color='otherMarker:N'
    )
    plt
    

    enter image description here

    A brute force approach to join the lines like the one shown in your image will be

    # generate a dataframe for the lines connecting different 'otherMarker' types
    def get_joining_lines(df):
        ids = datas[(datas['otherMarker']!=datas['otherMarker'].shift(-1))].index.to_list()[0:-1] # remove the last index
        ar = []
        for i in ids:
            temp = datas.loc[[i, i+1]] #adjacent indexes where the change happens
            temp['otherMarker'] = datas.loc[i]['otherMarker'] # change the tag of the last tag to be equal the previous
            ar.append(temp)
        df_temp = pd.concat(ar)
        return(df_temp)
    
    df_temp = get_joining_lines(datas)
    edge = alt.Chart(df_temp).mark_trail().encode(
        x='num',
        y=alt.Y('value', impute=alt.ImputeParams(value=None)),
        color='otherMarker:N'
    )
    edge
    

    enter image description here

    The color mapping is different from the initial plot, but this will get resolved when you combine them. If you want, you can hard code the color mapping using range and domain in the scale argument while defining color.

    Finally, you can layer these two together to get

    edge+ plt
    

    enter image description here