Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I add a layer in a shape of a box to an altair plot?

I am trying to add a box to be used as strikezone using a pandas dataframe with coordinates and pass it to altair.

box = pd.DataFrame()
box.loc[:,"x"] = [-0.5, 0.5, 0.5, -0.5]
box.loc[:,'y'] = [1.25, 1.25, 0.5, 0.5]

I have tried the following:

g = alt.Chart(box.loc[0:1,:]).mark_line().encode(
x = 'x',
y = 'y')

d = alt.Chart(box.loc[1:2,:]).mark_line().encode(
x = 'x',
y = 'y')

e = alt.Chart(box.loc[2:3,:]).mark_line().encode(
x = 'x',
y = 'y')

f = alt.Chart(box.loc[3:4,:]).mark_line().encode(
x = 'x',
y = 'y')

g + d + e + f

I would also like to know how to adjust the x and y axis so there is a bit of a margin around the box?

like image 973
Nicholas Marey Avatar asked Mar 06 '19 03:03

Nicholas Marey


1 Answers

I would recommend drawing all four sides with a single line chart. You can then use the domain scale parameter to adjust the axis limits (see more in the Adjusting Axis Limits section of Altair's documentation).

Here is an example:

import altair as alt
import pandas as pd

box = pd.DataFrame({
    'x': [-0.5, 0.5, 0.5, -0.5, -0.5],
    'y': [1.25, 1.25, 0.5, 0.5, 1.25]
}).reset_index()


alt.Chart(box).mark_line().encode(
    alt.X('x', scale=alt.Scale(domain=(-1, 1))),
    alt.Y('y', scale=alt.Scale(domain=(0, 1.5))),
    order='index'
)

enter image description here

Alternatively, you can use a rect mark to avoid having to construct the rectangle's coordinates manually in the right order:

box = pd.DataFrame({'x1': [-0.5], 'x2': [0.5], 'y1': [0.5], 'y2': [1.25]})

alt.Chart(box).mark_rect(fill='none', stroke='black').encode(
    alt.X('x1', scale=alt.Scale(domain=(-1, 1))),
    alt.Y('y1', scale=alt.Scale(domain=(0, 1.5))),
    x2='x2',
    y2='y2'
)

enter image description here

like image 113
jakevdp Avatar answered Oct 26 '22 20:10

jakevdp