Altair provides a number of hooks to configure the look of your chart; we don't have time to go into all the available options here, but it is useful to know where and how such configuration settings can be accessed and explored.
In general, there are two or three places where the look of a chart can be controlled, each with a greater priority than the last.
Top Level Chart Config. At the top level of an Altair chart, you can specify configuration settings that will apply to every panel or layer in the chart.
Local Configuration Settings. The top-level settings can be over-ridden locally, by specifying local configuration
Encoding Values. If an encoding value is specified, it will take highest precedance, and override the other options.
Let's see an example.
import altair as alt
import numpy as np
import pandas as pd
np.random.seed(42)
data = pd.DataFrame(np.random.randn(100, 2), columns=['x', 'y'])
Suppose you would like to control the color of the markers in a scatter plot: let's see each of the three options for doing this. We'll use a simple datasets of normally-distributed points:
alt.Chart(data).mark_point().encode(
x='x:Q',
y='y:Q'
)
At the top level, Altair has a configure_mark()
method that allows you to adjust a large number of configuration settings for marks in general, as well as a configure_point()
property that specifically adjusts the properties of points.
You can see the availale options in Jupyter in the documentation string, accessed with a question mark:
alt.Chart.configure_point?
Signature: alt.Chart.configure_point( self, align=Undefined, angle=Undefined, aspect=Undefined, baseline=Undefined, color=Undefined, cornerRadius=Undefined, cornerRadiusBottomLeft=Undefined, cornerRadiusBottomRight=Undefined, cornerRadiusTopLeft=Undefined, cornerRadiusTopRight=Undefined, cursor=Undefined, dir=Undefined, dx=Undefined, dy=Undefined, ellipsis=Undefined, fill=Undefined, fillOpacity=Undefined, filled=Undefined, font=Undefined, fontSize=Undefined, fontStyle=Undefined, fontWeight=Undefined, height=Undefined, href=Undefined, interpolate=Undefined, invalid=Undefined, limit=Undefined, lineBreak=Undefined, lineHeight=Undefined, opacity=Undefined, order=Undefined, orient=Undefined, radius=Undefined, shape=Undefined, size=Undefined, stroke=Undefined, strokeCap=Undefined, strokeDash=Undefined, strokeDashOffset=Undefined, strokeJoin=Undefined, strokeMiterLimit=Undefined, strokeOpacity=Undefined, strokeWidth=Undefined, tension=Undefined, text=Undefined, theta=Undefined, timeUnitBand=Undefined, timeUnitBandPosition=Undefined, tooltip=Undefined, width=Undefined, x=Undefined, x2=Undefined, y=Undefined, y2=Undefined, **kwds, ) Docstring: MarkConfig schema wrapper Mapping(required=[]) Attributes ---------- align : :class:`Align` The horizontal alignment of the text or ranged marks (area, bar, image, rect, rule). One of ``"left"``, ``"right"``, ``"center"``. angle : float The rotation angle of the text, in degrees. aspect : boolean Whether to keep aspect ratio of image marks. baseline : :class:`TextBaseline` The vertical alignment of the text or ranged marks (area, bar, image, rect, rule). One of ``"top"``, ``"middle"``, ``"bottom"``. **Default value:** ``"middle"`` color : anyOf(:class:`Color`, :class:`Gradient`) Default color. **Default value:** :raw-html:`<span style="color: #4682b4;">■</span>` ``"#4682b4"`` **Note:** * This property cannot be used in a `style config <https://vega.github.io/vega-lite/docs/mark.html#style-config>`__. * The ``fill`` and ``stroke`` properties have higher precedence than ``color`` and will override ``color``. cornerRadius : float The radius in pixels of rounded rectangle corners. **Default value:** ``0`` cornerRadiusBottomLeft : float The radius in pixels of rounded rectangle bottom left corner. **Default value:** ``0`` cornerRadiusBottomRight : float The radius in pixels of rounded rectangle bottom right corner. **Default value:** ``0`` cornerRadiusTopLeft : float The radius in pixels of rounded rectangle top right corner. **Default value:** ``0`` cornerRadiusTopRight : float The radius in pixels of rounded rectangle top left corner. **Default value:** ``0`` cursor : :class:`Cursor` The mouse cursor used over the mark. Any valid `CSS cursor type <https://developer.mozilla.org/en-US/docs/Web/CSS/cursor#Values>`__ can be used. dir : :class:`Dir` The direction of the text. One of ``"ltr"`` (left-to-right) or ``"rtl"`` (right-to-left). This property determines on which side is truncated in response to the limit parameter. **Default value:** ``"ltr"`` dx : float The horizontal offset, in pixels, between the text label and its anchor point. The offset is applied after rotation by the *angle* property. dy : float The vertical offset, in pixels, between the text label and its anchor point. The offset is applied after rotation by the *angle* property. ellipsis : string The ellipsis string for text truncated in response to the limit parameter. **Default value:** ``"…"`` fill : anyOf(:class:`Color`, :class:`Gradient`, None) Default Fill Color. This has higher precedence than ``config.color``. **Default value:** (None) fillOpacity : float The fill opacity (value between [0,1]). **Default value:** ``1`` filled : boolean Whether the mark's color should be used as fill color instead of stroke color. **Default value:** ``false`` for all ``point``, ``line``, and ``rule`` marks as well as ``geoshape`` marks for `graticule <https://vega.github.io/vega-lite/docs/data.html#graticule>`__ data sources; otherwise, ``true``. **Note:** This property cannot be used in a `style config <https://vega.github.io/vega-lite/docs/mark.html#style-config>`__. font : string The typeface to set the text in (e.g., ``"Helvetica Neue"`` ). fontSize : float The font size, in pixels. fontStyle : :class:`FontStyle` The font style (e.g., ``"italic"`` ). fontWeight : :class:`FontWeight` The font weight. This can be either a string (e.g ``"bold"``, ``"normal"`` ) or a number ( ``100``, ``200``, ``300``, ..., ``900`` where ``"normal"`` = ``400`` and ``"bold"`` = ``700`` ). height : float Height of the marks. href : string A URL to load upon mouse click. If defined, the mark acts as a hyperlink. interpolate : :class:`Interpolate` The line interpolation method to use for line and area marks. One of the following: * ``"linear"`` : piecewise linear segments, as in a polyline. * ``"linear-closed"`` : close the linear segments to form a polygon. * ``"step"`` : alternate between horizontal and vertical segments, as in a step function. * ``"step-before"`` : alternate between vertical and horizontal segments, as in a step function. * ``"step-after"`` : alternate between horizontal and vertical segments, as in a step function. * ``"basis"`` : a B-spline, with control point duplication on the ends. * ``"basis-open"`` : an open B-spline; may not intersect the start or end. * ``"basis-closed"`` : a closed B-spline, as in a loop. * ``"cardinal"`` : a Cardinal spline, with control point duplication on the ends. * ``"cardinal-open"`` : an open Cardinal spline; may not intersect the start or end, but will intersect other control points. * ``"cardinal-closed"`` : a closed Cardinal spline, as in a loop. * ``"bundle"`` : equivalent to basis, except the tension parameter is used to straighten the spline. * ``"monotone"`` : cubic interpolation that preserves monotonicity in y. invalid : enum('filter', None) Defines how Vega-Lite should handle marks for invalid values ( ``null`` and ``NaN`` ). * If set to ``"filter"`` (default), all data items with null values will be skipped (for line, trail, and area marks) or filtered (for other marks). * If ``null``, all data items are included. In this case, invalid values will be interpreted as zeroes. limit : float The maximum length of the text mark in pixels. The text value will be automatically truncated if the rendered size exceeds the limit. **Default value:** ``0``, indicating no limit lineBreak : string A delimiter, such as a newline character, upon which to break text strings into multiple lines. This property will be ignored if the text property is array-valued. lineHeight : float The height, in pixels, of each line of text in a multi-line text mark. opacity : float The overall opacity (value between [0,1]). **Default value:** ``0.7`` for non-aggregate plots with ``point``, ``tick``, ``circle``, or ``square`` marks or layered ``bar`` charts and ``1`` otherwise. order : anyOf(None, boolean) For line and trail marks, this ``order`` property can be set to ``null`` or ``false`` to make the lines use the original order in the data sources. orient : :class:`Orientation` The orientation of a non-stacked bar, tick, area, and line charts. The value is either horizontal (default) or vertical. * For bar, rule and tick, this determines whether the size of the bar and tick should be applied to x or y dimension. * For area, this property determines the orient property of the Vega output. * For line and trail marks, this property determines the sort order of the points in the line if ``config.sortLineBy`` is not specified. For stacked charts, this is always determined by the orientation of the stack; therefore explicitly specified value will be ignored. radius : float Polar coordinate radial offset, in pixels, of the text label from the origin determined by the ``x`` and ``y`` properties. shape : string Shape of the point marks. Supported values include: * plotting shapes: ``"circle"``, ``"square"``, ``"cross"``, ``"diamond"``, ``"triangle-up"``, ``"triangle-down"``, ``"triangle-right"``, or ``"triangle-left"``. * the line symbol ``"stroke"`` * centered directional shapes ``"arrow"``, ``"wedge"``, or ``"triangle"`` * a custom `SVG path string <https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths>`__ (For correct sizing, custom shape paths should be defined within a square bounding box with coordinates ranging from -1 to 1 along both the x and y dimensions.) **Default value:** ``"circle"`` size : float Default size for marks. * For ``point`` / ``circle`` / ``square``, this represents the pixel area of the marks. For example: in the case of circles, the radius is determined in part by the square root of the size value. * For ``bar``, this represents the band size of the bar, in pixels. * For ``text``, this represents the font size, in pixels. **Default value:** * ``30`` for point, circle, square marks; width/height's ``step`` * ``2`` for bar marks with discrete dimensions; * ``5`` for bar marks with continuous dimensions; * ``11`` for text marks. stroke : anyOf(:class:`Color`, :class:`Gradient`, None) Default Stroke Color. This has higher precedence than ``config.color``. **Default value:** (None) strokeCap : :class:`StrokeCap` The stroke cap for line ending style. One of ``"butt"``, ``"round"``, or ``"square"``. **Default value:** ``"square"`` strokeDash : List(float) An array of alternating stroke, space lengths for creating dashed or dotted lines. strokeDashOffset : float The offset (in pixels) into which to begin drawing with the stroke dash array. strokeJoin : :class:`StrokeJoin` The stroke line join method. One of ``"miter"``, ``"round"`` or ``"bevel"``. **Default value:** ``"miter"`` strokeMiterLimit : float The miter limit at which to bevel a line join. strokeOpacity : float The stroke opacity (value between [0,1]). **Default value:** ``1`` strokeWidth : float The stroke width, in pixels. tension : float Depending on the interpolation type, sets the tension parameter (for line and area marks). text : :class:`Text` Placeholder text if the ``text`` channel is not specified theta : float Polar coordinate angle, in radians, of the text label from the origin determined by the ``x`` and ``y`` properties. Values for ``theta`` follow the same convention of ``arc`` mark ``startAngle`` and ``endAngle`` properties: angles are measured in radians, with ``0`` indicating "north". timeUnitBand : float Default relative band size for a time unit. If set to ``1``, the bandwidth of the marks will be equal to the time unit band step. If set to ``0.5``, bandwidth of the marks will be half of the time unit band step. timeUnitBandPosition : float Default relative band position for a time unit. If set to ``0``, the marks will be positioned at the beginning of the time unit band step. If set to ``0.5``, the marks will be positioned in the middle of the time unit band step. tooltip : anyOf(:class:`Value`, :class:`TooltipContent`, None) The tooltip text string to show upon mouse hover or an object defining which fields should the tooltip be derived from. * If ``tooltip`` is ``true`` or ``{"content": "encoding"}``, then all fields from ``encoding`` will be used. * If ``tooltip`` is ``{"content": "data"}``, then all fields that appear in the highlighted data point will be used. * If set to ``null`` or ``false``, then no tooltip will be used. See the `tooltip <https://vega.github.io/vega-lite/docs/tooltip.html>`__ documentation for a detailed discussion about tooltip in Vega-Lite. **Default value:** ``null`` width : float Width of the marks. x : anyOf(float, enum('width')) X coordinates of the marks, or width of horizontal ``"bar"`` and ``"area"`` without specified ``x2`` or ``width``. The ``value`` of this channel can be a number or a string ``"width"`` for the width of the plot. x2 : anyOf(float, enum('width')) X2 coordinates for ranged ``"area"``, ``"bar"``, ``"rect"``, and ``"rule"``. The ``value`` of this channel can be a number or a string ``"width"`` for the width of the plot. y : anyOf(float, enum('height')) Y coordinates of the marks, or height of vertical ``"bar"`` and ``"area"`` without specified ``y2`` or ``height``. The ``value`` of this channel can be a number or a string ``"height"`` for the height of the plot. y2 : anyOf(float, enum('height')) Y2 coordinates for ranged ``"area"``, ``"bar"``, ``"rect"``, and ``"rule"``. The ``value`` of this channel can be a number or a string ``"height"`` for the height of the plot. File: ~/miniconda3/lib/python3.7/site-packages/altair/vegalite/v4/schema/core.py Type: function
This top-level configuration should be thought of as a chart theme: they are the default settings for the aesthetics of all chart elements.
Let's use configure_point
to set some properties of points:
alt.Chart(data).mark_point().encode(
x='x:Q',
y='y:Q'
).configure_point(
size=200,
color='red',
filled=True
)
Many local configurations are available; you can use Jupyter's tab-completion and help features to explore them
alt.Chart.configure_ # then the TAB key to see available configurations
Within the mark_point()
method, you can pass local configurations that will override the top-level configuration settings.
The arguments are the same as that of configure_mark
.
alt.Chart(data).mark_point(color='green', filled=False).encode(
x='x:Q',
y='y:Q'
).configure_point(
size=200,
color='red',
filled=True
)
Notice here that the "color" and "fill" configurations are overridden by the local configurations, but the "size" remains the same as before.
Finally, the highest precedence setting is the "encoding" setting. Here let's set the color to "steelblue" within the encoding:
alt.Chart(data).mark_point(color='green', filled=False).encode(
x='x:Q',
y='y:Q',
color=alt.value('steelblue')
).configure_point(
size=200,
color='red',
filled=True
)
Now this is a bit of a contrived example, but it's useful to help grasp the various places that properties of marks can be set.
Chart and axis titles are set automatically based on the data source, but sometimes it is useful to change them. For example, here is a histogram of the above data:
alt.Chart(data).mark_bar().encode(
x=alt.X('x', bin=True),
y=alt.Y('count()')
)
We can explicitly set the axis titles using the title
argument to the encoding:
alt.Chart(data).mark_bar().encode(
x=alt.X('x', bin=True, title='binned x values'),
y=alt.Y('count()', title='counts in x')
)
Likewise, we can set the title
property of the chart within the chart properties:
alt.Chart(data).mark_bar().encode(
x=alt.X('x', bin=True, title='binned x values'),
y=alt.Y('count()', title='counts in x')
).properties(
title='A histogram'
)
If you would like to set the properties of the axes, including grid lines, you can use the encodings'axis
argument.
alt.Chart(data).mark_bar().encode(
x=alt.X('x', bin=True, axis=alt.Axis(labelAngle=45)),
y=alt.Y('count()', axis=alt.Axis(labels=False, ticks=False, title=None))
)
Note that some of these values can be adjusted at the top-level configuration as well, if you want them to apply to the chart as a whole. For example:
alt.Chart(data).mark_bar().encode(
x=alt.X('x', bin=True),
y=alt.Y('count()', axis=alt.Axis(labels=False, ticks=False, title=None))
).configure_axisX(
labelAngle=45
)
Each encoding also has a scale
that allows you to adjust things like axis limits and other scale properties.
alt.Chart(data).mark_point().encode(
x=alt.X('x:Q', scale=alt.Scale(domain=[-5, 5])),
y=alt.Y('y:Q', scale=alt.Scale(domain=[-5, 5])),
)
Note that if you shrink the scale to smaller than the range of the data, the data will extend beyond the scale by default:
alt.Chart(data).mark_point().encode(
x=alt.X('x:Q', scale=alt.Scale(domain=[-3, 1])),
y=alt.Y('y:Q', scale=alt.Scale(domain=[-3, 1])),
)
Not hiding data is a useful default in exploratory visualization, because it prevents you from inadvertently missing data points.
If you would like the markers to be clipped beyond the range of the scales, you can set the clip
property of marks:
alt.Chart(data).mark_point(clip=True).encode(
x=alt.X('x:Q', scale=alt.Scale(domain=[-3, 1])),
y=alt.Y('y:Q', scale=alt.Scale(domain=[-3, 1])),
)
Another useful approach is to instead "clamp" the data to the extremes of the scale, keeping it visible even when it is out of range:
alt.Chart(data).mark_point().encode(
x=alt.X('x:Q', scale=alt.Scale(domain=[-3, 1], clamp=True)),
y=alt.Y('y:Q', scale=alt.Scale(domain=[-3, 1], clamp=True)),
).interactive()
Sometimes it's useful to manually adjust a color scale used
from vega_datasets import data
weather = data.seattle_weather()
weather.head()
date | precipitation | temp_max | temp_min | wind | weather | |
---|---|---|---|---|---|---|
0 | 2012-01-01 | 0.0 | 12.8 | 5.0 | 4.7 | drizzle |
1 | 2012-01-02 | 10.9 | 10.6 | 2.8 | 4.5 | rain |
2 | 2012-01-03 | 0.8 | 11.7 | 7.2 | 2.3 | rain |
3 | 2012-01-04 | 20.3 | 12.2 | 5.6 | 4.7 | rain |
4 | 2012-01-05 | 1.3 | 8.9 | 2.8 | 6.1 | rain |
alt.Chart(weather).mark_point().encode(
x='date:T',
y='temp_max:Q',
color='weather:N'
)
You can change the color scheme by using the color scale property, and by referencing any of Vega's named color schemes:
alt.Chart(weather).mark_point().encode(
x='date:T',
y='temp_max:Q',
color=alt.Color('weather:N', scale=alt.Scale(scheme="dark2"))
)
Alternatively, you can create your own color scheme by specifying a color domain and range:
colorscale = alt.Scale(domain=['sun', 'fog', 'drizzle', 'rain', 'snow'],
range=['goldenrod', 'gray', 'lightblue', 'steelblue', 'midnightblue'])
alt.Chart(weather).mark_point().encode(
x='date:T',
y='temp_max:Q',
color=alt.Color('weather:N', scale=colorscale)
)
Take about 10 minutes now and practice adjusting the aesthetics of your plots.
Use your favorite visualization from the previous exercise, and adjust the aesthetics of the plot:
Use tab-completion on alt.Chart.configure_
to see the various configuration options, then use ?
to see the documentation on what the options do.