Colors
Colors in EvilPlot are described by their HSL representation.
import com.cibo.evilplot.colors._
val transparentColor = HSLA(210, 100, 56, 0.8)
val color = HSL(210, 100, 56) // fully opaque
You can also use the RGB representation to describe a color. It will be converted to HSL automatically.
import com.cibo.evilplot.colors._
val transparentColor = RGBA(230, 126, 34, 0.8)
val color = RGB(230, 126, 34)
val hexColor = HEX("E67E22")
Predefined colors
All of the HTML named colors are available to use:
import com.cibo.evilplot.colors._
val htmlRed = HTMLNamedColors.red
val htmlDodgerBlue = HTMLNamedColors.dodgerBlue
val htmlTomato = HTMLNamedColors.tomato
Modifying colors
You can create colors by modifying the HSLA properties of another color.
import com.cibo.evilplot.colors._
val htmlRed = HTMLNamedColors.red
val transparentRed = htmlRed.copy(opacity = 0.5)
val difficultWhite = htmlRed.copy(lightness = 100)
EvilPlot has several helpful methods for modifying colors:
import com.cibo.evilplot.colors._
val htmlRed = HTMLNamedColors.red
val lighterRed = htmlRed.lighten(20) // Increase lightness by 20
val darkerRed = htmlRed.darken(20)
// Two new colors evenly spaced around the HSL color wheel from the first
val (triad1, triad2) = htmlRed.triadic
// Two new colors adjacent to the first color on the color wheel
// (+/- 45 degrees away in this example)
val (analogue1, analogue2) = htmlRed.analogous(45)
Color Sequences and Gradients
A variety of streams and sequences of colors can be generated.
import com.cibo.evilplot.colors._
val colors = Color.stream.take(40)
import com.cibo.evilplot.colors._
// A gradient across all hues
val colors = Color.getGradientSeq(10)
import com.cibo.evilplot.colors._
// A gradient between specific hues
val colors = Color.getGradientSeq(10, startHue = 0, endHue = 120)
import com.cibo.evilplot.colors._
val colors = Color.getDefaultPaletteSeq(8)
Data can be colored using a continuous gradient.
import com.cibo.evilplot.colors._
import com.cibo.evilplot.plot._
import com.cibo.evilplot.plot.renderers.PointRenderer
import com.cibo.evilplot.geometry.Extent
import com.cibo.evilplot.numeric.Point
val gradient = ContinuousColoring.gradient(HTMLNamedColors.blue, HTMLNamedColors.orange)
val points = Seq.tabulate(100) { i =>
Point(i.toDouble, (math.sin(i.toDouble / 10) * 50) + 50)
}
val renderer = PointRenderer.depthColor(points.map(_.y), Some(gradient))
ScatterPlot(points, pointRenderer = Some(renderer))
.frame().xAxis().yAxis().xGrid().yGrid()
.xbounds(0, 100).ybounds(0, 100)
.render(Extent(500, 300))
import com.cibo.evilplot.colors._
// Multiple stop points can be given for continuous gradients
val gradient = ContinuousColoring.gradient(Seq(
HTMLNamedColors.green,
HTMLNamedColors.red,
HTMLNamedColors.blue,
HTMLNamedColors.red
), Some(0d), Some(40d), GradientMode.Linear)
val gradientFunc = gradient(Seq(0, 40))
val colors = Seq.tabulate(40) { gradientFunc(_) }
Categorical data can be colored using a categorical gradient.
import com.cibo.evilplot.colors._
import com.cibo.evilplot.plot._
import com.cibo.evilplot.plot.renderers.PointRenderer
import com.cibo.evilplot.geometry.Extent
import com.cibo.evilplot.numeric.Point
val gradient: Coloring[Double] = CategoricalColoring.gradient(
HTMLNamedColors.blue,
HTMLNamedColors.orange
)
val points = Seq.tabulate(100) { i => Point(i.toDouble, i.toDouble) }
val renderer = PointRenderer.colorByCategory(points.map(p => p.x % 3), Some(gradient))
ScatterPlot(points, pointRenderer = Some(renderer))
.frame().xAxis().yAxis().xGrid().yGrid()
.xbounds(0, 100).ybounds(0, 100)
.rightLegend()
.render(Extent(500, 300))