<span class="mw-page-title-main">Mathematica</span>
Fabrice P. Lauss𝕪's Web

Mathematica

Mathematica is a computational engine. It is probably the closest tool we have to an effective universal computer in its broadest sense.

Applets (Wolfram Demonstrations)

  1. Cavity Quantum Electrodynamics with Bosons: Emission Spectra in the Strong and Weak Coupling Regimes, Fabrice P. Laussy and Elena del Valle, 7 March (2011).
  2. Mollow Triplet, Elena del Valle and Fabrice P. Laussy, 9 December (2013).
  3. Polarized Polariton Fields on the Poincaré Sphere, David Colas, Elena del Valle and Fabrice P. Laussy, 12 February (2015).
  4. Rabi and Josephson Oscillations, Amir Rahmani and Fabrice P. Laussy, 11 April (2016).
  5. Dispersion Properties of a Spin-Orbit-Coupled Bose-Einstein Condensate, David Colas, Fabrice P. Laussy and Matthew J. Davis, 15 September (2017).
  6. Polariton and Jaynes-Cummings Blockade, Eduardo Zubizarreta Casalengua, Juan Camilo López Carreño, Fabrice P. Laussy and Elena del Valle, 18 January (2019).

Background

Mathematica is the pinacle of Wolfram research, the company built by Stephen Wolfram, initially to develop Mathematica, now with extended ambitions in various areas of computational interest (see a new kind of science and Wolfram|Alpha as other major examples).

Weaknesses

The main one is that it is proprietary code.

The most annoying practical feature of Mathematica is that it does not have a good text editor, although this is fundamental for anything related to code editing ("writing code"). Particularly crippling is the inability to split windows, to work on remote aspects of the computation in parallel. Someone reports that:

I asked this split screen question to Wolfram in 1994! He tried and convince me I didn't need it.

The following trick—using a palette that makes a duplicate, read-only copy—is useful:

CreatePalette[Button["Duplicate Active Notebook",
   NotebookPut[NotebookGet[InputNotebook[]] /. 
   {Rule[DockedCells, _] :> Sequence[], 
    Rule[WindowMargins, _] :> Rule[WindowMargins, {{0, Automatic}, {0, Automatic}}], 
    Cell[x___] :> Cell[x, Evaluatable -> False]}, 
    Background -> GrayLevel[0.95], Editable -> False, "ClosingSaveDialog" -> False, 
    DockedCells -> With[{sourcenb = InputNotebook[]}, 
      Cell[BoxData[ToBoxes[Button["Update", 
          SelectionMove[InputNotebook[], All, Notebook]; 
          NotebookWrite[InputNotebook[], 
           NotebookGet[sourcenb] /. Cell[x___] :> Cell[x, Evaluatable -> False]]]]],
       "DockedCell", CellContext -> Cell]],
    WindowTitle -> "Duplicate of " <> AbsoluteOptions[InputNotebook[], WindowTitle][[1, 2]]];
   SetSelectedNotebook[InputNotebook[]]], WindowTitle -> "Duplicate"];

Beautiful plots by default

Mathematica's plots are correct but plain, and turning them into something one would put in a paper means repeating the same dozen options on every single Plot. Since the kernel reads ~/.Mathematica/Kernel/init.m at startup, all that styling can be set once and for all with SetOptions. Mine lives in ~/.Mathematica/Kernel/PlotDefaults.m (loaded from there), so that a bare, frameless plot needs no styling at all:

Plot[{Sin[x], Sin[2 x]/2, Sin[3 x]/3}, {x, 0, 4 Pi},
     AxesLabel -> {"x", "Λ"}, PlotLegends -> {"n=1", "n=2", "n=3"}]

and comes out with italic maths labels at the tips of the axes, upright tick numbers, Latin Modern (the LaTeX font) throughout, 1.8pt curves in a colour-blind-safe cycle and an unframed legend in the same font—no Frame, no Style, no Directive anywhere in the input.

Labelling is then a one-liner, in whichever flavour suits:

What you want What you write
The axes AxesLabel -> {"x", "Λ"}
The curves, labelled in place PlotLabels -> {"sin", "cos"} (leader lines to the curve ends, and no legend at all)
The curves, legend on the side PlotLegends -> {"n=1", "n=2"}
The curves, legend inside the plot PlotLegends -> Placed[{"n=1", "n=2"}, {0.85, 0.65}] (scaled coordinates)

To tweak: PlotDefaults`$PlotFontSize = 20; PlotDefaults`PlotDefaultsOn[], and likewise for $PlotColors, $PlotFont and $PlotImageSize. PlotDefaults`PlotDefaultsOff[] restores stock Mathematica exactly (the original options of every function are saved before they are touched).

Four traps dictated the implementation, all of them found by exporting the figure and looking at it:

  • There is no such thing as an axes-label style separate from the tick style. The obvious LabelStyle -> Italic italicises the tick numbers as well, and nothing in TicksStyle can undo it—neither Plain, nor FontSlant -> Plain, nor Italic -> False. The only cure is to rebuild the tick list (with Charting`ScaledTicks, the automatic generator) and wrap each label in an explicit Style[lab, FontSlant -> Plain], which does win.
  • That trick makes ParametricPlot, PolarPlot, ListPolarPlot and DiscretePlot render as an empty pink error box, so those four keep the stock ticks and their numbers stay italic. Logarithmic axes keep their own 10^n ticks too (they are upright anyway).
  • PlotStyle -> {d1, d2, ...} is merged into a single style when the plot has only one curve, so the last colour of the list wins and every single-curve plot comes out olive. Wrapping each directive in its own list, {{d1}, {d2}, ...}, makes it an unambiguous colour cycle. Defining a custom PlotTheme with a DefaultPlotStyle silently does nothing.
  • AspectRatio and ImagePadding must never be pushed onto the defaults of Graphics, ParametricPlot or PolarPlot: their Automatic aspect ratio is what keeps a circle round. Only the plotters whose two axes carry unrelated quantities get 1/GoldenRatio.
(* ::Package:: *)

(* PlotDefaults.m -- v1.0.4
   Beautiful defaults for frameless (Axes) plots:
     . axes labels typeset in italic maths at the tip of each axis,
       so  AxesLabel -> {"x", "\[CapitalLambda]"}  is all you ever have to write;
     . tick numbers upright and smaller;
     . Latin Modern (the LaTeX font) throughout, if installed;
     . thicker curves in a colour-blind-safe cycle;
     . unframed legends in the same font.

   Loaded from ~/.Mathematica/Kernel/init.m.
   PlotDefaultsOff[] restores Mathematica's own options, PlotDefaultsOn[] puts
   these back (call it again after changing $PlotFontSize, $PlotFont, ...). *)

BeginPackage["PlotDefaults`"];

PlotDefaultsOn::usage  = "PlotDefaultsOn[] applies the default plot styling.";
PlotDefaultsOff::usage = "PlotDefaultsOff[] restores Mathematica's own plot options.";
$PlotFont::usage       = "Font family used by the plot defaults.";
$PlotColors::usage     = "The curve colour cycle used by the plot defaults.";
$PlotFontSize::usage   = "Axes-label font size; ticks are 5pt smaller, legends 3pt.";
$PlotImageSize::usage  = "Default ImageSize of a plot.";

Begin["`Private`"];

(* ---- font: the LaTeX look if installed, else a decent serif -------------- *)
$PlotFont = SelectFirst[
   {"Latin Modern Roman", "CMU Serif", "Times New Roman", "Times", "DejaVu Serif"},
   MemberQ[$FontFamilies, #] &,
   "Latin Modern Roman"   (* $FontFamilies is empty in a kernel with no front end *)
];

$PlotFontSize  = 17;
$PlotImageSize = 400;

(* ---- curve colours ------------------------------------------------------
   Colour-blind-safe cycle (Okabe-Ito, darkened and reordered): every adjacent
   pair keeps deltaE >= 9 under deuteranopia/protanopia/tritanopia and >= 3:1
   contrast on white.  Replace $PlotColors and re-run PlotDefaultsOn[] to
   change it.                                                                *)
$PlotColors = RGBColor /@ {
   "#0072B2",  (* blue       *)
   "#D55E00",  (* vermillion *)
   "#009E73",  (* green      *)
   "#9061C2",  (* purple     *)
   "#B07800",  (* ochre      *)
   "#2E90C4",  (* sky        *)
   "#B5628E",  (* pink       *)
   "#6B8E23"   (* olive      *)
};

(* NB: each style is wrapped in its OWN list.  A bare list of directives gets
   merged into a single style when the plot has only one curve (the last
   colour would win); the extra braces make it an unambiguous cycle. *)
curveStyles[] := {Directive[AbsoluteThickness[1.8], AbsolutePointSize[5.5], #]} & /@ $PlotColors;

(* ---- upright tick numbers ------------------------------------------------
   LabelStyle -> Italic italicises the axes labels AND the tick numbers, and
   nothing in TicksStyle can undo it (neither Plain nor FontSlant -> Plain nor
   Italic -> False).  So the tick labels are rebuilt with an explicit Style,
   which does win.                                                            *)
upright[tf_][min_, max_] := Replace[
   tf[min, max],
   {v_, lab : Except[_List], rest___} :> {v, Style[lab, FontSlant -> Plain], rest},
   1
];
linTicks := upright[Charting`ScaledTicks[{Identity, Identity}]];

(* ---- the option set ------------------------------------------------------ *)
commonOpts[] := {
   (* axes labels, PlotLabel, PlotLabels, legend text: italic maths *)
   LabelStyle -> Directive[GrayLevel[0.1], FontFamily -> $PlotFont,
                           FontSize -> $PlotFontSize, Italic],
   TicksStyle -> Directive[GrayLevel[0.25], FontFamily -> $PlotFont,
                           FontSize -> $PlotFontSize - 5],
   AxesStyle  -> Directive[GrayLevel[0.15], AbsoluteThickness[0.9]],
   ImageSize  -> $PlotImageSize,
   PlotRangePadding -> Scaled[0.03],
   (* room at the tips of the axes so the labels are not clipped *)
   ImagePadding -> {{Automatic, $PlotFontSize + 6}, {Automatic, $PlotFontSize + 6}},
   PlotStyle -> curveStyles[]
};

(* linear axes: rebuild both tick sets.  Log axes keep Mathematica's own ticks
   (10^n labels) -- rebuilding those is not worth the fragility. *)
$linearFunctions = {
   Plot, ListPlot, ListLinePlot, ListStepPlot
};
(* These choke on a Style[] inside a tick label (they render as an empty pink
   error box), so they keep Mathematica's own ticks -- their tick numbers come
   out italic like the labels. *)
$plainTickFunctions = {ParametricPlot, PolarPlot, ListPolarPlot, DiscretePlot};
(* AspectRatio only where the two axes carry unrelated quantities.  Forcing it
   on Parametric/Polar plots (or on Graphics) would turn circles into ellipses. *)
$golden = {Plot, ListPlot, ListLinePlot, ListStepPlot, DiscretePlot,
   LogPlot, ListLogPlot, LogLinearPlot, ListLogLinearPlot, LogLogPlot, ListLogLogPlot};
$logFunctions = {
   LogPlot -> {"lin", "log"}, ListLogPlot -> {"lin", "log"},
   LogLinearPlot -> {"log", "lin"}, ListLogLinearPlot -> {"log", "lin"},
   LogLogPlot -> {"log", "log"}, ListLogLogPlot -> {"log", "log"}
};
$legendFunctions = {LineLegend, PointLegend, SwatchLegend, BarLegend};

$saved = <||>;

(* push only the options a given function actually accepts *)
setSafely[f_, opts_] := (
   If[! KeyExistsQ[$saved, f], $saved[f] = Options[f]];
   Quiet@SetOptions[f, FilterRules[opts, Options[f]]]
);

tickSpec["lin"] := linTicks;
tickSpec["log"] := Automatic;

PlotDefaultsOn[] := Module[{opts = commonOpts[]},
   Do[setSafely[f, Append[opts, Ticks -> {linTicks, linTicks}]], {f, $linearFunctions}];
   Do[setSafely[First[f], Append[opts, Ticks -> tickSpec /@ Last[f]]], {f, $logFunctions}];
   Do[setSafely[f, opts], {f, $plainTickFunctions}];
   Do[setSafely[f, {AspectRatio -> 1/GoldenRatio}], {f, $golden}];
   (* bare Graphics: fonts only, nothing that could reshape a picture *)
   setSafely[Graphics, FilterRules[opts, {LabelStyle, TicksStyle, AxesStyle}]];
   Do[setSafely[f, {
         LabelStyle       -> Directive[GrayLevel[0.1], FontFamily -> $PlotFont,
                                       FontSize -> $PlotFontSize - 3],
         LegendMarkerSize -> 26,
         Spacings         -> 0.3
      }], {f, $legendFunctions}];
   $PlotColors
];

PlotDefaultsOff[] := (
   KeyValueMap[Quiet@SetOptions[#1, #2] &, $saved];
   $saved = <||>;
);

End[];
EndPackage[];

PlotDefaults`PlotDefaultsOn[];

See also

In my Blog

Links