Skip to content

Commit c562791

Browse files
committed
Release v4.12.0
1 parent 4e671b5 commit c562791

File tree

6 files changed

+173
-157
lines changed

6 files changed

+173
-157
lines changed

CHANGELOG.md

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,120 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres
66
to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). All scales should have the 'format' parameter.
77

8+
## [4.12.0] - 2025-12-02
9+
10+
This release is 100% compatible with Lets-Plot [v 4.8.1](https://github.com/JetBrains/lets-plot/releases/tag/v4.8.0),
11+
GeoTools [v 33.2](https://github.com/geotools/geotools/releases/tag/33.2)
12+
13+
### Added
14+
15+
- Geometries:
16+
- `geomPointDensity()` [[#1370](https://github.com/JetBrains/lets-plot/issues/1370)].
17+
18+
See: [example notebook](https://raw.githack.com/JetBrains/lets-plot-kotlin/refs/heads/master/docs/examples/jupyter-notebooks/f-4.12.0/geom_pointdensity.html).
19+
20+
- Geoms with 1-to-1 statistics (such as `geomQQ()`, `geomSina()`) preserve the mapping to original data after statistical transformation.
21+
22+
See: [example notebook](https://raw.githack.com/JetBrains/lets-plot-kotlin/refs/heads/master/docs/examples/jupyter-notebooks/f-4.12.0/stat_data_bijection.html).
23+
24+
- `geomHistogram()`: custom bin bounds (parameter `breaks`) [[#1382](https://github.com/JetBrains/lets-plot/issues/1382)].
25+
26+
See: [example notebook](https://raw.githack.com/JetBrains/lets-plot-kotlin/refs/heads/master/docs/examples/jupyter-notebooks/f-4.12.0/geom_histogram_param_breaks.html).
27+
28+
- Plot Layout:
29+
- The legend automatically wraps to prevent overlap - up to 15 rows for vertical legends and 5 columns for horizontal ones [[#1235](https://github.com/JetBrains/lets-plot/issues/1235)].
30+
31+
See: [example notebook](https://raw.githack.com/JetBrains/lets-plot-kotlin/refs/heads/master/docs/examples/jupyter-notebooks/f-4.12.0/legend_wrap.html).
32+
33+
- `gggrid()`: support for shared legends (parameter `guides`).
34+
35+
See: [example notebook](https://raw.githack.com/JetBrains/lets-plot-kotlin/refs/heads/master/docs/examples/jupyter-notebooks/f-4.12.0/gggrid_legend_collect.html).
36+
37+
- Plot Theme:
38+
- `flavorStandard()` sets the theme's default color scheme [[#1277](https://github.com/JetBrains/lets-plot/issues/1277)]. <br>
39+
Use to override other flavors or to make defaults explicit.
40+
41+
See: [example notebook](https://raw.githack.com/JetBrains/lets-plot-kotlin/refs/heads/master/docs/examples/jupyter-notebooks/f-4.12.0/flavor_standard.html).
42+
43+
- `themeGray()` as an alias for `themeGrey()`.
44+
45+
- New `theme` functions for setting legend justification: `legendJustificationTop()`, `legendJustificationRight()`, <br>
46+
`legendJustificationBottom()`, and `legendJustificationLeft()`.
47+
48+
See: [example notebook](https://raw.githack.com/JetBrains/lets-plot-kotlin/refs/heads/master/docs/examples/jupyter-notebooks/f-4.12.0/legend_justification.html).
49+
50+
- Support for inward axis ticks.
51+
52+
See: [example notebook](https://raw.githack.com/JetBrains/lets-plot-kotlin/refs/heads/master/docs/examples/jupyter-notebooks/f-4.12.0/axis_tick_direction.html).
53+
54+
- Markdown:
55+
- Support for `target` attribute for links.
56+
- Links now open in a new tab by default [[#1397](https://github.com/JetBrains/lets-plot/issues/1397)].
57+
58+
- `ggtb()`: `sizeZoomin` and `sizeBasis` parameters for geometry scaling [[#1369](https://github.com/JetBrains/lets-plot/issues/1369)].
59+
60+
See: [example notebook](https://raw.githack.com/JetBrains/lets-plot-kotlin/refs/heads/master/docs/examples/jupyter-notebooks/f-4.12.0/ggtb_size_zoomin.html).
61+
62+
- New `output` parameter for the library descriptor to control output types stored in notebook cells [[LPK-277](https://github.com/JetBrains/lets-plot-kotlin/issues/277)].\
63+
Thanks to [AndreiKingsley](https://github.com/AndreiKingsley) for the contribution!
64+
```
65+
%use lets-plot(output="js, png")
66+
```
67+
68+
Available output types:
69+
- `js` - Classic Web output: HTML+JS
70+
- `ktnb` - Kotlin Notebook Swing-based rendering
71+
- `svg` - Static SVG output
72+
- `png` - Static PNG output
73+
74+
Default: `"js, ktnb, svg"`
75+
76+
**Note:** Static images (SVG/PNG) are hidden when `js` or `ktnb` outputs are present, and only displayed in environments where JavaScript is not executed (e.g., GitHub).
77+
78+
This option can be helpful when a Kotlin Notebook file size becomes a problem. \
79+
For example, when working with large datasets where plot interactivity is not a priority, storing only static output (SVG or PNG) can significantly reduce file size.
80+
81+
- [`CenteredPlotPanel`](https://github.com/JetBrains/lets-plot/blob/master/platf-awt/src/main/kotlin/org/jetbrains/letsPlot/awt/plot/component/CenteredPlotPanel.kt) helper class for displaying plots centered in Swing applications.
82+
83+
### Changed
84+
85+
- [**BREAKING**] Explicit `group` aesthetic now overrides default grouping behavior instead of combining with it [[#1401](https://github.com/JetBrains/lets-plot/issues/1401)].
86+
87+
See: [example notebook](https://raw.githack.com/JetBrains/lets-plot-kotlin/refs/heads/master/docs/examples/jupyter-notebooks/f-4.12.0/group_override_defaults.html).
88+
89+
> [!IMPORTANT]
90+
> Previously, setting `group="variable"` would group by both the explicit variable AND any discrete
91+
> aesthetics (color, shape, etc.). \
92+
> Now it groups ONLY by the explicit variable, matching `ggplot2` behavior. \
93+
> Use `group=listOf(var1, var2, ...)` to group by multiple variables explicitly, \
94+
> and `group=emptyList<Any>()` to disable any grouping.
95+
96+
- Missing values in `geomLine(), geomPath(), geomRibbon()`, and `geomArea()` create gaps in geometries instead of being interpolated over [[LPK-269](https://github.com/JetBrains/lets-plot-kotlin/issues/269)],[[#818](https://github.com/JetBrains/lets-plot/issues/818)], [[#1406](https://github.com/JetBrains/lets-plot/issues/1406)].
97+
98+
See: [example notebook](https://raw.githack.com/JetBrains/lets-plot-kotlin/refs/heads/master/docs/examples/jupyter-notebooks/f-4.12.0/missing_values_line_path_area_ribbon.html).
99+
100+
- `theme`: the `exponentFormat` default value changed to `"pow"` - superscript powers of 10 (was e-notation).
101+
102+
- The multi-layer line plot now shows tooltips for each series simultaneously, in the same way that a single-layer plot with color mapped to series does.
103+
104+
105+
### Fixed
106+
107+
- Group by multiple columns [[LPK-136](https://github.com/JetBrains/lets-plot-kotlin/issues/136)].
108+
- `geomPie` on geospatial plot with `mapJoin` failes to render without explicit `group` aesthetic.
109+
- `geomDensity2D`: NullPointerException when weight aesthetic contains None values [[#1399](https://github.com/JetBrains/lets-plot/issues/1399)].
110+
- Tooltip shows duplicate lines when as_discrete is applied twice to the same var [[#1400](https://github.com/JetBrains/lets-plot/issues/1400)].
111+
- `geomSina`: incorrect shape in legend [[#1403](https://github.com/JetBrains/lets-plot/issues/1403)].
112+
- `geomDensity2D`: Incorrect processing of weighted statistics when None value occurs in the x or y column.
113+
- `facetWrap`: indescriptive error when the specified facet variable is not present in the dataset [[#1409](https://github.com/JetBrains/lets-plot/issues/1409)].
114+
- Integer numbers in facet strip titles are displayed as float [[#1386](https://github.com/JetBrains/lets-plot/issues/1386)].
115+
- Error when using `scaleIdentity(aesthetic="shape")` [[#1212](https://github.com/JetBrains/lets-plot/issues/1212)].
116+
- `ggsave`: theme option `face="italic"` doesn't work [[#1391](https://github.com/JetBrains/lets-plot/issues/1391)].
117+
- Fail early if string format is incorrect [[#1410](https://github.com/JetBrains/lets-plot/issues/1410)].
118+
- `statECDF()` takes a very long time for even moderately sized datasets [[#1424](https://github.com/JetBrains/lets-plot/issues/1424)].
119+
- inconsistencies in theme/flavor inheritance in `gggrid()` subplots.
120+
121+
8122
## [4.11.2] - 2025-09-12
9123

10124
This release is 100% compatible with Lets-Plot [v 4.7.3](https://github.com/JetBrains/lets-plot/releases/tag/v4.7.3),

README.md

Lines changed: 49 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ See the "Quickstart" notebook in [Datalore](https://datalore.jetbrains.com/view/
6767
- [Compose Multiplatform](#in-compose-multiplatform)
6868
- [JVM and Kotlin/JS](#in-jvm-js)
6969
- [Documentation](#documentation)
70-
- [What is new in 4.11.0](#new)
70+
- [What is new in 4.12.0](#new)
7171
- [Recent Updates in the Gallery](#recent_gallery_updates)
7272
- [Change Log](#change_log)
7373
- [Code of Conduct](#CoC)
@@ -103,12 +103,21 @@ In this case the latest `library descriptor` will be pulled from the [Kotlin Jup
103103
#### Library Descriptor Parameters
104104

105105
```
106-
%use lets-plot(v=4.11.2, isolatedFrame=false)
106+
%use lets-plot(v=4.12.0, isolatedFrame=false, output="js, ktnb, svg")
107107
```
108108
- `v` - version of the Lets-Plot Kotlin API.
109-
- `isolatedFrame` - If `false`: load JS just once per notebook (default in Jupyter).
109+
- `isolatedFrame` - If `false`: load JS just once per notebook (default in Jupyter).
110110
If `true`: include Lets-Plot JS in each output (default in [Datalore](https://datalore.jetbrains.com/) notebooks).
111+
- `output` - comma-separated list of output types to store in notebook cells (default: `"js, ktnb, svg"`). \
112+
Available types:
113+
- `js` - Classic Web output: HTML+JS
114+
- `ktnb` - Kotlin Notebook Swing-based rendering
115+
- `svg` - Static SVG output
116+
- `png` - Static PNG output
111117

118+
**Note:** Static images (SVG/PNG) are hidden when `js` or `ktnb` outputs are present, and only displayed in environments where JavaScript is not executed (e.g., GitHub).
119+
120+
This option can be helpful when file size becomes a problem. For example, storing only static output (SVG or PNG) can significantly reduce file size when working with large datasets where plot interactivity is not a priority.
112121

113122
<a id="in-compose-multiplatform"></a>
114123
### Compose Multiplatform
@@ -132,68 +141,61 @@ Examples of using the Lets-Plot Kotlin API in JVM and Kotlin/JS applications are
132141

133142

134143
<a id="new"></a>
135-
## What is new in 4.11.0
144+
## What is new in 4.12.0
145+
146+
- #### `geomPointDensity()` Geometry
147+
148+
<img src="https://raw.githubusercontent.com/JetBrains/lets-plot/master/docs/f-25e/images/geom_pointdensity.png" alt="f-25e/images/geom_pointdensity.png" width="400" height="246">
149+
150+
See: [example notebook](https://raw.githack.com/JetBrains/lets-plot-kotlin/refs/heads/master/docs/examples/jupyter-notebooks/f-4.12.0/geom_pointdensity.html).
151+
152+
- #### Explicit `group` aesthetic now overrides default grouping behavior instead of combining with it
153+
154+
> [!IMPORTANT]
155+
> **BREAKING CHANGE:**
156+
>
157+
> Previously, setting `group='variable'` would group by both the explicit variable AND any discrete
158+
> aesthetics (color, shape, etc.). \
159+
> Now it groups ONLY by the explicit variable, matching `ggplot2` behavior. \
160+
> Use `group=[var1, var2, ...]` to group by multiple variables explicitly, \
161+
> and `group=[]` to disable any grouping.
136162
137-
- #### Time Series Plotting
138-
- Support temporal data types from `kotlinx.datetime`, `java.time`, and `java.util`.
139-
- Support for timezone-aware `java.time.ZonedDateTime` and `java.time.OffsetDateTime` objects.
163+
<img src="https://raw.githubusercontent.com/JetBrains/lets-plot/master/docs/f-25e/images/group_override_defaults.png" alt="f-25e/images/group_override_defaults.png" width="400" height="263">
140164

141-
<img src="https://raw.githubusercontent.com/JetBrains/lets-plot/master/docs/f-25b/images/time_date_datetime.png" alt="f-25b/images/time_date_datetime.png" width="400" height="237">
142-
143-
See [Date-time](https://nbviewer.org/github/JetBrains/lets-plot-kotlin/blob/master/docs/examples/jupyter-notebooks/f-4.11.0/time_date_datetime.ipynb) cookbook.
144-
<br><br>
145-
<img src="https://nbviewer.org/github/JetBrains/lets-plot-kotlin/blob/master/docs/examples/jupyter-notebooks/f-4.11.0/images/bitcoin_trading.png" alt="f-4.11.0/images/bitcoin_trading.png" width="400" height="237">
146-
147-
See [Bitcoin trading](https://nbviewer.org/github/JetBrains/lets-plot-docs/blob/master/source/kotlin_examples/demo/trading_chart.ipynb) demo.
148-
<br><br>
165+
See: [example notebook](https://raw.githack.com/JetBrains/lets-plot-kotlin/refs/heads/master/docs/examples/jupyter-notebooks/f-4.12.0/group_override_defaults.html).
149166

150-
- #### `geomSina()` Geometry
167+
- #### `gggrid()`: support for shared legends (parameter `guides`)
151168

152-
<img src="https://raw.githubusercontent.com/JetBrains/lets-plot/master/docs/f-25b/images/geom_sina.png" alt="f-25b/images/geom_sina.png" width="400" height="276">
169+
<img src="https://raw.githubusercontent.com/JetBrains/lets-plot/master/docs/f-25e/images/gggrid_legend_collect.png" alt="f-25e/images/group_override_defaults.png" width="500" height="172">
153170

154-
See: [example notebook](https://nbviewer.org/github/JetBrains/lets-plot-kotlin/blob/master/docs/examples/jupyter-notebooks/f-4.11.0/geom_sina.ipynb).
171+
See: [example notebook](https://raw.githack.com/JetBrains/lets-plot-kotlin/refs/heads/master/docs/examples/jupyter-notebooks/f-4.12.0/gggrid_legend_collect.html).
155172

156-
- #### `geomTextRepel()` and `geomLabelRepel()` Geometries
173+
- #### Better handling of missing values in `geomLine(), geomPath(), geomRibbon()`, and `geomArea()`
157174

158-
<img src="https://raw.githubusercontent.com/JetBrains/lets-plot/master/docs/f-25b/images/geom_repel.png" alt="f-25b/images/geom_repel.png" width="400" height="232">
175+
<img src="https://raw.githubusercontent.com/JetBrains/lets-plot/master/docs/f-25e/images/missing_values_ribbon.png" alt="f-25e/images/missing_values_ribbon.png" width="500" height="192">
159176

160-
See: [example notebook](https://nbviewer.org/github/JetBrains/lets-plot-kotlin/blob/master/docs/examples/jupyter-notebooks/f-4.11.0/ggrepel.ipynb).
177+
See: [example notebook](https://raw.githack.com/JetBrains/lets-plot-kotlin/refs/heads/master/docs/examples/jupyter-notebooks/f-4.12.0/missing_values_line_path_area_ribbon.html).
161178

162-
- #### `waterfallPlot()` Chart
179+
- #### `geomHistogram()`: custom bin bounds (parameter `breaks`)
163180

164-
- Annotations support via `relativeLabels` and `absoluteLabels` parameters.
165-
<br><br>
166-
<img src="https://raw.githubusercontent.com/JetBrains/lets-plot/master/docs/f-25b/images/waterfall_plot_annotations.png" alt="f-25b/images/waterfall_plot_annotations.png" width="400" height="253">
181+
See: [example notebook](https://raw.githack.com/JetBrains/lets-plot-kotlin/refs/heads/master/docs/examples/jupyter-notebooks/f-4.12.0/geom_histogram_param_breaks.html).
167182

168-
See: [example notebook](https://nbviewer.org/github/JetBrains/lets-plot-kotlin/blob/master/docs/examples/jupyter-notebooks/f-4.11.0/waterfall_plot_annotations.ipynb).
169-
<br><br>
170-
- Support for combining waterfall bars with other geometry layers.
171-
<br><br>
172-
<img src="https://raw.githubusercontent.com/JetBrains/lets-plot/master/docs/f-25b/images/waterfall_plot_layers.png" alt="f-25b/images/waterfall_plot_layers.png" width="400" height="227">
183+
- #### Legend automatically wraps to prevent overlap — up to 15 rows for vertical legends and 5 columns for horizontal ones
173184

174-
See: [example notebook](https://nbviewer.org/github/JetBrains/lets-plot-kotlin/blob/master/docs/examples/jupyter-notebooks/f-4.11.0/waterfall_plot_layers.ipynb).
175-
176-
- #### Continuous Data on Discrete Scales
185+
See: [example notebook](https://raw.githack.com/JetBrains/lets-plot-kotlin/refs/heads/master/docs/examples/jupyter-notebooks/f-4.12.0/legend_wrap.html).
177186

178-
Continuous data when used with discrete positional scales is no longer transformed to discrete data. <br>
179-
Instead, it remains continuous, allowing for precise positioning of continuous elements relative to discrete ones.
180-
<br><br>
181-
<img src="https://raw.githubusercontent.com/JetBrains/lets-plot/master/docs/f-25b/images/combo_discrete_continuous.png" alt="f-25b/images/combo_discrete_continuous.png" width="400" height="151">
187+
- #### `flavorStandard()` resets the theme's default color scheme
188+
Use to override other flavors or make defaults explicit.
182189

183-
See: [example notebook](https://nbviewer.org/github/JetBrains/lets-plot-kotlin/blob/master/docs/examples/jupyter-notebooks/f-4.11.0/numeric_data_on_discrete_scale.ipynb).
190+
See: [example notebook](https://raw.githack.com/JetBrains/lets-plot-kotlin/refs/heads/master/docs/examples/jupyter-notebooks/f-4.12.0/flavor_standard.html).
184191

185-
> [!TIP]
186-
> New way of handling continuous data on discrete scales could potentially break existing plots.
187-
> If you want to restore a broken plot to its original form, you can use the [`asDiscrete()`](https://lets-plot.org/kotlin/as-discrete.html) function to annotate continuous data as discrete.
192+
- #### `theme` methods controlling legend justification: `legendJustificationTop()`, `legendJustificationRight()`, `legendJustificationBottom()`, and `legendJustificationLeft()`
188193

194+
See: [example notebook](https://raw.githack.com/JetBrains/lets-plot-kotlin/refs/heads/master/docs/examples/jupyter-notebooks/f-4.12.0/legend_justification.html).
189195

190-
- #### Plot Layout
191-
The default plot layout has been improved to better accommodate axis labels and titles. <br>
192-
Also, new `theme()` options `axisTextSpacing`, `axisTextSpacingX`, and `axisTextSpacingY` control spacing between axis ticks and labels.
193-
<br><br>
194-
<img src="https://raw.githubusercontent.com/JetBrains/lets-plot/master/docs/f-25b/images/plot_layout_diagram.png" alt="f-25b/images/plot_layout_diagram.png" width="400" height="175">
196+
- #### `ggtb()`: Added `sizeZoomin` and `sizeBasis` parameters to control point size scaling behavior when zooming (works with `geomPoint` and related layers).
195197

196-
See new [Plot Layout Diagrams](https://lets-plot.org/kotlin/presentation-options.html#plot-layout-diagrams) showing various layout options and their effects on plot appearance.
198+
See: [example notebook](https://raw.githack.com/JetBrains/lets-plot-kotlin/refs/heads/master/docs/examples/jupyter-notebooks/f-4.12.0/ggtb_size_zoomin.html).
197199

198200

199201
- #### And More

USAGE_BATIK_JFX_JS.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ plugins {
5252

5353
dependencies {
5454
// Lets-Plot Kotlin API
55-
implementation("org.jetbrains.lets-plot:lets-plot-kotlin-jvm:4.11.2")
55+
implementation("org.jetbrains.lets-plot:lets-plot-kotlin-jvm:4.12.0")
5656
// Lets-Plot Multiplatform (Batik rendering)
57-
implementation("org.jetbrains.lets-plot:lets-plot-batik:4.7.3")
57+
implementation("org.jetbrains.lets-plot:lets-plot-batik:4.8.1")
5858
}
5959
```
6060

@@ -75,9 +75,9 @@ plugins {
7575

7676
dependencies {
7777
// Lets-Plot Kotlin API
78-
implementation("org.jetbrains.lets-plot:lets-plot-kotlin-jvm:4.11.2")
78+
implementation("org.jetbrains.lets-plot:lets-plot-kotlin-jvm:4.12.0")
7979
// Lets-Plot Multiplatform (JFX Scene rendering)
80-
implementation("org.jetbrains.lets-plot:lets-plot-jfx:4.7.3")
80+
implementation("org.jetbrains.lets-plot:lets-plot-jfx:4.8.1")
8181
}
8282
```
8383

@@ -95,7 +95,7 @@ kotlin {
9595
named("jsMain") {
9696
dependencies {
9797
// Lets-Plot Kotlin API
98-
implementation("org.jetbrains.lets-plot:lets-plot-kotlin-js:4.11.2")
98+
implementation("org.jetbrains.lets-plot:lets-plot-kotlin-js:4.12.0")
9999
}
100100
}
101101
}
@@ -193,7 +193,7 @@ val rawSpec = figure.toSpec()
193193
```kotlin
194194
val html: String = PlotHtmlExport.buildHtmlFromRawSpecs(
195195
plotSpec = rawSpec,
196-
scriptUrl = PlotHtmlHelper.scriptUrl(version="4.7.3"),
196+
scriptUrl = PlotHtmlHelper.scriptUrl(version="4.8.1"),
197197
iFrame = true
198198
)
199199
```

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ if (project.file("local.properties").exists()) {
3636

3737
allprojects {
3838
group = "org.jetbrains.lets-plot"
39-
version = "4.11.3-SNAPSHOT"
39+
version = "4.12.1-SNAPSHOT"
4040
// version = "0.0.0-SNAPSHOT" // for local publishing only
4141

4242
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().all {

0 commit comments

Comments
 (0)