In the previous guide we talked about using different types of inputs for
ramp that were output to colors picked from a list. In this guide, you will see how
ramp supports the use of other types of outputs (like numbers and images) as well as CARTO VL’s fixed constant palettes of colors.
One way to output colors is to specify a list of colors, as demonstrated in Part 1 with expressions like
ramp($dn, [blue, red]). In those examples, you mainly saw the usage of named colors (
With CARTO VL any valid color expression (not just named colors) can be used:
ramp($dn, [rgb(200,220,222), rgba(200,120,22, 0.8)])
ramp($dn, [hsv(0,1,1), hsv(0.5,1,1)]
ramp($dn, [#00F, #F00])
ramp($dn, [blue, #F00])
ramp($dn, [opacity(blue, 0.4), opacity( #F00, 0.6)])
Another way to specify colors is to use built-in color schemes. CARTO VL, by default, supports the use of both CARTOColors and ColorBrewer schemes.
To access CARTOColors, replace the list of colors with the name of the scheme you want to use:
To access ColorBrewer, replace the list of colors with the name of the scheme you want to use appended with
You can find scheme names for CARTOColors here and for ColorBrewer here.
Use the map below, to switch between various color expressions and color schemes:
// Style 1: apply colors from a color list of named colors color: ramp($dn, [green, yellow, red]) // Style 2: apply colors from a color list including "transparent" color: ramp($dn, [transparent, gray, yellow]) // Style 3: apply colors from a color list with HSV color constructors color: ramp($dn, [hsv(0,1,1), hsv(0.5,1,1)]) // Style 4: apply color using the CARTOColor scheme "temps" color: ramp($dn, temps)
You can explore this map here
Proportional symbols (aka “bubble-maps”) are a method of symbolizing points using a numeric property. The symbol size of each point is scaled according to its value in the data.
Matching between numbers (the feature’s data) and other numbers (the point sizes) is a special case because basic math can create the required match without the need for the special function
ramp. However, using
ramp facilitates some advanced usages.
In the following sections you will see both approaches, and learn how to create proportional symbol maps like the ones below.
// Style 1: Sets a pixel width of 0 to accidents with the lowest damage amounts and 50 pixels to the highest damage amount width: ramp($total_damage, [0, 50]) // Style 2: The same as Style 1 for extreme values, but the interpolation is linear in area, not in width. An intermediate value with half the damage of the worst accident will get half the area of the worst (50²/2), but not half its width. Unless you want to accentuate differences, this is usually the proper way to make a bubble map width: sqrt(ramp($total_damage, [0, 50^2])) // Style 3: The same as Style 2 since the dataset has accidents with zero damage width: sqrt($total_damage/globalMax($total_damage))*50) // Style 4: The Equal Intervals method allows to detect the outliers quickly. width: ramp(globalEqIntervals($total_damage, 3), [1, 25])
You can explore this map here
ramp can be used in the same way with numbers. With this approach, the same implicit casts we explored in Part 1, will be performed.
width: ramp($number, [0, 50])
Classified numerical properties are similar too:
width: ramp(globalQuantiles($number, 7), [1, 50])
Categorical properties can be used, although normally, it doesn’t make sense to set the width by a categorical property:
width: ramp(buckets($cat, 'categoryA', 'categoryB'), [1, 50])
ramp($number, [0, 50]) works, and it probably works as expected. If
$number is a property with a minimum of
0 and a maximum of
300 in the dataset, a feature with
$number=150 is halfway in the
linear range. Therefore, ramp will output
However, this is probably not what you want. The reason for this is that a change of
3x in width is not perceive as a change of
3x, because we perceive the change of area, not the change of width, and the change of area when triplicating the width is not a
3x, but a
9x. Basic geometry tells us that the area of a circle is proportional to the square of its radius.
If you don’t want to accentuate differences you can take the square root of the output values to specify the widths and not the areas:
width: sqrt(ramp($number, [0, 50^2]))
Similarly, classifiers can be re-mapped in the same way:
width: sqrt(ramp(globalQuantiles($number, 7), [1, 50^2]))
ramp is useful because it allows mapping most input to most values, interpolating the values if needed and providing implicit casts if they are convenient. However, it can be overkill when the matching is done from a numerical property to a numeric list.
For this case, using regular math is probably simpler and easier, while having the same, correct, results.
For example, the
width: ramp(sqrt(linear($number)), [0, 50]) is equivalent to
width: sqrt($number/globalMax($number))*50. And since sometimes we don’t want to normalize by the maximum value in the dataset, this could be reduced further to
The last supported type of value for
ramp is the
The map below, assigns different image markers and colors to two categories in the data (
bus). The features labeled “Default” in the legend are ones that weren’t specified in the
buckets list. Because of this, they are symbolized with default image symbology: colored gray with a circle image.
symbol: ramp(buckets($complaint,['Car','Bus']), [car,bus]) color: ramp(buckets($complaint,['Car','Bus']), [#59ca22,#009fff]) width: 20
As discussed above, the others bucket receives default values, but they can be overwritten, even when working with images.
In the map below, the defaults are overwritten to
cross for the image and
gold for the color:
symbol: ramp(buckets($complaint,['Car','Bus']), [car,bus], cross) color: ramp(buckets($complaint,['Car','Bus']), [#59ca22,#009fff], gold) width: 20
You can explore this map here