Altair: line chart with different point marker?

Created on 10 Apr 2019  路  16Comments  路  Source: altair-viz/altair

How can I give different lines a different type of point marker, say a cross (+) symbol? For example, the following chart with point=True will have data points as solid circle, but it won't work well when print black & white.

import altair as alt
from vega_datasets import data

source = data.stocks()

alt.Chart(source).mark_line(point=True).encode(
    x='date',
    y='price',
    color='symbol'
)
question

Most helpful comment

You can get the result you want by carefully defining legends and scale resolution:

import altair as alt
from vega_datasets import data

source = data.stocks()

line = alt.Chart(source).mark_line().encode(
    x='date',
    y='price',
    color=alt.Color('symbol', legend=None)
)

points = line.mark_point(filled=True).encode(
    color='symbol',
    shape='symbol'
)

alt.layer(
    line,
    points
).resolve_scale(
    color='independent',
    shape='independent'
)

visualization (12)

All 16 comments

Hi there,

Perhaps you could add the shape encoding.

alt.Chart(source).mark_line().encode(
    x='date',
    y='price',
    color='symbol',
    shape=alt.Shape('symbol', scale=alt.Scale(range=['cross', 'circle', 'square', 'triangle-right', 'diamond']))
)

visualization (4)

It is exactly what I am hoping for. thanks.
The default symbol size does seem small, alt.Shape doesn't seem to have any option to set it though, is there anyway to change it?

Hi there,

Just as you can specify a shape encoding, you can also specify a size encoding. You can find the Altair encoding options here in the docs.

One way to have more control over the shapes, apart from the lines, is to use layers (docs here):

import altair as alt
from vega_datasets import data

source = data.stocks()

c=alt.Chart(source).encode(
    x='date',
    y='price',
    color='symbol'
)

l=c.mark_line()

p=c.mark_point(filled=True).encode(
    shape=alt.Shape('symbol', scale=alt.Scale(range=['cross', 'circle', 'square', 'triangle-right', 'diamond'])),
    size=alt.Size('symbol', scale=alt.Scale(range=[100,500],domain=['AAPL', 'AMZN', 'GOOG', 'IBM', 'MSFT']))
)

l+p

visualization (5)

Hi there,

Perhaps you could add the shape encoding.

alt.Chart(source).mark_line().encode(
    x='date',
    y='price',
    color='symbol',
    shape=alt.Shape('symbol', scale=alt.Scale(range=['cross', 'circle', 'square', 'triangle-right', 'diamond']))
)

visualization (4)

Is there a way to combine the two legends to include both the color and the shape in a single legend?

For point charts, this kind of legend combination is done automatically:

import altair as alt
from vega_datasets import data

source = data.stocks()

alt.Chart(source).mark_point(filled=True).encode(
    x='date',
    y='price',
    color='symbol',
    shape='symbol'
)

visualization (11)

The reason this doesn't happen for the line chart is because the color legend refers to the line itself.

Thanks Jake. I saw that for the point chart and thought I was mostly finished with a little excel chart replacement project. But, people will want the legend to look like the above, but also have the lines.

I'll have to see what else I can find.

@cmartin-cay

You might consider layering the points on top of the line chart.

I'll have to see what else I can find.

OK, best of luck. Sorry Altair didn't work for you.

Doing that brings me back to the initial situation where I have two separate legends. One with colors and one with shapes.

Maybe I can convince people that it's better this way :)

You can get the result you want by carefully defining legends and scale resolution:

import altair as alt
from vega_datasets import data

source = data.stocks()

line = alt.Chart(source).mark_line().encode(
    x='date',
    y='price',
    color=alt.Color('symbol', legend=None)
)

points = line.mark_point(filled=True).encode(
    color='symbol',
    shape='symbol'
)

alt.layer(
    line,
    points
).resolve_scale(
    color='independent',
    shape='independent'
)

visualization (12)

I knew there was a way!

All I can say is thank you very much.

Is there any way to set the size of the points on a mark_line chart with the 'shape' encoding without overlaying a mark_line and a mark_point chart?

Where can I find a menu of available shapes? (And thanks for the great thread!)

Where can I find a menu of available shapes? (And thanks for the great thread!)

Hi Janet. This link to the Vega-Lite docs on the "point" mark may help.

In Altair's docs, it's under shape here: https://altair-viz.github.io/user_guide/marks.html#mark-properties

Was this page helpful?
0 / 5 - 0 ratings

Related issues

SuperShinyEyes picture SuperShinyEyes  路  3Comments

tonylee3399 picture tonylee3399  路  3Comments

LukeMathWalker picture LukeMathWalker  路  3Comments

zanarmstrong picture zanarmstrong  路  4Comments

bmcfee picture bmcfee  路  3Comments