- "text": "Explicit color mapping with scale_color_manual\nI am fairly happy with the scale_fill_gradient2 used with squish. We get a really nice palette that’s centered around 0. However scale_fill_gradient2 is limited to 3 colors (high, midpoint, low), which is not quite enable the more dynamic color palette that I’m seeking.\nTo be more explicit with the colors, I will bin the PDIFF and map colors manually using scale_fill_manual\n\nBin with polars.Series.cut\n\nlabour_processed_cutted = (\n labour_processed_cat.with_columns(\n pl.col(\"PDIFF\")\n .cut(\n [\n -0.05,\n -0.025,\n -0.012,\n -0.0080,\n -0.0040,\n 0,\n 0.0040,\n 0.0080,\n 0.012,\n 0.025,\n 0.05,\n ]\n )\n .alias(\"PDIFF_BINNED\")\n )\n .with_columns(\n pl.when(pl.col(\"PDIFF\") == 0)\n .then(pl.lit(\"0\"))\n .otherwise(pl.col(\"PDIFF_BINNED\"))\n .alias(\"PDIFF_BINNED\")\n )\n .sort(\"PDIFF\")\n .with_columns(pl.col(\"PDIFF_BINNED\"))\n)\nlabour_processed_cutted.group_by(\"PDIFF_BINNED\").len()\n\n\nshape: (13, 2)\n\n\n\nPDIFF_BINNED\nlen\n\n\ncat\nu32\n\n\n\n\n\"(-0.008, -0.004]\"\n1201\n\n\n\"(-0.025, -0.012]\"\n892\n\n\n\"(0.004, 0.008]\"\n1736\n\n\n\"(0.008, 0.012]\"\n1021\n\n\n\"0\"\n74\n\n\n…\n…\n\n\n\"(-0.05, -0.025]\"\n255\n\n\n\"(0.012, 0.025]\"\n1292\n\n\n\"(0.025, 0.05]\"\n315\n\n\n\"(0, 0.004]\"\n2624\n\n\n\"(0.05, inf]\"\n58\n\n\n\n\n\n\n\n(\n ggplot(\n (\n labour_processed_cutted.filter(\n pl.col(\"YEAR\") >= FILTER_YEAR[0], pl.col(\"YEAR\") <= FILTER_YEAR[1]\n )\n ),\n aes(x=\"DATE_YMD\", y=\"centered_rank_cat\", fill=\"PDIFF_BINNED\"),\n )\n + geom_tile(height=0.95) # whitespace between tiles, vertically\n + theme_tufte()\n + theme(figure_size=FIGURE_THEME_SIZE, axis_text_x=element_text(angle=90))\n)\n\n\n\n\n\n\n\n\n\n\nscale_fill_manual for explicit color mapping\nNow we need to order the levels, and map explicit colors\nWe will make PDIFF=0% to be gray, positive values to have a green and blue colors (job growth = good), and negative values to have warmer (alarming, bad) colors.\n\norder = (\n labour_processed_cutted.drop_nulls()\n .sort(\"PDIFF\")\n .select(pl.col(\"PDIFF_BINNED\"))\n .unique(maintain_order=True)\n .to_series()\n .to_list()\n)\n\nlabour_processed_cutted_ordered = labour_processed_cutted.with_columns(\n pl.col(\"PDIFF_BINNED\").cast(pl.Enum(order))\n)\n\ncolor_mapping = {\n \"(-inf, -0.05]\": \"#d82828ff\",\n \"(-0.05, -0.025]\": \"#fa6f1fff\",\n \"(-0.025, -0.012]\": \"#f1874aff\",\n \"(-0.012, -0.008]\": \"#f1b274ff\",\n \"(-0.008, -0.004]\": \"#FEE08B\",\n \"(-0.004, 0]\": \"#FFFFBF\",\n \"0\": \"#a8a8a8ff\",\n \"(0, 0.004]\": \"#E6F5D0\",\n \"(0.004, 0.008]\": \"#bce091ff\",\n \"(0.008, 0.012]\": \"#9ad65fff\",\n \"(0.012, 0.025]\": \"#78b552ff\",\n \"(0.025, 0.05]\": \"#5cb027ff\",\n \"(0.05, inf]\": \"#1f6fc6ff\",\n}\n\n(\n ggplot(\n (\n labour_processed_cutted.filter(\n pl.col(\"YEAR\") >= FILTER_YEAR[0], pl.col(\"YEAR\") <= FILTER_YEAR[1]\n )\n ),\n aes(x=\"DATE_YMD\", y=\"centered_rank_across_industry\", fill=\"PDIFF_BINNED\"),\n )\n + geom_tile(color=\"white\")\n # + geom_point(shape=\"s\")\n + theme_tufte()\n + theme(figure_size=FIGURE_THEME_SIZE, axis_text_x=element_text(angle=90))\n + scale_fill_manual(values=color_mapping, breaks=order)\n)\n\n\n\n\n\n\n\n\nThat looks great. The power of scale_fill_manual enables much more control over the color palette. However, the cost was that it takes a lot more effort and lines of code to create a custom mapping.",
0 commit comments