It contains the major improvements for NeuralNet
standard package, provides more features for graphics and insets. We also fixed many bugs in wljs-export-html
and in WXF deserializer. New examples are available in Animation
folder.
const balloonContainer = document.getElementById("balloon-container"); function random(num) { return Math.floor(Math.random() * num); } function getRandomStyles() { var r = random(255); var g = random(255); var b = random(255); var mt = random(200); var ml = random(50); var dur = random(5) + 5; return ` background-color: rgba(${r},${g},${b},0.7); color: rgba(${r},${g},${b},0.7); box-shadow: inset -7px -3px 10px rgba(${r - 10},${g - 10},${b - 10},0.7); margin: ${mt}px 0 0 ${ml}px; animation: float ${dur}s ease-in infinite `; } function createBalloons(num) { for (var i = num; i > 0; i--) { var balloon = document.createElement("div"); balloon.className = "balloon"; balloon.style.cssText = getRandomStyles(); balloonContainer.append(balloon); } } function removeBalloons() { balloonContainer.style.opacity = 0; setTimeout(() => { balloonContainer.remove() }, 500) } createBalloons(10); setTimeout(removeBalloons, 15000); return '';
Inset
An update for Inset
expression
Now you can put any expression on top of your Graphics
object. Please, make sure this expression supports WLJS Execution Enveroment (see top line of reference
)
For example
Plot[x, {x,0,10}, Epilog->{Inset[EditorView["(*FB[*)((1)(*,*)/(*,*)(2))(*]FB*)"], {3,5}, {10,30}, {1,3}]}]
(*VB[*)(FrontEndRef["3ca22e97-4a4d-4068-b58a-dc793fdfd51b"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKGycnGhmlWprrmiSapOiaGJhZ6CaZWiTqpiSbWxqnpaSlmBomAQCF1hYI"*)(*]VB*)
Or even put a mermaid diagram using virtual cells
mermaid = CellView["graph LR A[Square Rect] -- Link text --> B((Circle)) A --> C(Round Rect) B --> D{Rhombus} C --> D", "Display"->"mermaid"]; Plot[x, {x,0,10}, Epilog->{Inset[mermaid, {2,5}, {10,30}, {7,4}]}]
(*VB[*)(FrontEndRef["a0bb8b0e-c9e3-4c62-8ce0-b72f9844cf6f"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKJxokJVkkGaTqJlumGuuaJJsZ6VokpxroJpkbpVlamJgkp5mlAQCR6BY5"*)(*]VB*)
Slides now supports scripts
All inline JS scripts provided in slide cells will be executed. Use them for whatever ideas you come up with.
Tube now supports dynamics
3D graphics primitive Tube
now can be coupled to a dynamic symbol, as an example check this out 😉
(*BB[*)(* Just run this cell *)(*,*)(*"1:eJxTTMoPSmNhYGAo5gcSAUX5ZZkpqSn+BSWZ+XnFaYwgCS4g4Zyfm5uaV+KUXxEMUqxsbm6exgSSBPGCSnNSg9mAjOCSosy8dLBYSFFpKpoKkDkeqYkpEFXBILO1sCgJSczMQVYCAOFrJEU="*)(*]BB*) RandomIntegerVectorWithinBox[min_List, max_List] := Table[ RandomInteger[{min[[i]], max[[i]]}], {i, Length[min]} ] PositionKey[pos_] := ToString[pos] WithinBoundsQ[pos_, gridMin_, gridMax_] := And @@ Thread[pos >= gridMin] && And @@ Thread[pos <= gridMax] IsUnoccupied[pos_, occupiedPositions_] := ! KeyExistsQ[occupiedPositions, PositionKey[pos]] (* Main function to simulate a pipe *) SimulatePipe[] := Module[ { gridMin = {-10, -10, -10}, gridMax = {10, 10, 10}, occupiedPositions = <||>, currentPosition, positions, lastPosition, lastDirectionVector = Null, directionVector, newPosition, axis, dir, possibleDirections, triedDirections, moveMade }, (* Initialize the starting position *) currentPosition = RandomIntegerVectorWithinBox[gridMin, gridMax]; positions = {currentPosition}; occupiedPositions[PositionKey[currentPosition]] = True; (* Simulate the pipe growth *) Function[Null, (* Initialize possible directions *) possibleDirections = { {1, 0, 0}, {-1, 0, 0}, {0, 1, 0}, {0, -1, 0}, {0, 0, 1}, {0, 0, -1} }; (* Prioritize continuing in the same direction *) If[lastDirectionVector =!= Null && RandomReal[] < 0.5, (* Try to continue in the same direction *) directionVector = lastDirectionVector; possibleDirections = Prepend[DeleteCases[possibleDirections, directionVector], directionVector];, (* Shuffle possible directions *) possibleDirections = RandomSample[possibleDirections]; ]; triedDirections = {}; moveMade = False; (* Try each possible direction *) Do[ directionVector = dir; newPosition = currentPosition + directionVector; If[ WithinBoundsQ[newPosition, gridMin, gridMax] && IsUnoccupied[newPosition, occupiedPositions], (* Valid move found *) positions = Append[positions, newPosition]; occupiedPositions[PositionKey[newPosition]] = True; lastDirectionVector = directionVector; currentPosition = newPosition; moveMade = True; Break[]; ]; AppendTo[triedDirections, dir]; , {dir, possibleDirections} ]; If[!moveMade, (* No valid moves, terminate simulation *) $Failed , positions ] ] ] With[{ frame = CreateUUID[], win = CurrentWindow[] }, Module[{ pipeFunction = Function[Null, $Failed], pipesNumber = 0, trigger = 1 }, EventHandler[frame, Function[Null, With[{ result = pipeFunction[] }, If[FailureQ[result], With[{ segments = Unique["pipe"], generator = SimulatePipe[] }, pipesNumber++; pipeFunction = Function[Null, With[{seg = generator[]}, If[FailureQ[seg], $Failed , segments = seg // N; ] ] ]; pipeFunction[]; FrontSubmit[{ ColorData[97][pipesNumber], Tube[segments // Offload, 0.2] }, MetaMarker[marker], "Window"->win]; ] ] ]; trigger++; ]]; Graphics3D[{ Opacity[0], Cuboid[{-4,-4,-4}, {4,4,4}], Opacity[1], MetaMarker[marker], AnimationFrameListener[trigger // Offload, "Event"->frame] }] ] ]
Neural Networks
We have finally added partial support for NeuralNet
package. You can see training progress, representations of different layers and etc
(*BB[*)(* try this one *)(*,*)(*"1:eJxTTMoPSmNhYGAo5gcSAUX5ZZkpqSn+BSWZ+XnFaYwgCS4g4Zyfm5uaV+KUXxEMUqxsbm6exgSSBPGCSnNSg9mAjOCSosy8dLBYSFFpKpoKkDkeqYkpEFXBILO1sCgJSczMQVYCAOFrJEU="*)(*]BB*) trained = NetTrain[LinearLayer[], {1 -> 1.9, 2 -> 4.1, 3 -> 6.0, 4 -> 8.1}]
trained[3]
6.04994535446167`
NetGraph
is not supported as well as some icons. We need volunteers to work on it ;) Please contact us if you know something about ML and Wolfram Language Graphics
.
net = NetModel["LeNet Trained on MNIST Data"]
(*VB[*)temporalStorage$145507(*,*)(*"1:eJwlkc1ymlAAhWmni06foslKoTNC0AvpTBb8KgISufyImSxALoLgRZErwmP0iWPSzTdnzu585yGp3ew7RVGXX3doadHWTVCgDv77RlEr1Cp5XOC3ER3Ib/T494j+Q49H9CP3Fy17rvQ566ZJdk6um7WriUoLxCQik3UiN2Ta6FZ13RZd4XhW7QwKhB5GfPrKX71DyxiZX6BFiWcaRrmNT5rImwKUjHNhYx/EVVmogw4uxpk3sdSnTlSd8c1JbvsK76Wj6857Z7pDVQ+APdv6ZlIvu6ZtNusF6QCBRsswSqhZAjzG58uC58VkZwqi4Os2hzrzGu3mg2jlicB2WllUcENAUg1zNvQYdWo+8VubKG6aghbXe51Z+GHiuRAxcbpayblEOCNQHe1UBvF0rlmT7el2jiBrH4+Ruc6k7HblUajLp0OQC7PVQV0aM2UC7tPDmMuP5kRhVWNZZumzUwrNRc+a5wS4kzBXeqDrd0mS8loP04jHrck+7V9eHj+dvwcyPX7/f9WPO1xSIfjzM6A4dXDVf7VeQ9AH8nGRcw=="*)(*]VB*)
net[(*VB[*)(FrontEndRef["7c52eb9d-6d46-4b1d-ab0a-a2043d2ccccc"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKmyebGqUmWabomqWYmOmaJBmm6CYmGSTqJhoZmBinGCWDAACODxZ6"*)(*]VB*)]
5
ok, kinda looks like 5
Some other examples
layer = NetInitialize @ LinearLayer[2, "Input" -> 2]
LinearLayer[(*VB[*) <|"Type" -> "Linear", "Arrays" -> <|"Weights" -> NumericArray[{{-0.3594474792480469, -0.04992305114865303}, {-1.127055048942566, 1.086535930633545}}, "Real32"], "Biases" -> NumericArray[{0., 0.}, "Real32"]|>, "Parameters" -> <|"OutputDimensions" -> {2}, "$OutputSize" -> 2, "$InputSize" -> 2, "$InputDimensions" -> {2}|>, "Inputs" -> <|"Input" -> NeuralNetworks`TensorT[{2}, NeuralNetworks`AtomT]|>, "Outputs" -> <|"Output" -> NeuralNetworks`TensorT[{2}, NeuralNetworks`RealT]|>|>, <|"Version" -> "14.1.2", "Unstable" -> False|> (*,*)(*"1:eJytUMsKwjAQrI+LXgQ9CJ7qL3j0ptBiQSy00rORbCWQbGSboEX8d9NUqVfBy7A7M8sMuzzrrBwEQVAtHGz1PdakThsihhfguVWKUe3ostd4Jg5i0mgi5IUgY5lshaGDnZbcDweNUPY/9F5UpjP5zWvzr7x3TmJAFQJu+cxpqTVXa0IuFGAlNFbrsD0cO4i4MJq8tyn/WD27wMxKyEfNAIzXKcra00ey8GuPqdMS/HuN9ktWyhcQzmJg"*)(*]VB*)]
NetExtract[LinearLayer[(*VB[*) <|"Type" -> "Linear", "Arrays" -> <|"Weights" -> NumericArray[{{-0.3594474792480469, -0.04992305114865303}, {-1.127055048942566, 1.086535930633545}}, "Real32"], "Biases" -> NumericArray[{0., 0.}, "Real32"]|>, "Parameters" -> <|"OutputDimensions" -> {2}, "$OutputSize" -> 2, "$InputSize" -> 2, "$InputDimensions" -> {2}|>, "Inputs" -> <|"Input" -> NeuralNetworks`TensorT[{2}, NeuralNetworks`AtomT]|>, "Outputs" -> <|"Output" -> NeuralNetworks`TensorT[{2}, NeuralNetworks`RealT]|>|>, <|"Version" -> "14.1.2", "Unstable" -> False|> (*,*)(*"1:eJytUMsKwjAQrI+LXgQ9CJ7qL3j0ptBiQSy00rORbCWQbGSboEX8d9NUqVfBy7A7M8sMuzzrrBwEQVAtHGz1PdakThsihhfguVWKUe3ostd4Jg5i0mgi5IUgY5lshaGDnZbcDweNUPY/9F5UpjP5zWvzr7x3TmJAFQJu+cxpqTVXa0IuFGAlNFbrsD0cO4i4MJq8tyn/WD27wMxKyEfNAIzXKcra00ey8GuPqdMS/HuN9ktWyhcQzmJg"*)(*]VB*)], "Weights"] // Normal
{{-0.3594474792480469`,-0.04992305114865303`},{-1.127055048942566`,1.086535930633545`}}
Support for custom CSS
Open your settings and add any styles you want. This is a new step towards customization
Print now supports formatted output
Try this one
Print[Style["Hey", Red, 14]]
(*BB[*)("Hey")(*,*)(*"1:eJxTTMoPSmNiYGAo5gcSAUX5ZZkpqSn+BSWZ+XnFaYwgCRYg4ZGfkwJRxgkkgkuKMvPSnfIr0phBQhxAIsjdyTk/J78oE6QlkwFO8AEJiEaQMUGlOanBbHATwGIhRaWpAL9wHBA="*)(*]BB*)
You can also print Graphics
if needed
Offset support for labels
It was always a bit of a pain to fight agains FrameLabel
or AxesLabel
and trying to position them. We extended the API for this (Mathematica does not have this feature)
Plot[PDF[NormalDistribution[0, 1], x], {x, -10, 10}, AxesLabel -> { {"wavenumber (cm^{-1})", {-100,-15}}, {"absorption \\alpha", {112,0}} }, PlotRange->Full]
(*VB[*)(FrontEndRef["257a6bab-bb74-4016-b624-a40b453a2e63"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKG5maJ5olJSbpJiWZm+iaGBia6SaZGZnoJpoYJJmYGicapZoZAwCDIRVZ"*)(*]VB*)
Support for Entity
and Quantity
We recreated boxes for them
Quantity[1, "Millimeters"/"Seconds"]
(*VB[*)(q)(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KWlMIB43kAgsTcwrySypdMqvyAQpgciwAomQzNzU4mCQGt/MnBwgpyS1qBghHZBfnloUzA5kBacm5+elFGf+BwIA5ecbxA=="*)(*]VB*)
Entity["Country", "Germany"]
(*VB[*)(Entity["Country", "Germany"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KWlMIB4nkHDNK8ksqXTKrwhmB/Kc80vzSooqwWz31KLcxLxKAJLGDq8="*)(*]VB*)
%["Population"]
(*VB[*)(q)(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KWlMIB43kAgsTcwrySypdMqvyFzA950lmA0oGJCaX5CTCgBVHw3o"*)(*]VB*)
Support for SystemOpen
Works only if use our desktop application (not a console version)
SystemOpen[NotebookDirectory[]]
Better Audio support
We also added a new snippet in the command palette
Record Voice
(*VB[*)(Notebook`Editor`Kernel`PCMAudio`Internal`dump$112924)(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKmyamJKUkmZnpJhoYJuqamKWY6CYmmVvqmpoYJZoYWBoaGpsmAwCODRWP"*)(*]VB*) // AudioPlot
(*VB[*)(FrontEndRef["fc127432-1b30-420d-b760-f91b0846329e"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKpyUbGpmbGBvpGiYZG+iaGBmk6CaZmxnoplkaJhlYmJgZG1mmAgB2gxTV"*)(*]VB*)
External API
We know, that normally libraries for Wolfram Language are distributed as WL Packages or paclets, which do not have support for shipping Javascript / CSS files and etc.
Now it is possible to inject them in a runtime, you have to do it only once
FrontEndRuntime[{"Modules", "js"}] = Append[FrontEndRuntime[{"Modules", "js"}], File["path to your JS"]]
See docs for more information
To check if a code is running with WLJS frontend, you can check this system variable
Internal`Kernel`WLJSQ
True
Ballon animation by Jemima (codepen)