All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Number formatting:
- We have aligned our specifications with D3.js (rather than Python):
g
format type with~
(e.g.~g
) now truncates trailing zeros, and without~
it doesn't. - The default number formatter now respects
theme(exponent_format=...)
settings and does not use 's' format type for large numbers.
- We have aligned our specifications with D3.js (rather than Python):
- Legends with more than 200 items are now not rendered.
- Bad precision in the default tooltip format when using coord limits [#1134].
- Display integer values without fractional part in tooltips [#1186].
- Suboptimal tooltip positioning in facets [#1187].
- Incorrect Y-axis layout with facets and panel_inset [#1194].
- Grouped plot hits the limit of 1000 and doesn't render with not-friendly exception [#1224].
- Kandy toPNG reports NullPointerException [#1228]
- lets_plot_kotlin_bridge is unable to locate libc++.1.dylib, I am using Mac m2 [#1234].
- Wrong formatting when type='g' for small values [#1238].
- Formatting when type='g' for large values throws exception [#1239].
- Wrong formatting when type='s' with explicit precision [#1240].
- Extra trim in formatted number when type='g' [#1241].
- Axis breaks are badly formatted if explicitly set [#1245].
- Badly formatted zero break for the "~g" format [#1246].
- How to adjust the vertical position of geom_text when using position_dodge [#1248].
- Incorrect result for format(9.999, ".2f") [#1251].
- Tooltips overlapping when not enough vertical space for them [#1254].
- Plot limited to 1000 lines (Internal error: IllegalStateException : Too many groups: 1099) [#1261].
- Nice to have tooltip to inherit formatting configured for axis [LPK-229].
- Interact refinement:
- Dragging the plot or Livemap disables the pinned tooltip mode.
- Double-clicking the plot or Livemap disables the pinned tooltip mode.
- Ctrl + double-clicking the Livemap zooms in without the blinking fade-in effect.
- Buttons alignment in the toolbar.
- Wheel zooming-out a plot with log positional scales crashes fast.
-
Python 3.13 support
-
ggtb()
: enable zoom/pan interactivity on plot [#983],[#1019]See example notebook.
-
Interactive links in tooltips/labels/texts [#1091].
See example notebook.
-
Formatting:
-
LaTeX support: superscript, subscript ([#861]) and Greek letters ([#960]).
See example notebook.
-
Scientific notation: compact form. Enable the compact form using the
exponent_format
parameter intheme()
[#1071].See example notebook.
[WARNING] Subscripts and superscripts are not supported in PDF and PNG exports.
-
-
In
theme()
:-
legend_margin, legend_spacing, legend_spacing_x, legend_spacing_y, legend_box, legend_box_just, legend_box_spacing
parameters [#1180].See example notebook.
-
legend_key, legend_key_size, legend_key_width, legend_key_height, legend_key_spacing, legend_key_spacing_x, legend_key_spacing_y
parameters [#1181].See example notebook.
-
strip_background_x, strip_background_y, strip_text_x, strip_text_y
parameters [#1195].See example notebook.
-
-
Custom
linetype
patterns [#1198]:- a list specifying the pattern of dashes and gaps used to draw the line:
[dash, gap, dash, gap, ...]
; - a list with a specified offset:
[offset, [dash, gap, dash, gap, ...]]
; - a string of an even number (up to eight) of hexadecimal digits specifying the lengths in consecutive positions in the string.
See example notebook.
- a list specifying the pattern of dashes and gaps used to draw the line:
-
Geometries:
-
geom_blank()
[#831]. -
base
parameter inwaterfall_plot()
[#1159].See example notebook.
-
check_overlap
parameter ingeom_text()
andgeom_label()
.See example notebook.
-
marginal
parameter inqq_plot()
:See example notebook.
-
inherit_aes
parameter in layers [#1172].
-
-
expand_limits()
[#820].See example notebook.
-
Support for 3-character hex color codes
-
Parameters
labwidth
infacet_wrap()
,x_labwidth, y_labwidth
infacet_grid()
: the maximum label length is applied after splitting at\n
separators, if present. -
Use
theme_light()
as the default theme inqq_plot()
. -
[BREAKING] For API deprecated in v4.0 the deprecation level raised to "Error" (only relevant for Kotlin clients).
-
[BREAKING] The 'base-midnight', 'base-antique' and 'base-flatblue' tilesets are deprecated (no longer served by CARTO) and will be removed in future releases.
- Better Marimo Support (via PR-2084) [#1018].
- Support layering
aes()
multiple times [#822]. - waterfall_plot: faceting doesn't work without a measure mapping [#1152].
- waterfall_plot: tooltips don't work with column names from original dataset [#1153].
- Legend icon background is not transparent when
legend_background
is set to "blank" intheme
[#1167]. - Unable to display or save graph when using geom_path [#1168].
- Legend icon background should inherit the fill color of the plot panel (i.e. grey when
theme_grey
is used). - Vertex sampling uses different tolerances for objects within the same plot [#1174].
- sampling_vertex_vw doesn't work as expected [#1175].
- sampling_vertex_dp may break rings [#1176].
- ggmarginal: bottom boxplot is broken [#1189].
- Offscreen cells are sometimes not rendered in JupyterLab.
- The legend_justification parameter doesn't work if the legend_position='top' [#1031].
- coord_polar: geom_point tooltips should take in account point size [#1214].
-
New variables computed by
'bin'
statistic:'..sumprop..'
,'..sumpct..'
[#1155].See: example notebook.
- "cmapmpl" color scale doesn't show the entire range of colors in continuous cmap. [#1149].
geom_histogram
: wrong plot area wheny='..density..'
[#1157].
-
Waterfall plot [#975]:
See example notebook.
-
geom_band()
[#733]:See example notebook.
-
Custom legends [#774]:
manual_key
parameter in plot layerlayer_key()
function
See example notebook.
-
In legends:
-
title
parameter inguide_legend()
andguide_colorbar()
functionsSee example notebook.
-
override_aes
parameter in theguide_legend()
function [#807]:See example notebook.
-
-
plot_title_position
andplot_caption_position
parameters intheme()
[#1027]:See example notebook.
-
threshold
parameter ingeom_histogram()
[#1122]:See example notebook.
-
Color scales using Matplotlib's colormap [#1110]:
Thanks to a contribution by Eric Gayer.
See example notebook.
- [breaking change]
guide_legend()
/guide_colorbar()
require keyword arguments for 'nrow'/'barwidth' and other parameters except 'title'. - The triangular point shape is now anchored to the data point via the centroid
as_discrete()
is added tolets-plot
wildcard import (i.e. when usingfrom lets-plot import *
)
- ggsave (.svg) transforms geom_text integer to float [#626].
- Int DataFrame column names are being converted to float string representation [#901].
linetype
= 0 ('blank') should make lines invisible [#712].geom_density2d
: support weight aesthetic [#791].- Discrete axis labels unnecessarily rotate 90 degrees when applying coord system limits.
- Axis title via
labs()
breaks the date-time scale [#1113]. - JavaFX IllegalArgumentException: Unsupported attribute
display
in Pane.
- Support for "angle" aesthetic in
geom_point()
[#736]. See example notebook.
- [BREAKING] Dropped support for Python 3.7 as it is in the "end-of-life" of its release cycle.
- Livemap: improve "tiles" documentation [#1093].
- Undesired vertical scroller when displaying
gggrid
in Jupyter notebook. - GeoJson structure breaks if the ring start label occurs several times [#1086].
theme
: left margin doesn't work for theplot_title
parameter [#1101].- Improve border line type experience [LPK-220].
to_svg()
,to_html()
: return the content as string if no "path" is given [#1067].
- LP occasionally crashes when drawing polygons [#1084].
- Regression of issue [#966].
- Livemap: labels on the map look blurry [#1045].
- Linetype doesn't work for
geom_tile()
[LPK-241].
-
Parameter
dpi
inggsave()
,to_png()
andto_pdf()
functions [#839].See example notebook.
-
Parameter
labwidth
infacet_wrap()
andx_labwidth/y_labwidth
infacet_grid()
[LPK-237].See: example notebook.
-
Parameter
linetype
inelement_line()
andelement_rect()
intheme()
[LPK-235].See: example notebook.
-
Parameter
arrow
ingeom_spoke()
[#986].See: example notebook.
-
Parameter
size_unit
ingeom_point()
,geom_text()
andgeom_label()
.See: example notebook.
-
Auto-detection of
orientation="y"
in bar-chart etc. [#558].See: example notebook.
-
Parameter
plot_inset
intheme()
.See: example notebook.
- ggmarginal(): broken coloring [#760].
- Incorrect 'plot_background' area (with empty space capture) [#918].
- geom_density2df: uneven borders [#941].
- DateTime is not recognised in polars.DataFrame [#961].
- Support geom_spoke() in geom_livemap() [#988].
- NASA BlueMarble tiles have become blank [#1000].
- Line segments in geom_density2df() do not get interpolated when used with coord_polar() [#1037].
- arrow on segment: reduce arrow size for short segments [#1040].
- arrow on curve sometimes looks weird [#1041].
- livemap: when release the mouse button from outside the map, it gets stuck in panning mode [#1044].
- Improve documentation for parameter
position
[#1047]. - Error when build geom_smooth() with se=False [#1050].
- Livemap:
vjust
implemented incorrectly [#1051]. - Add tooltips for
geom_curve()
[#1053]. - Incorrect position for bar annotations when specifying
scale_x_reverse()/scale_y_reverse()
[#1057]. - Missing outer bar annotations when specifying
scale_x_reverse()/scale_y_reverse()
[#1058]. geom_density2d
: the doc missing some 'computed' variables [#1062].- Weird and problematic behavior : lets-plot does not respect x and y. Sizing problem ?[#1068].
- Plot layout breaks when marginal layers are used #1074 [#1074].
- Discrete scale doesn't work for datetime data [LPK-231].
- Add
linetype
parameter inelementLine()
andelementRect()
[LPK-235]. - Any way to line-wrap facet labels? [LPK-237].
- Missing marginal gridlines.
- Cryptic error message on geom_boxplot with orientation="y" [#600].
set_theme()
should accept "feature list" [#657].
-
coord_polar()
The polar coordinate system is most commonly used for pie charts, but
it can also be used for constructing Spider or Radar charts using theflat
option [#452].See: example notebook.
-
In the
theme()
function:-
panel_inset
parameter - primarily used for plots with polar coordinates.See: example notebook.
-
panel_border_ontop
parameter - enables the drawing of panel border on top of the plot geoms. -
panel_grid_ontop, panel_grid_ontop_x, panel_grid_ontop_y
parameters - enable the drawing of grid lines on top of the plot geoms.
-
-
geom_curve()
See: example notebook.
-
[UNIQUE] Visualizing graph-like data with
geom_segment()
andgeom_curve()
.-
Aesthetics
size_start, size_end, stroke_start
andstroke_end
enable better alignment of
segments/curves with nodes of the graph by considering the size of the nodes. -
The
spacer
parameter allows for additional manual fine-tuning.
See:
-
-
alpha_stroke
parameter ingeom_label()
to enable the applying ofalpha
tocolor
[#1029].See: example notebook.
-
Showing plots in external browser
The setup_show_ext() directive allows plots to be displayed in an external browser window.
- [BREAKING] Function
geom_image()
is removed. Please usegeom_imshow()
instead. - Parameter
axis_ontop
intheme()
is nowTrue
by default.
- coord_map() should distort tiles size to account for different unit size at different latitudes [#331].
- geom_errorbar(): wrong positioning of tooltips [#992].
- geom_path(): tooltip position interpolation [#855].
- Stacked bar-chart annotation: labels go out of the plot when zooming-in using coord_cartesian(xlim, ylim) [#981].
- Facets: "free scales" options are ignored by discrete axis [#955].
- Bar width is too large when x-domain is defined via x-scale limits [#1013].
- How to hide only main tooltip? [LPK-#232].
- Make middle strip in
geomCrossbar()
optional [LPK-233]. - Can't set None for coord limit [#486].
- Scale limits don't work for bars/area [LPK-219], [#978].
- No gridlines when axis_ontop=True [#1012].
- bar-plot: do not draw bar border adjacent to the axis [#845].
- Displaying tooltips on a multilayer plot [#1030].
- Make segment geometry better suited for graphs visualization [#572].
-
Support for
Categoricals
:- Support for
pandas.Categorical
data type [#914]. - The
levels
parameter inas_discrete()
function [#931].
See: example notebook.
- Support for
-
Support for superscript for numbers in scientific notation [#743].
Do NOT(!) use
exponent_format='pow'
if you are planning to export plot to a raster format (PNG,PDF).The
CairoSVG
library (which is under the hood of ourggsave()
function) does not handletspan
element properly and breaks superscript notation when transforming SVG to PNG/PDF.More details: Kozea/CairoSVG#317
See: example notebook.
-
Support exporting plot to a file-like object.
Convenience methods:to_svg()
,to_html()
,to_png()
,to_pdf()
[#885], [#590].See: example notebook.
-
Sharing of X,Y-scale limits between subplots in
gggrid()
[#718].See: example notebook.
-
geom_spoke()
[#738].See: example notebook.
-
scale_x_log2()
,scale_y_log2()
[#922]. -
High-contrast tileset "BW" for
geom_livemap()
.See: example notebook.
-
New variables computed by
'count'
and'count2d'
statistics:'..sumprop..'
,'..sumpct..'
[#936].See: example notebook.
-
Support using dictionaries for breaks/labels/values customization in
scale_xxx()
functions [#169], [#882].See: example notebook.
-
The
lablim
parameter inscale_xxx()
functions [#939, #946].See: example notebook.
-
label_text
parameter intheme()
for annotation text settings [#930].See: example notebook.
-
NumberFormat: new flag
~
to trim trailing zeros.
-
[BREAKING] Function
margin()
is deprecated and will be removed in future releases.
Please replace all existing usages, i.e.theme(plot_margin=margin(..))
andelement_text(margin=margin(..))
with a list or with just a number:- a number or list of one number - the same margin it applied to all four sides;
- a list of two numbers - the first margin applies to the top and bottom, the second - to the left and right;
- a list of three numbers - the first margin applies to the top, the second - to the right and left, the third - to the bottom;
- a list of four numbers - the margins are applied to the top, right, bottom and left in that order.
See: example notebook.
-
Upgraded Apache Batik to version 1.17 [#887]
- Jitter reproducibility in geom_jitter, position_jitter, position_jitterdodge [#911].
- Facets: order = 0 doesn't work as expected [#923].
- geom_livemap: fix missing styles (e.g. road outline on high zooms) [#926].
- geom_livemap: freeze at zoom 10 [#892].
- Enormous CPU / Time/ Memory consumption on some data [#932].
- gggrid: composite plot is not visible if saved with ggsave [#942].
- gggrid doesn't override global theme [#966].
scale_continuous()
fails with non-color aesthetics [#953].- NumberFormat:
g
format doesn't use e-notation for small numbers [#965]. - Tooltips: graphical artifacts and bad performance in multi-line plot in Batik [#967].
- Wrong tooltip position on
geom_segment()
with position adjustment [#963].
-
Annotations in Barchart
See: example notebook.
-
Common theme support in subplots (i.e.
gggrid()
) [LPK-#197].See: example notebook.
-
HCL
andCIELAB
color space for hue color scale and gradient color scales [#876].See: example notebook.
-
New scale transformations:
'log2'
and'symlog'
.See: example notebook.
-
plot_margin
parameter intheme()
[#856].See: example notebook.
-
Dual orientation for geometries:
geom_errorbar()
geom_crossbar()
geom_pointrange()
geom_linerange()
geom_ribbon()
See: example notebook.
-
Python 3.12 support [#907].
- [BREAKING]
stat_summary()
andstat_summary_bin
no longer supports computing of additional variables specified in mappings.
- Husl palette equivalent [#876].
- Tooltips are trimmed and not visible on a very narrow chart [#837].
geom_crossbar
: an error occurs if the mapped values of aesthetics are not populated [#886].- Exception label is unresizeble, uncopyable and uncontrollable [#902].
- Flickering during plot downsizing [#888].
- Bad default formatting of numeric values in annotations [#905].
- corr_plot: unexpected whitespace between the "geometry area" and the legend [#877].
- scale_log: an option to generate only breaks which are integer powers of 10 needed [#850].
- Trimmed legend when bounds of the rightmost X-axis tick label exceeds the axis length [#851].
- HTML files exported using ggsave() are missing the encoding specification [#900].
plot_margin
parameter intheme()
[#856].- Subplot themes not inherited by parent [LPK-#197].
- Saving plots in PDF format using ggsave() [#710].
element_blank()
has no effect on plot title/subtitle/caption intheme()
[#913].- Lollipop in legend is disproportionately large [LPK-216].
- geomBar with fill, produces tooltips artefacts [#895].
- Exception, when trying to build plot with column name containing line breakes [#894].
- Added "grey" spelling for the gray color (earlier - "gray" only).
-
plot_message
parameter intheme(...)
[#863].
See: example notebook. -
Add
geom_count()
/stat_sum()
[#821].
See: example notebook.
-
If layer transparency is set via the alpha-channel in the colors RGBA specification and via the
alpha
aesthetic,
then thealpha
aesthetic overrides the alpha-channel in the color. Previousely it was the opposite. -
geom_pie()
defaults:- "stroke" is visible and
stroke_side='both'
(wasstroke_side='outer'
). - the "hole" is not created automatically when
stroke_side = 'both'/'inner'
(was created automatically).
- "stroke" is visible and
-
geom_bar()
now has solid outline color by default (was transparent). -
geom_tile()
,geom_bin2d()
now have solid outline color by default (was transparent).- however, by default the
size
is 0 (i.e. tiles outline initially is not visible).
- however, by default the
geom_tile()
,geom_bin2d()
: thealpha
aesthetic is applied to the tiles outline.scale_x_datetime()
: error building plot for early dates [#346].geom_livemap()
: theme/flavor plot background is not shown [#857].geom_livemap()
: in AWT dragging a map in a facet moves maps in all facets.geom_livemap()
: support rectangle 'linetype' [#307].theme_void()
+flavor_xxx()
: no expected plot background [#858].- Inconsistent color in legend when using
paint_a/paint_b/paint_c
[#867].
-
Flavor-aware colors: pen, brush and paper
- By default, all geometries utilize new flavor-aware colors.
- Theme
geom
parameter allows redefinition of "geom colors":theme(geom=element_geom(pen, brush,paper))
.
See: example notebook.
-
stat_summary()
: example notebook. -
stat_summary_bin()
: example notebook. -
stat_ecdf()
: example notebook. -
geom_function()
: example notebook. -
theme_void()
[#830] : example notebook. -
"sum"
statistic [#821]: example notebook. -
"boxplot_outlier"
statistic: example notebook. -
Support for variadic line width and/or color in
geom_line()
andgeom_path()
[#313]. -
In tooltip customization API:
disable_splitting()
function [LPK-189]. -
In
geom_pie()
:stroke
andcolor
aesthetics - the width and color of pie sector arcs.stroke_side
parameter - which arcs to show (inner, outer, both).spacer_width
andspacer_color
parameters - lines between sectors.
See: example notebook.
size_unit
parameter : example notebook.
-
The default qualitative color palette is now Color Brewer "Set1" (was "Set2")
-
Geometries default colors are now flavor-dependent: example notebook.
-
Geometries default size/line-width is now slightly bigger.
-
Point size is adjusted to match the width of a line of the same "size".
-
[BREAKING]
geom_pie()
no longer supports parameterstroke_color
. -
[BREAKING]
geom_boxplot()
no longer support parametersampling
. -
[BREAKING]
geom_pointrange()
:size
aesthetic shouldn't affect line width [#751]:linewidth
aesthetic is used for line width,size
- for mid-point size only. -
geom_boxplot()
:size
andstroke
parameters now affect outlier shapes. -
[BREAKING, only affects users of Lets-Plot Kotlin API]
The entire project has undergone package refactoring.
As a result of package names changed, Lets-Plot v4.0.0 is partially incompatible
with Lets-Plot Kotlin API versions 4.4.1 and earlier.
ggsave()
doesn't save geom_raster() layer to a file [#778].ggsave()
: saving geomImshow() to SVG produces fuzzy picture [LPK-188].ggsave()
: saving geomImshow() to raster format produces fuzzy picture.geom_crossbar()
aesthetics takemiddle
argument instead ofy
[#804].geom_boxplot()
doesn't apply alpha to outliers [#754].geom_boxplot()
outliers do not show tooltips.geom_step()
no tooltips.geom_step()
: toggle the behavior of thedirection
parameter when the orientation is changed.geom_livemap()
: memory leak when re-run cells without reloading a page.geom_ribbon()
: not all tooltips are shown on a multi-layer plot [#847].- Bug in empty plot: IndexOutOfBoundsException [#194].
- Weird tooltip/legend in case of extremely long value [#315].
- panning on interactive map should be more responsive [#336].
- Offline mode doesn't work with manylinux wheels [#808].
-
geom_lollipop()
.See: example notebook.
-
Aesthetic
stroke
[#320] and its scalesscale_stroke()
,scale_stroke_identity()
.See: example notebook.
-
Aesthetic
linewidth
(forgeom_lollipop()
) and its scalesscale_linewidth()
,scale_linewidth_identity()
.See: example notebook.
-
The 'newline' character (
\n
) now works asline break
in legend text ([#726])See: example notebook.
-
Horizontal error bars and vertical "dodge" ([#735]).
See: example notebook.
-
Colorbar in
geom_imshow()
. Parametersshow_legend
andcolor_by
[#717].
-
[BREAKING]
geom_dotplot()
andgeom_ydotplot()
no longer support parameterstat
. -
Position adjustment settings:
width, height
parameters ofgeom_jitter()
have priority over thewidth, height
parameters ofposition_jitter()
function;nudge_x, nudge_y
parameters ofgeom_text(), geom_label()
have priority overx, y
parameters ofposition_nudge()
function.
-
geom_text(), geom_label()
usestat='identity'
by default. -
JVM/Batik: improved "paint manager" which now has better performance and fixes issues with artifacts that could appear beyond the plot component.
- Batik:
geom_imshow()
fail with an error: "The attribute "xlink:href" of the element is required" - Batik: bug with usage of "&" [#713].
- Categorical ordering, it's not respected for Boxplot and violin plot [#746].
- Groups not sorted similarly when using facets [#679].
- HTML export: exclude computation messages from the output [#725].
- Image export not working with
geom_imshow()
andgeom_raster()
[LPK-175]. geom_segment()
doesn't take into account the alpha [#748].geom_density2d
: Internal error with None values in data [#702].- DateTime metadata is not applied for scales other than X/Y [LPK-174].
- Quantile should be shown in tooltip if the variable
..quantile..
is mapped to geom aesthetic. - Bad default formatting for stat variables [#654].
- The scale name does not apply with
as_discrete()
[#653]. - Tooltip is not shown when configured for 'const' value [#610].
- Fix crash when try to add a constant to a tooltip (e.g.
"^size"
, wheresize
aesthetic is specified with a number). - "Variable not found" error in
ggmarginal
[#681]. facet_grid
: Internal error [#699].- Export to SVG fails if breaks are given by integers [#763].
- Remove hard IPython dependency [#749].
- Tooltips bug [LPK-176].
- livemap: doesn't work well with gggrid [#750].
- livemap: memory leak caused by a document event handler.
- livemap: flickering when zooming with the buttons.
- livemap: tooltip text doesn't reflect data under the cursor [#709].
-
gggrid()
function.See: example notebook.
-
joint_plot()
See: example notebook.
-
Export to PNG files in
ggsave()
.Note: export to PNG file requires the CairoSVG library.
See: example notebook.
-
Axis
position
parameter in position scalesscale_x_*(), scale_y_*()
.See: example notebook.
-
angle
parameter inelement_text()
intheme()
.See: example notebook.
-
Additional "color" aesthetics:
paint_a, paint_b, paint_c
.These aesthetics are flexible and can be used as either "color" or "fill" as needed. See Multiple Color Scales demo.
Also added a set of related "color scale" functions with the "aesthetic" parameter for configuring of additional color scales.
See New "Scale" Functions demo.
-
Drawing quantile lines and filling quantile areas in
geom_violin()
andgeom_density()
See: example notebook.
-
geodesic
parameter forgeom_segment()
andgeom_path()
.See: example notebook.
-
density2d
anddensity2df
geometry types inresidual_plot()
.
-
The
MinGW
toolchain is no longer required for installing ofLets-Plot
onWindows
. -
[BREAKING]
geom_violin()
no longer supports parameterdraw_quantiles
. Use newquantile_lines
andquantiles
parameters as needed. -
[BREAKING]
stack
andfill
position adjustments now stack objects on top of each other only if these objects belong to different groups. If necessary, usemode="all""
inposition_stack()
orposition_fill()
to stack objects regardless of their group.See: example notebook.
- Tooltip does not reflect
..quantile..
aesthetic change [#658]. color_by
parameter of theresidual_plot()
should group the data points [#662].- 'map_join': variable is lost after "stat" [#664].
- Error when tooltip has variable mapped to aesthetic used by stat [#665].
- Groups not sorted similarly when
position='stack'
[#673]. - Area ridges: fill overlaps geometry borders when colors are repeated [#674].
- livemap: hide tooltips when user is zooming-in by double-clicks [#659].
- livemap: wrong position when path goes through the antimeridian [#682].
- livemap: wrong position if path is on a circle of latitude [#683].
- livemap: tooltip may show wrong data on density2df [#684].
- livemap: geom_text vjust="center" is a bit off [#132].
- livemap: segment that goes through the antimeridian should be straight [#692].
- livemap: apply alpha to the pie chart and to its tooltip color marker.
- Layout: uneven plot margins for the horizontal axis [#705].
- Sampling: increase the default N for "pick sampling" and for other types of sampling [#687].
-
Python wheel for Python 3.11.
-
residual_plot()
.See: example notebook.
-
geom_area_ridges()
.See: example notebook.
-
geom_pie()
.See: example notebook.
-
Annotations for pie chart:
See: example notebook.
-
New variables computed by
'count'
and'count2d'
statistics:'..sum..'
,'..prop..'
,'..proppct..'
.See: example notebook.
-
Maps:
-
"Spatial pies" on interactive maps.
See: example notebook.
-
The
flat
parameter forgeom_path()
andgeom_segment()
(replaces the retiredgeodesic
parameter ingeom_livemap
).See: example notebook.
-
-
Static maps:
-
The value "provided" for
use_crs
parameter.See: example notebook.
-
-
geom_imshow()
:-
Improved performance by orders of magnitude.
-
Transparency of
NaN
values in grayscale images [#631]. See: example notebook. -
alpha
parameter [#630]. See: example notebook.
-
-
tails_cutoff
parameter ingeom_violin()
See: example notebook.
- [BREAKING] Dropped support for Python 3.6 as it is in the "end-of-life" of its release cycle.
- [BREAKING]
geom_livemap()
itself no longer draws geometries, so the following options are no longer supported:symbol
,data
,mapping
,map
,map_join
,ontop
,stat
,position
,show_legend
,sampling
,tooltips
. To draw point and pie markers on map, please, use thegeom_point()
andgeom_pie()
geometry layers. - Java/Swing platf.: Apache Batik upgraded to v.1.16 [#624], [LPK #140].
- The default size is increased for the plot title and decreased for the caption.
- Upgraded Kotlin version to 1.7.21 (was 1.7.20).
- Themes: can't change plot background after applying a "flavor" [#623].
- Layout: uneven left/right, top/bottom plot margins [#625].
- A plot building error with empty data on various geoms.
- Precision error in gradient [#634].
- geom_livemap: wrong position when datapoints geodesic line goes close to the N.P. [#645].
-
geom_text(), geom_label()
:- the 'newline' character (
\n
) now works asline break
([#605]) lineheight
aesthetic ([#324])nudge_x, nudge_y
parameters ([#324])- special text alignments (
vjust
andhjust
):"inward"
and"outward"
([#324])
See: example notebook.
- the 'newline' character (
-
vjust
parameter inposition_stack()
andposition_fill()
[#323].See: example notebook.
-
use_crs
parameter ingeom_map()
and other geoms, working withGeoDataFrame
See: example notebook.
-
geom_imshow()
(formergeom_image()
):-
extent
parameterSee: example notebook.
-
vmin, vmax, cmap
parametersSee: example notebook.
-
-
image_matrix()
:-
vmin, vmax, cmap
parametersSee: example notebook.
-
-
geom_image()
renamed togeom_imshow()
See updated examples: image 101, Fisher's boat.
-
geom_boxplot()
: default value for parameterwhisker_width
is 0.5. -
Upgraded Kotlin version to 1.7.20 (was 1.6.21).
- element_blank() has no effect in theme legend_title [#608].
geom_livemap()
: add support of geom_label parameters [#601].- Tooltip: different formats for same aesthetic Y [#579].
- Positioning with "constant" x/y doesn't work on axis with log10 transform [#618].
- Positional "constant" doesn't honor axis limits [#619].
- Parameter
norm
ingeom_imshow()
. - Several issues leading to crush in Swing/Batik apps. Related to [discussions]
- Text labels got trimmed occasionally, when symbols
-
,/
,\
or|
present. geom_livemap()
doesn't load vector tiles insideiframe
with certain security policies.
-
New theme:
theme_bw()
[#554].See: example notebook.
-
Color schemes (flavors) applicable to existing themes:
flavor_darcula()
flavor_solarized_light()
flavor_solarized_dark()
flavor_high_contrast_light()
flavor_high_contrast_dark()
See: example notebook.
-
Viridis color scales:
scale_color_viridis()
,scale_fill_viridis()
.See: example notebook.
-
New parameters in
element_text()
[#562]:size, family
(example notebook)hjust, vjust
for plot title, subtitle, caption, legend and axis titles (example notebook)margin
for plot title, subtitle, caption, axis titles and tick labels (example notebook)
-
The 'newline' character (
\n
) now works asline break
in axis title.See: example notebook.
-
Parameter
whisker_width
ingeom_boxplot()
[#549].See: example notebook.
-
New geometry
geom_label()
[#557].See: example notebook.
-
Auto-detection of Databricks and NextJournal environments [#602].
-
Python wheels for manylinux arm64 architecture [#581].
-
New tooltip style after applying
coord_flip()
[#580].See: example notebook.
-
In Lets-Plot for Java/Swing, Apache Batik upgraded to v.1.15 [#604]
- Density and area geoms: preserve the z-order when grouping [#552].
- Allow to import all 'bistro' functions just by '*' [#551].
- Boxplot, violin, crossbar: position dodge width=0.95 should be used by default [#553].
- Tooltip is shown not for the nearest object [#574].
- Tooltip is not displayed for the object on the plots border [#575].
- The plot caption overlaps with the legend [#587].
- Unclear size unit of width [#589].
- Specify size units in docstrings [#597].
- No tooltips for geom_boxplot with zero height [#563].
- geom_text: wrong label alignment with
hjust
0 and 1 [#592]. - Error when using lets-plot in streamlit [#595].
- Documentation for the
breaks
parameter in scales [#507].
-
Python 3.10 support [#505].
-
Python 3.9: a Python wheel for macOS arm64 architecture (Apple Silicon).
-
LetsPlot.set_theme()
- configuring a default plot theme.See: example notebook.
-
Quantile-Quantile (Q-Q) plot:
- geometries:
geom_qq()
geom_qq_line()
geom_qq2()
geom_qq2_line()
- quick Q-Q : the
qq_plot()
function in thebistro
module.
See: example notebook.
- geometries:
-
Marginal plots: the
ggmarginal()
function [#200], [#384].See: example notebook.
-
Parameter
orientation
in geoms:bar, boxplot, density, histogram, freqpoly, smooth, violin
.See: example notebook.
-
New in plot theme:
-
face
parameter inelement_text()
.See: example notebook.
-
panel_border
parameter intheme()
[#542].See: example notebook.
-
Tooltip theme options, new parameters in
theme()
:tooltip
- tooltip rectangle options;tooltip_text, tooltip_title_text
- tooltip text options;axis_tooltip_text, axis_tooltip_text_x, axis_tooltip_text_y
- axis tooltip text options.
See: example notebook.
-
-
scale_color_gradientn()
andscale_fill_gradientn()
functions [#504].See: example notebook.
geom_livemap
[breaking change] :symbol="point"
now should be specified explicitly to enable the "livemap" layer to handle provided "point" aesthetics directly. This change doesn't affect "points" layers added via thegeom_point()
geometry layer.- New style of tooltip color marker (two sidebars with a stroke color) and symbols in legend (rectangle with a stroke instead of a slash-line).
- New type of general tooltip for
geom_boxplot
: displayed under the cursor. - Default sampling type for
geom_violin
switched fromsystematic
topick
.
geom_livemap
: support of thearrow
parameter ingeom_segment
[#131].- Differences in tooltip color marker for plots with and without livemap.
- Labels out of plot when axis_text_y='blank' [#525].
- NPE in corr_plot with null coefficients.
- Outliers are not shown when boxplot' alpha=0.
- Support for polars.DataFrame [#526].
- JFX rendering issue that causes tooltips to stuck [#539].
- Support trim parameter in density and ydensity stats [#62].
- Unexpected point geometries on geom_livemap() [#547].
geom_violin
: add missing parameterskernel
,bw
,adjust
,n
,fs_max
to signature and docstring.
-
Plot subtitle and caption [#417]:
subtitle
parameter inggtitle()
andlabs()
,caption
parameter inlabs()
,plot_subtitle
andplot_caption
parameters intheme()
.See: example notebook.
-
The 'newline' character (
\n
) now works asline break
in plot title, subtitle, caption and in legend title.See: example notebook.
-
New in tooltip customization API:
- The
title()
option defines a tooltip "title" text which will always appear above the rest of the tooltip content. - The 'newline' character (
\n
) now works asline break
in tooltips. - Automatic word wrap: occurs when the length of a text value in tooltip exceeds the 30 characters limit.
See: example notebook.
- The
-
Parameter
scales
infacet_grid()/facet_wrap()
[#451, #479].See: example notebook.
-
New in
geom_livemap()
:- The
Reset
button: returns the map widget to its initial zoom/location state. - Parameters
data_size_zoomin, const_size_zoomin
: allow configuring how zooming-in of the map widget increases size of geometry objects (circles, lines etc.) on map. - Parameter
ontop
that controls z-index of thegeom_livemap
layer. - Parameter
show_coord_pick_tools
to show "copy location" and "draw geometry" buttons.
- The
-
New geometries:
geom_violin()
See: example notebook.
geom_dotplot()
See: example notebook.
geom_ydotplot()
See: example notebook.
- New tooltip style: rounded corners, bold label, colored marker inside the tooltip.
- Deprecated tooltip customization API:
function
color()
will be removed in one of the future releases. - 'Auto shrink': plots automatically shrink when necessary to fit width of the output (notebook) cell [#488].
- LiveMap, Swing-batik: legend is not visible when overlapping map [#496].
- CVE-2021-23792 in org.jetbrains.lets-plot:[email protected] [#497].
- Color in tooltip does not correspond to the color of marker on map [#227].
- tooltip on livemap: hide tooltip when the cursor is over the controls [#335].
- Automatic detection of DateTime series [#99].
- Fix tooltips for
geom_histogram(stat='density')
. - The axis tooltip overlaps the general tooltip [#515].
- The multi-layer tooltip detection strategy will only be used if more than one layer provides tooltips.
- scaleColorManual Divide by Zero with 1 mapping [#506].
- LinearBreaksHelper$Companion.computeNiceBreaks out of memory error [#105].
-
scale_x_time()
andscale_y_time()
[#468].See: example notebook.
-
plot_background, legend_background
parameters intheme()
[#485]. -
axis_ontop, axis_ontop_x, axis_ontop_y
parameters intheme()
- Coord system limits do not work with x/y scale with transform [#474].
- Provide 0-23 hour formatting [#469].
- No tooltip shown when I'm trying to add an empty line [#382].
coord_fixed()
should adjust dimensions of "geom" panel accordingly [#478].- The tooltip dependence on number of factors works separately by layers [#481].
- Tooltip on y-axis looks wrong [#393].
- Is kotlin-reflect really needed for lets-plot? [#471].
-
coord_flip()
.See: example notebook.
-
Date-time formatting support:
- tooltip format() should understand date-time format pattern [#387];
- scale_x_datetime should apply date-time formatting to the breaks [#392].
See: example notebook.
-
Pre-configured themes:
- Standard ggplot2 themes:
theme_grey(), theme_light(), theme_classic(), theme_minimal()
; - Other themes:
theme_minimal2()
- the default theme,theme_none()
.
- Standard ggplot2 themes:
-
Theme modification: more parameters were added to the
theme()
function.See: example notebook.
Note: fonts size, family and face still can not be configured.
corr_plot()
function now also accepts pre-computed correlation coefficients. I.e. the following two expressions are equivalent:
corr_plot(iris_df).points().labels().build()
corr_plot(iris_df.corr()).points().labels().build() # new
- The size of fonts on plot was slightly increased all across the board.
- The default plot size was increased by 20%, it's now 600x400 px.
- Deprecated API:
stat_corr()
and "correlation stat" will be removed in one of the future releases. Please use thecorr_plot()
plot builder object instead.
- Ordering facets - the "order" value 0 disables facet ordering [#454].
- Tooltips for discrete variables: add the dependence of the tooltip on the number of factors. The X-axis tooltip is always shown for discrete data.
- map_join doesn't work when join variables with same names without mappings [#428].
- Zoom without clipping breaks tooltips [#373].
- Unreadable breaks on axis [#430].
- Map rendering is broken when browser uses scaling [#450].
- corr_plot() error for data with zero variation [#329].
- Misleading error message [#271].
-
Ordering categories. New parameters in the
as_discrete
function:order_by
(string) - the name of the variable by which the ordering will be performed;order
(int) - the ordering direction - 1 for ascending direction and -1 for descending (default value).
See: as_discrete.
-
Basemap tiles configuring:
- Subdomains parameter
{s}
for XYZ raster tiles. - Solid color tiles:
maptiles_solid()
. - Builtin configurations for some 3rd party maptile services. The
lets_plot.tilesets
module.
- Subdomains parameter
- Upgraded Apach Batik version to 1.14 (was 1.12) [#398].
- Upgraded Kotlin version to 1.5.21 (was 1.4.21)
- Upgraded Gradle version to 7.1.1 (was 6.8.3)
- geom_livemap: properly handle
max_zoom
pamareter inmaptiles_zxy()
. - Strange looking legend for tiles [#245].
- Need to skip "bad" values during scale transformation [#301].
- NPE on negative value in data and scale_xxx(trans='log10') [#292].
- Legend is broken when using scale_fill_brewer with 'trans' parameter [#284].
- Scale breaks should be distributed evenly on 'sqrt' scale. [#407].
- Wrong tooltip formatting when used with log10 scales [#406].
- Bad axis labels when using both plot and layer data [#327].
- Plot layout looks wrong [#403].
- map_join is not working correctly when
map=geocoder
[#380] - Tooltip default formatting should not change after adding other variables to tooltip [#388].
- Tooltip on axis: increase the font size. [#399].
- Tooltip format for variable is not working [#401].
- Wrong direction in colorbars (legend) [#204].
- geom_jitter: show axis tooltips (same as geom_point) [#412].
- Outlier tooltips: the spout sometime is too long (boxplot) [#358].
- Faceted plot is broken by geom with "constant" aesthetics [#391].
- Interactive maps in AWT (PyCharm plugin):
- Memory leaks in PyCharm caused by
dispose()
method in PlotPanel. - While showing map in PyCharm CPU is busy all the time, even when nothing is changing on screen.
- Click events detection.
- Memory leaks in PyCharm caused by
- Upgraded
kotlinx.html
version to 0.7.3 (was 0.7.2)
In JVM projects it's no longer necessary to add
https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven
repository to the project configuration.
- Multilayer plots are corrupted [#385].
- In tooltip customization API:
layer_tooltips(variables)
- the new parametervariables
defines a list of variable names, which values will be placed line by line in the general tooltip. See: Tooltip Customization.
- CDN: Lets-Plot JavaScript library is now served via JSDELIVR (was CDNJS):
https://cdn.jsdelivr.net/gh/JetBrains/[email protected]/js-package/distr/lets-plot.min.js
- Removed the last dependency on bintray JCenter (commit).
- geom_boxplot: should be possible to create boxplot without specifying x-series [#325]
- geom_hline: graph plotted outside of coordinate plane visible part [#334]
- Draw geometry only once if layer has no aes mapping specified [#73]
- map: calif.housing [#140]
- Can't build plot: "Uncaught SyntaxError: Unexpected string" in a console [#371]
- All scales should have the 'format' parameter [#347].
- Poor font rendering in Swing/Batik. Related to: [#364]
- Exclude slf4j implementation from lets-plot-common [#374]
- Due to shutting down of Bintray, JCenter:
- The Lets-Plot JS library is now delivered via CDNJS.
- JVM Maven artifacts are now published at Maven Central.
- The
alpha
parameter for lines [#139]. - Tooltips for
geom_segment()
[#296]. - The
guides()
function [#52]. - New Java Swing plot components to enable embedding Lets-Plot charts into JVM applications.
- See:
vis-swing-common, vis-swing-batik, vis-swing-jfx
modules.
- See:
- Fix auto-detection of PyCharm env to enable plotting in SciView while using remote interpreter [348]
- Fix tooltips appearing outside the specified x/y limits.
- Clippath in accordance to the given limits [#189].
- Treat a data as DataFrame if both data and map are GeoDataFrames [#343].
- Removed the restriction on tooltips for small polygons [#298].
- The x/y axis labels are derived from x/y aesthetics only [#333].
- Merge 'theme' settings [#147].
- Add axis tooltips for
geom_bin2d
. - Outlier tooltips for
geom_ribbon()
. - Fix tooltip crosshair [#309].
-
Python 3.9 support on all platforms.
-
facet_wrap()
function [#238] -
In facets:
- Ascending/descending ordering of faceting values.
- Formatting of faceting values.
See: Facets demo
-
In tooltip customization API:
- option
color
overrides the default tooltip color:geom_xxx(tooltips=layer_tooltips().color('red'))
See: Tooltip Customization.
- option
-
Crosshair cursor when tooltip is in fixed position specified by the
anchor
option. -
Scale
format
parameter: formatting tick labels on X/Y axis. Supported types arenumber
anddate/time
.Example:
scale_x_datetime(format="%b %Y") scale_x_continuous(format='is {.2f}')
Demo: Formatting demo
See also: Formatting
-
[breaking change] New Geocoding API!
Since Lets-Plot v2.0.0 the peviouse Geocoding API is no longer working (hence we bumped the version to 2.0.0).
The old version of the Geocoding backend remains on-line for a couple of release cycles to continue support of prior versions of Lets-Plot.
To learn more about Geocoding API see: Geocoding.
-
The project upgraded to Kotlin v1.4.21 (was v1.4.10).
- Kernel density estimate computation is too slow.
- Serialize NaN and other special values as None (CRITICAL for the "Lets-Plot in SciView" PyCharm plugin) [#282].
- Error in plot building: 'trans' parameter not compatible with None values in data [#287].
- LOESS smoothing fails on small (<3) number points.
- Facet grid truncated in jupyter [#28].
- The
reverse
parameter on discrete scale with 'limits' [#303]. - Geocoder's
allow_ambiguous()
doesn't prevent "ValueError: Multiple objects.." [#174]. - Fix tooltip for overlapping objects [#230].
- Fix duplicate values in tooltip [#280].
- geom_histogram should not try to handle geometries in GeoDataFrame [#281].
- Error building plot: Layer 'MAP' is not supported on Live Map. [#285].
- Align title to the left of the plot geom area [#289].
- Tooltip on
geom_ribbon()
.
- “Symbol not found: _NSGenericException” error on macOS [#276].
-
Correlation plot.
See: Charts.
-
'No Javascript' mode.
Support for notebook renderers that don't execute Javascript.
See: 'No Javascript' mode
-
In tooltip customization API:
- options:
center
andmiddle
(anchor). - option 'minWidth'.
See: Tooltip Customization.
- options:
-
'na_text' parameter in 'geom_text'
-
Tooltip customization API:
- The
anchor
option moved fromtheme
tolayer
:wheregeom_xxx(tooltips=layer_tooltips().anchor(anchor_value))
anchor_value
:['top_right'|'top_center'|'top_left'|'bottom_right'|'bottom_center'|'bottom_left'|'middle_right'|'middle_center'|'middle_left']
.
See: Tooltip Customization.
- The
- Tooltip should appear when the mapped data is continuous [#241]
- Tooltip 'null' displayed for undefined vals [#243]
- Y-tooltip should be aligned with a tile center [#246]
- With
facet_grid
tooltip shows data from last plot on all plots [#247]
- [breaking change] In functions
format(field, format)
andline(template)
in tooltip builder, the '$' symbol is no longer used in aesthetic reference. It was replaced by the '^' (hat) symbol (see the udated doc: Tooltip Customization). - The project upgraded to Kotlin v1.4.10 (was v1.3.72).
- No tooltip on v-line [#229]
- Facilities for customization of tooltip contents and its position (see Tooltip Customization).
attribution
and other new parameters in themaptiles_zxy()
function.label_format
parameter in thegeom_text()
function.scale_x_discrete_reversed()
/scale_y_discrete_reversed()
ggsave()
function (only SVG, HTML)
- Mercator's projection computes coordinates incorrectly (
geom_map(), coord_map()
) - Handling of
xlim,ylim
incoord_fixed(), coord_map()
- Colorbars: take in account limits defined in continuous color/fill scales.
scale_color_hue
incorrectly interprets chroma range [#206].scale_color_brewer
shouldn't fail if 'type' is not specified [#203].scale_fill_discrete
should not replace the default discrete scale (Brewer) with 'HUE' scale [#172].
- Lets-plot vector map-tiles are configured by default.
- PACIFIC_BLUE color (#118ED8) replaced DARK_BLUE as a default color/fill value on plots.
- Default discrete color scheme is now ColorBrewer's Set2 (was Dark2)
-
Function
gg_image_matrix()
. The new function is:image_matrix()
in thelets_plot.bistro.im
module. The new function is not any longer displaying matrix by itself but returns a GGBunch object instead. Unlike the depricatedgg_image_matrix()
function, it is not imported byfrom lets_plot import *
statement.Usage:
from lets_plot.bistro.im import image_matrix image_matrix()
- map_titanic.ipynb : UnboundLocalError: local variable 'map_join' referenced before assignment [#182]
- Add the
map_join
parameter to all geoms which supportmap
parameter (py) [#183]
- scale_x_reverse() / scale_y_reverse()
- Mnemonics for the
resolution
parameter in theregions.boundaries()
function.
- Exception when using
coord_map
withxlim
[#173] - Clipped tooltip [#155]
- Text on axis is clipped after hiding the tick-marks in theme [#160]
- Tooltip on x axis with no title shouldn't be above the axis line [#161]
- NPE while creating scale mapper when data series contains only nulls.
- Default Geocoding server url.
- geocoding package
- NPE on geom_tile when data contains null-s.
- The order of values in the
limits
parameter on discrete scales is ignored. - Livemap is not shown in GGBunch.
- Plugin for IntelliJ IDEA / PyCharm is available. For more info see the plugin homepage: Lets-Plot in SciView.
- Plots build time reduced (up to 4X)
geom_smooth
: automatic sampling when n>1000 and the method is LOESS.
- 'map_join' fails when the
map
argument is a dictionary [#130]
- HTML output was modified allow better integration with PyCharm.
- The deprecated method 'load_lets_plot_js()'.
- Support for interactive maps.
- The
as_discrete()
function. - Polynomial regression of an arbitrary degree (the
lm
smoothing method) in geom_smooth. axis_tooltip
,axis_tooltip_x
,axis_tooltip_y
parameters intheme()
- Kaggle and Datalore notebook demos.
- Severe performance degradation when using discrete scales [#119].
- Opaque background to better support PyCharm dark theme [#121].
- Auto-detection of a Kaggle environment.
- Limits on the maximum plot size [#115].
- Installation instructions for Windows users [#118 MinGW].
- More slick shape for tooltips on the axis.
- Python 3.6 support.
- Windows platform support.
- SVG/HTML export to file.
- Offline mode for Jupyter notebooks.
- Support for cloud-based notebooks like Google Colab and Datalore.
- JVM Maven artefacts released.
- Tooltip on
geom_rect
andgeom_vline
. - Error when date-time series contains
NaT
value.
- Optional
load_lets_plot_js()
function is now deprecated. - Initialisation call
LetsPlot.setup_html()
is now mandatory in Jupyter.
- tooltip not showing in geom_polygon
- geopandas support in geoms: point, path, polygon, rect, text.
- support for LOESS smoothing method in geom_smooth.
- new geometry layers: geom_crossbar, geom_linerange, geom_pointrange, geom_bin2d.
- support for coordinate stystem xlim, ylim parameters (i.e. "clipping").
- Was not working
weight
parameter in stats: bin, count, bin2d, density, density2d - incorrect tooltip line 'NaN' in geom_boxplot.
- ambiguous tooltip positioning in geoms: tile, bin2d.
- cropped text in tooltip.
- GGBunch. Combines several different plots into one graphical object.
- geom_image(). Displays an image specified by ndarray with shape (n,m) or (n,m,3) or (n,m,4).
- gg_image_matrix(). A utility helping to combine several images into one graphical object.
- user_guide.ipynb
- ggbunch.ipynb
- scatter_matrix.ipynb
- image_101.ipynb
- image_fisher_boat.ipynb
- image_matrix.ipynb
- Switched to Kotlin 1.3.61
- scale_datetime(). Date-time formatting in tooltips.
- Links in README_PYTHON.md
- First public release.