Search code examples
pythonlayertreemapaltairvega-lite

Using Altair, how do I create a rectangular color layer?


Trying to fill in the rectangles with color using a separate layer. -- Edited to add a dataframe and reduced the number of rectangles to 5.

DF = pd.DataFrame(np.array([['josh',20.255954921881653, 28.273276474768977, 237.57142857142856, 265.84470504619753,
   711.6681465038845, 731.9241014257661], ['mike',17.174311926605526,
   33.61525704809287,  496.37455579246625, 529.9898128405591,
   488.5828386400432, 505.7571505666487],['kim',12.381243550051579, 18.73049780659926, 445.47959183673464,
   464.2100896433339, 400.26581527347787, 412.64705882352945],['ryan', 16.54241139180131, 14.2627034936894,
   681.0628210823381, 695.3255245760275, 61.462339239101226, 78.00475063090254],['ben', 12.717713479181384,
   18.753142318287132, 663.3220247966516, 682.0751671149387, 430.64705882352945, 443.36477230271083]]),columns=['label', 'height', 'width', 'x','x2', 'y', 'y2'])
base = alt.Chart(DF,width=500,height=500)
    rects=base.mark_rect(fill='id',stroke='black').encode(
    x='x',
    y='y',
    x2='x2',
    y2='y2')
    
    marks = base.mark_area().encode(
    x='x:Q',
    y=alt.Y('y:Q'),#impute = {'value':None}),
    x2='x2:Q',
    y2='y2:Q',
    fill=alt.Color('label:N'))#,scale=None),)    

    return alt.layer(rects, marks)

enter image description here


Solution

  • You don't need separate layers to create filled rectangles:

    alt.Chart(DF).mark_rect(stroke='black').encode(
        x='x',
        y='y',
        x2='x2',
        y2='y2',
        color='label')
    

    enter image description here

    If you want two layers you could follow the below for the same result, but I don't see the advantage of this approach:

    bottom = alt.Chart(DF).mark_rect(stroke='black', strokeWidth=3, fillOpacity=0).encode(
        x='x',
        y='y',
        x2='x2',
        y2='y2')
    
    top = alt.Chart(DF).mark_rect().encode(
        x='x',
        y='y',
        x2='x2',
        y2='y2',
        color='label')
    
    bottom + top