2

I tried creating the chart however it ends up showing two charts side-by-side. How do I get a single chart instead like the one shown in altair grouped bar chart example.

df = pd.DataFrame({
    'strike': [200,225,250,275,300,325,350,200,225,250,275,300,325,350],
    'opttype': ['ce','ce','ce','ce','ce','ce','ce','pe','pe','pe','pe','pe','pe','pe' ],
    'oi': [100,150,500,800,450,200,77,50,500,210,300,150,60,17]
    
})
c = alt.Chart(df).mark_bar().encode(
    x='strike:N',
    y='oi:Q',
    color='opttype:N',
    column='opttype:N'
)

Output output

I tried adding axis as specified in this link, however I could not get the combined graph. May be I am missing something here.

Also I wonder how the official documentation example works correcly without the "axis" as well.

Neo
  • 4,640
  • 5
  • 39
  • 53

2 Answers2

1

The current best way to do this is to switch your x and column encodings, then make the width of each panel narrower:

c = alt.Chart(df).mark_bar().encode(
    x='opttype:N',
    y='oi:Q',
    color='opttype:N',
    column='strike:N'
).properties(width=50)

enter image description here

Then, if you wish, you can adjust axis & heading labels as in the linked examples. For example, you can move the header labels to the bottom like this:

c = alt.Chart(df).mark_bar().encode(
    x=alt.X('opttype:N', axis=None),
    y='oi:Q',
    color='opttype:N',
    column=alt.Column('strike:N', header=alt.Header(orient='bottom'))
).properties(width=50)

enter image description here

This is admittedly an imperfect solution. Vega-Lite is in the process of adding an offset encoding that will make this possible without having to use multiple column facets, but that is not available yet.

jakevdp
  • 77,104
  • 11
  • 125
  • 160
  • Thanks @jakevdp, this works. The offset would make this nicer. I'll play around to remove the labels (ce/pe) at the bottom. Also wondering if there is a way to get the Strike values at the bottom instead of the current position (at the top). My mind is trained to view the values at the bottom for X-axis. – Neo Nov 18 '21 at 18:47
  • Yes, the answer you linked to in your question shows how to move the heading labels to the bottom. – jakevdp Nov 18 '21 at 21:35
  • The example linked uses **"axis="** on the Column type which I do not see supported in the [latest docs](https://altair-viz.github.io/user_guide/generated/channels/altair.Column.html). The "spacing" option helped reduce the gap between the bars. – Neo Nov 19 '21 at 00:28
  • 1
    OK, see my edited answer – jakevdp Nov 19 '21 at 01:33
1

The x-axis and color variable should be the same:

df = pd.DataFrame({
    'strike': [200,225,250,275,300,325,350,200,225,250,275,300,325,350],
    'opttype': ['ce','ce','ce','ce','ce','ce','ce','pe','pe','pe','pe','pe','pe','pe' ],
    'oi': [100,150,500,800,450,200,77,50,500,210,300,150,60,17]
})

alt.Chart(df).mark_bar().encode(
    x='opttype:N',
    y='oi:Q',
    color='opttype:N',
    column='strike:N'
)

enter image description here

joelostblom
  • 43,590
  • 17
  • 150
  • 159
  • thanks @joelosblom for your answer. I just chose the previous as the accepted answer as that came in a few seconds earlier. – Neo Nov 18 '21 at 18:49