See the wikipedia page on Logistic Map function

Create data for a range of the logistic map function

import spire.algebra._

val initial = 0.3
// initial: Double = 0.3

import java.util.TreeSet
val memo = collection.mutable.Map.empty[Double, TreeSet[Double]]
// memo: collection.mutable.Map[Double, TreeSet[Double]] = HashMap(
//   3.441475 -> [0.441843868131019, 0.4418438681310315, 0.8487292146314505, 0.8487292146314557],
//   3.2696 -> [0.48885400315007677, 0.8169938069796027],
//   3.097725 -> [0.5592674741889692, 0.7635500774013108],
//   3.9571 -> [0.04267247440624257, 0.04309838117976036, 0.04589402429849939, 0.04841085498645868, 0.05268425486646831, 0.05445075037809183, 0.059787970122293366, 0.062038078786446356, 0.06204632299888421, 0.06681599209495541, 0.0698698798052346, 0.07024311007533801, 0.07866774230618095, 0.08356792547392135, 0.09610384481280872, 0.09886058489310885, 0.0993229313119621, 0.10319595285549582, 0.10922609954832717, 0.11105842826925762, 0.11712759750450226, 0.1426718389008983, 0.15078424463443954, 0.15581223607381062, 0.1616536065142235, 0.16165640571626283, 0.16319440780791358, 0.1641070072154968, 0.16772540418875756, 0.17327255630325167, 0.17362933630901856, 0.18229269165161024, 0.1974934166462566, 0.20373472098709616, 0.20885244610540513, 0.21288031280303363, 0.21387384227739395, 0.2163080914138626, 0.21959451771694777, 0.22244192148438077, 0.2302610989139107, 0.2302896740600378, 0.23376245896715572, 0.24673157688511976, 0.2525126937925101, 0.2571643301857636, 0.258434305481506, 0.273547515825511, 0.28040072917222214, 0.2834718012326063, 0.28680715988843464, 0.29638473708696356, 0.30305184158220255, 0.30707434601095823, 0.32557030284952965, 0.34047352797091424, 0.34374495056912446, 0.34592148832454983, 0.35252683901291865, 0.35399380317392304, 0.3662159457624865, 0.3699332611416092, 0.3708279685957619, 0.37916230689112723, 0.38500904685380816, 0.39066253605133344, 0.3914691271069075, 0.3917996956772106, 0.39314813769818124, 0.40559308462732185, 0.409198659395128, 0.41244247128977296, 0.414460431504783, 0.4362701287272594, 0.4508303208905984, 0.4658328685365325, 0.4714297964401069, 0.48401895963338826, 0.49147351599947176, 0.5067001503366728, 0.5204962904562452, 0.5264624161242119, 0.5362729903578217, 0.5362804858649601, 0.5403894627699287, 0.542818743594693, 0.5431065172867638, 0.5523858067751253, 0.5598655357648019, 0.561394685739483, 0.5616476607693902, 0.5668513204252845, 0.5677733735816993, 0.5707482411416618, 0.5821926759298408, 0.58985350224716, 0.5921855645681813, 0.6104190684352865, 0.6241804843596593, 0.6271598571050929, 0.6368102719498209, 0.6419480044626596, 0.6538439073749307, 0.6594413191853002, 0.6598735979180124, 0.6630607188595588, 0.664802745291893, 0.6653144323095036, 0.6708032431580004, 0.6781391703822449, 0.6795167605063398, 0.6844260032929936, 0.700991342149856, 0.7013600652706424, 0.7014210633359472, 0.708786143151287, 0.7251340086862942, 0.7252402001700398, 0.7300880913158538, 0.7354472393705186, 0.7415928608024178, 0.7458065591600431, 0.7469027566375223, 0.7480463407251603, 0.7501835969837706, 0.7559281269361989, 0.7583105074729751, 0.7583624468737464, 0.7699115686596237, 0.7797840296654437, 0.7863520328583709, 0.7885188609488879, 0.7887081128394596, 0.7984484437328263, 0.8037484999251484, 0.8094201076261686, 0.8167784676502796, 0.8252168974554104, 0.8287336930584712, 0.8288309145323112, 0.8294179751148617, 0.8357847215411213, 0.8419905193433909, 0.8546823528221187, 0.8617524376565232, 0.8637021137987521, 0.8688773863637202, 0.8738315622906001, 0.8811319620403752, 0.8818003822113332, 0.8840604672957172, 0.8881332361926515, 0.8885719679152415, 0.8886794467657111, 0.8926598690856951, 0.8953327030144219, 0.8956185636166359, 0.903214670648688, 0.9049182959815878, 0.9095424583394279, 0.9152097594229854, 0.918450138956013, 0.922331328367279, 0.9232491494592157, 0.9252901600592599, 0.9314944226889587, 0.936950586016326, 0.9410285700054537, 0.9419691317249712, 0.9426645154871669, 0.9429480199990259, 0.9440955211390117, 0.9540066906765148, 0.9556...
implicit val ringDouble: Ring[Double] = spire.implicits.DoubleAlgebra
// ringDouble: Ring[Double] = spire.std.DoubleAlgebra@72bb30c3

def lhsContainsMark(minX: Double, maxX: Double, maxY: Double, minY: Double): Boolean = {
  val λ = minX
  val f = axle.math.logisticMap(λ)
  val set = memo.get(λ).getOrElse {
    val set = new TreeSet[Double]()
    axle.algebra.applyForever(f, initial).drop(10000).take(200) foreach { set.add }
    memo += minX -> set
    set
  }
  !set.tailSet(minY).headSet(maxY).isEmpty
}

Define a “value to color” function.

import axle.visualize._

val v2c = (v: Boolean) => if (v) Color.black else Color.white
// v2c: Boolean => Color = <function1>

Define a PixelatedColoredArea to show a range of Logistic Map.

import cats.implicits._

val pca = PixelatedColoredArea[Double, Double, Boolean](
  lhsContainsMark,
  v2c,
  4000,    // width
  4000,    // height
  2.9, 4d, // x range
  0d, 1d   // y range
)
// pca: PixelatedColoredArea[Double, Double, Boolean] = PixelatedColoredArea(
//   f = <function4>,
//   c = <function1>,
//   width = 4000,
//   height = 4000,
//   minX = 2.9,
//   maxX = 4.0,
//   minY = 0.0,
//   maxY = 1.0
// )

Create the PNG

import axle.awt._
import cats.effect._

pca.png[IO]("logMap.png").unsafeRunSync()
// res0: Boolean = true

Logistic Map