A propos

DesmosGraph Calculator is an incredibly powerful tool to display curves ( Cartesian, polar, implicit ) and a lot more (with animation, sliders, summation and derivatives, custom functions, vectors of parameters, fitting, regression, stats, …). Firstly dedicated to pupils and high-school activities, it is also of interest for the scientist, the engineer and the university student. But the simplicity of principles and the minimalist manual hide some of the power of the tool. Conversely, some things are uneasy (and many think impossible) to do if you don’t know how to twist the tool.
In this blog, we will explore some of these points.

Disclaimer: I’m not related to the development team. I’m just a hard user of the tool 🙂

Some official and unofficial links:

Various tricks: sliders, keyboard, interrupted contours, function selector

Sliders

Making a movable point from variables respects their constraints.
→ this allows for 1D sliders:
set v=1 , then settle some value range. then draw point (0,v), and makes it vertically movable (in facts it is the default).

Note that DesmosGraph is smart enough so that even translation and scaling are permitted to draw your slider: (0, v/2 + 1/2 ) . ( But not non-linear transforms ).

Same principle to tune 2 variables as a square 2D slider.

What about other shapes, e.g., disk ?
DesmosGraph allows to put equation everywhere, comprising in parameters tunings, so that the second parameter range can be constrained by the first: range -sqrt(1-v²), sqrt(1-v²)

Example here. More extreme: spiral slider.

Keyboard user control


Desmos have multiple input and output alternatives, to help with various disabilities.
One of the features is that many thing can be controlled from the keyboard.
This include selecting a movable point ( use CTRL-ALT-P , then TAB or shift TAB to browse points ) and moving it ( using arrow keys ).
Practical use: to let the user control 1 ot 2 parameters via keyboard, put a discrete movable point somewhere, and just tell users to first do CTRL-ALT-P once, then use arrow keys.

Example here.

Interrupted contours

Sometime you want to store several contours or shapes in a same list.
This is possible, because DesmosGraph knows special numbers “undefined” like 0/0 , and “infinity”, like 1/0 or infty command.
The first can be used to interrupt contours, the second to make horizontal or vertical asymptotes.

Example here.

Function selector

Sometime you want to test a transform other several possible functions, or let the user experiment. Instead of changing the formula for f(x) or swapping the namings fi(x) vs f(x), you can implement a function selector by storing them in a table: F(x) = [ all functions ] then f(x) = F(x)[s] .
Example here.

Extending DesmosGraph

Disclaimer: This is the most technical and unreasonable post on this blog. Ephemeral & hazardous stuff here.


There are 3 ways to extend DesmosGraph with more features:

  • For programmers, the Desmos API lets you use and interact with Desmos elements within your own JS programs. I won’t address this here, see Desmos API ( help in the official API googlegroup and in the unofficial “programming” channel in the desmos discord forum ).
  • Adding plugins. Attention, these are non official, and might break with new versions of DesmosGraph.
  • Secret beta-features. Attention, these are unpublic and experimental, so they can disappear or change at any time, and have many bugs. Just for fun !

Plugins:

Secret beta-features

Attention, these are unpublic and experimental, so they can disappear or change at any time, and have many bugs. Just for fun !

  • Simulation:
    Run equations at every frame of an animation (choose the rate), or just when clicking “1 step”.
    This open a whole new world of reactive animations, simulations and games !
    Principle: name the variable(s) to be updated with the equation(s) you give.
    Trick: if you update big arrays, hide them in closed folder for better perfs.

    To activate it:
    F12 to go to the JS console, then enter Calc.updateSettings({clickableObjects: true}) +return, then F12 to exit.

  • Active buttons :
    Run equations each time a point is clicked. To switch on-off something, or so more: e.g. one step of simulation above.

    To activate it:
    as above. Points will now show a new option: clickable ( only for not movable points ).
    But for this one, attention: when people load your graph they do can use the feature, but they won’t see the update equations if they don’t activate the feature.

  • Advanced styling:
    More styling options for points and lines, before they (maybe) get public. (free colors once where there).

    To activate it:
    F12 to go to the JS console, then enter Calc.updateSettings({advancedStyling: true}) +return, then F12 to exit.

  • 3D mode:
    no longer available.

Examples:
Interactive drawing (with reset button).
Conway game of life cellular automata.
– See various simulations and automata in this reddit Desmos competition.

Using Complexes

We can use either points (x,y) or arrays [x,y] to implement complex, then redefine all classical operators mul, div, pow, exp, log. ( addition, subtraction, multiplication by scalar works directly ).

  • Implementation with points
    Advantages:
    – directly displayable and dragable.
    – points can contain lists ( to generate automatically a set of complexes )
    Inconvenient: you cannot compare or solve points.
  • Implementation with arrays
    Big advantage: you can compare and solve array: see Inversion below.
    Inconvenients:
    – you have to convert to/from points for display or drag parameters.
    – you cannot have list or list, so you can’t generate automatically a set of complexes.

Note that to display the mapping of space via a complex transform we would like to display the transformed grid, via solving f(X) = grid. Alas, only array-complexes allow solving while only points-complexes allow grids. But we can still do that by testing that values are integer via mod()=0, or near integer.

Example: complex inversion

Fitting curves and surfaces

For once this is not about a hidden feature or advanced trick: it is about a not know enough incredibly powerful function of DesmosGraph: fitting, i.e., finding the parameters of a simple target curve best approaching your raw data or your too complex function.
Many tools propose least square method to fit a line on a set, but DesmosGraph is a very rare tool allowing you to fit equations or data to really any shape you like, with any kind of parameters. And this can also be used for multidimensional functions.
And all this ultra simple: complexfunc(X) ~ simplefunc(X) , where simplefunc(x) is defined as usual, with use of free parameters as usual (just don’t define them, fitting will). X is an array of values, since fitting work on data sets.

Simple example

2D example

In the definition of g(), you can add contraints on the parameters , e.g. { -1 ≤ b ≤ 1 } to restrict search domain (in some complex situations this can help).

More about the history of this feature, and about advanced advices to handle complex cases here.

Useful hacks: more colors !

New (v 1.6) :

Desmos Graph now have color functions !
var = rgb(r,g,b)  (r,g,b in 0..255 )  , or     var = hsv(h,s,v)   ( h in 0..360, s and v in 0…1 )

Declaring this add a new color to the palette you can use when choosing colors.
You can use any expression, possibly depending on an existing variable (e.g. time). NB: The variable name is compulsory, despite of no use for you.

A cool use is to define array values for colors: then if you draw an array of points or curves and set this “color” to it, each successive element will use the successive color in the array.
See example1, example2, example3.

desmos-graph (6)  desmos-graph-5  capture-decran_7

So now we can even do ray-tracing with the proper colors  😉
desmos-graph (11)

Deprecated way:

Desmos Graph only allows a very small palette of 6 colors, even if you can simulate more by superimposing layers with transparency.

Mr H. Here to Help proposed a useful hack to add more, via javascript:

desmos-graph_colors

                                                                         Example  ➛

  • Open the Javascript Console of your browser ( via menu, or shortcut F12 )
  • In the console, type Calc.colors.COLORNAME = "#RGB" , where RGB packs the R,G,B color components encoded in hexadecimal from 0 (min intensity ) to F (max intensity).  E.g., Calc.colors.olive = "#880"
  • Variant: You can have more precision in the tint by encoding the colors as "#RRGGBB" , i.e.  2 digits for each color component from 00 (min intensity ) to FF (max intensity). E.g., Calc.colors.olive = "#808000"
  • You can then close the Javascript tab with the close button or F12.
  • Now, the color menu shows the extra colors !

Attention: the object colors are correctly saved, but at loading they will no longer appear as choice in the color menu.

Conveniently packed by Andre Issa as a Color Picker plugin 
   [ not working well on my ubuntu, though ]

[ To be continued ]

See also: secret geometry features , undocumented details

Drawing geometry (secret features inside :-) )

If you practice even a bit of Desmos Graph, you already know many way to draw curves (explicit, implicit, parametric, polar plot…) and to fill them (using inequalities).  We also presented here how to draw series of curves and do more complex regions painting. With this we can already produce polygonal figures from equations:
polygons  concentric polygons   stars       involved constructions
desmos-graph (23).png  desmos-graph (24).png    desmos-graph (25).pngdesmos-graph (26).png

But it is also possible to directly draw and manipulates shapes, and there are even undocumented features to do so.

At the base is the point: we already use them to draw parametrics  ( X(t), Y(t) ) , or to get visual sliders ( a, b ). This set point syntax. But there is a lot more you can do with points:

  • You can name them: A = (1,2), even for unknowns: X = (x,y)
  • Indeed they can even contain a list:
    • X = [1,2,3]  Y = [4,2,7]  P = (X,Y)desmos-graph (27).png
      Or directly as T = ( [1,2,3], [4,2,7] )
      Or using an array.    Example: Delaunay triangulation :
    • This allows to define point sets:
      P = ( cos( 2Pi[0...N]/N ) , sin( 2Pi[0...N]/N ) )
  • Conversely, you can have list of points: L = [ (1,2), (3,5), (0,0) ]
    That you can even translate ans scale:  (0,2) + .3 L
  • You can access point coordinates with P.x and P.y
  • You can draw polygons:
    •  polygon( A, B, C ),
      polygon( (1,1), (0,5), (5,3) ),
      polygon(P) with P defining a set above.
      The attributes button let you tune the look as for curves, with more options.
    • Indeed you can also directly draw polygons when defining points set as P above: The  attributes button let you join them with lines and tune exactly the same set of parameters.
    • Arrays also let you display columns as point sets and tune attributes, allowing to draw points and join then with lines. Making them loop is not easy ( P[ join([1,...length(P)],[1])]  ) , so it can be simple to duplicates the first point to the last position (explicitly, or by storing the duplicate values in some variables).
  • You can compute the distance between points (simples or sets):
    distance(A,P)
  • You can get the midpoint(A,P)
  • Since version 1.6, you can add, substract, multiply points. E.g. (1-t)A + tB draws segment AB.
    You can also use piecewise definition: C = { n=0: (1,2) , n=1: (0,7), (0,0) } . see example.desmos-graph (7)
  • Example of application: drawing splines from point sets:
  • Alas we cannot directly solve or compare (e.g., A+X = B-X or  midpoint( (0,0),(x,y)) = (5,5) ).But we can do it on anything scalar:
    • via their coordinates,
    • we do can solve and compare with the distance operator:
      distance( (x,y), (0,0) ) <= 1 draws a filled circle.desmos-graph (8)
      distance( (x,y), (0,0) ) = [0...N]/N draws a series of circles.
      distance( (x,y), (0,1) ) = distance( (x,y), (x,0) ) draws a parabola.
      More examples here.
      Attention: distance( (x,y), P ) = 1 with P as above would traces a series of circles, one around each points in the set, but distance( (x,y), P ) = [0...N]/N won’t turn them into a double series (multiple circles around points): remember than arrays are synchronous in expressions, so each element of the array of radii will fit the corresponding element in the array of points.
  • Of course, you can also do geometry with points encoded as arrays, using points only for display and controls.  Example here.  Then,desmos-graph (28).png
    • you can add, substract, weight points-as-arrays, cf 3D ellipse:
    • dot product is  total(V1*V2),
    • distance is  sqrt(total(V1²)),
    • multiplication by matrix is [ total(V*[M00,M01]) , total(V*[M10,M11]) ],
    • etc.
    • ( drawing grids and vector fields: treated here ).
  • With some effort, from all this you can even do meshes in perspective: see here.desmos-graph (16)

Desmos traps: “why is it not working ?”

It’s not uncommon to have either unexpected results or puzzling error messages in Desmos. Here are some classical examples and solutions.

Misleading functions

  • Desmos log means log10. Not to be confused with ln , that also be noted log_e.
  • Desmos stdev means the statistical estimator, not to be confused with the real standard deviation of a set, noted stdevp. ( stdev = sqrt(N/(N-1))*stdevp ).

 Misleading span of variables

  • There is no local variable. Sum_n prevents you to use n anywhere else again (and the error message will be puzzling)… but in other sums.
  • Lists are kind of vectors, but with common alignment for all expressions in your session. Don’t expect to enlarge the combinatory by passing an extra vector where a constant was expected.

Ambiguous syntax

  • The syntax for tracing the locus where a variable or function equals something looks a lot like what you would do for defining it, and Desmos easily think it’s a second definition of the same thing, which it allows… as long as its not used in another expression (then you’ll get a puzzling error message).→To avoid f(x) = 3 ambiguity, either trace 3 = f(x) or f(x)+0 = 3
  • Conditions look like a separate statement, but indeed it’s part of the expression.That’s why ( x, y ) { cond } can’t work, for a point is not a value. Use (x, y { cond } ) .

Copy-pasting

  • From Desmos Graph to exterior, you will always get LaTeX form of equations. So Desmos can be used as a LaTeX editor, but you can’t get simple text version.
  • From outside text to Desmos Graph: it works… but for operators like sqrt, |.|, {.}, sum …Indeed Desmos expect some LaTeX source, and just extend syntax to some text names like sin so that simple text expressions accidentally work. Conversely x_a = \sum{\sqrt{x}} works, or any complex LaTeX formula.But \{, that block the pasting.
    New: some plugins now allow to manage that.

Out of conceptual space

Many limitations can be twisted, like drawing in 3D, making random numbers, or emulating vector algebra. But some concepts remain definitively out of reach:

  • In fact all expressions are precomputed by Desmos. So don’t expect to reproduce really evolving states, like dynamics simulation ( but with this hacky non-reliable hidden feature ). Even recursivity won’t work, for conditions are just functions like the others, rather than algorithmic structures.
  • There is no way you can get the inverse of a function. But you can trace it.
  • or between conditions is near impossible, appart duplicating the function and applying the alternate condition (for plotting)  or putting the whole content in piecewise form (for definitions): f(x) = { cond1: val, cond2: same-val }
    (and can be obtained with the m < x < M syntax for simple cases or by nesting { cond } statements.

Generating random numbers and points

Undocumented functions: (see more)

  • random(N)creates an array of N uniform random numbers in range 0..1.
    random(N,s) provides a seed s allowing producing different sequences.
  • Distributions: uniformdist(), normaldist(), poissondist(), binomialdist(), tdist() (student)
  • random(normaldist(...) , ... )  or  normaldist(...).random(...) :
    creates an array of random numbers with target distribution.

See example1 , example2.

Manually:

  • A classical hash function is obtained by tacking least significant bits of a high frequency sin: e.g., R(i) = mod(10⁴.sin(10⁴i),1)  , to be evaluated at discreet i values.
    Examples:  uniform dots , cloud covariance ,  lightening random walk , bush
    desmos-graph (15)    desmos-graph (16)  desmos-graph (18).pngdesmos-graph (14)
    more (with animation):
    rand.png
  • You can make a 2D hash function the same way. An historical tuning giving good quality values is H(i,j) = mod( sin(i*12.9898 +j* 78.233) * 43758.5453, 1)

desmos-graph (21)

Enriching graphics

Thick or varying thickness curves

The curve tracing engine of DesmosGraph is very efficient. So you get thick curves by a twist: add a very high frequency oscillation ! e.g.:  sin(x) + .1*sin(1000x)
cf more elaborate example:
desmos-graph (3)

Emulating two parameters parametrics

the idea is to take a large range for parametric parameter t, and to slice it in chunks using mod(t/N,1) as parameter 1, parameter 2 being the slice number given by floor(t/N). If you want a full grid rather than parallel curves, duplicate the plot and swap the floor() and mod().
The same principle extends to 3 parameters using floor(mod(t,N)), floor(t/N), mod(t/N,1).

desmos-graph (10).pngdesmos-graph (9).pngExamples:

  • See rest grid here:
  • See m() in spiral galaxy:
  • See isometric ellipsoid below
  • This can also be used to draw a field of vectors or circles (another example). Note that thin details can sometime be missed by the display engine.

desmos-graph (13)    desmos-graph (11)      desmos-graph (12) desmos-graph (14)

3D plots

Filling / Painting

  • Inequations let you color areas, with plain or dash border depending on inclusive vs strict inequality.
  • You can avoid the border line by putting the inequation in the condition:
    0 < 1  { sin(x)sin(y) < -0.5 }
    ( alas the resulting colors varying very non-linearly with the number of semi-transparent layers, and get quickly opaque, at a different rate depending on the base color ).
  • desmos-graph (5).pngYou can get several lever of shade by superimposing layers, thanks to array parameters:
    0 < 1  { sin(x)sin(y) < -1+2*[0,.3,...1] }
  • New: custom colors and custom gradients now give more freedom.

extreme examples:
Ray-tracing sphere           tests on color composition
desmos-graph desmos-graph (4)

Undocumented details

The manual is very short: many more can be done !
( Many additional info is scattered in the help center, if you take time to crawl it 🙂 ).

Variables and function names

  • x,y, r,θ  are the default parameterization in Cartesian and polar coordinates,
  • π,τ,e are the special constants.
  • Possible names: a0, A1, B_whatever, α (type "alpha"), β, φ,  α1, α_whatever,
  • More: since LaTeX inputs are valid, you can get any other Greek variable name, in caps or not, by copy pasting from outside (or from a text field in DesmosGraph): \gamma, \Gamma, \epsilon, etc. Once there the symbol can be copy-pasted between fields.
    New: a plugin now allows all Greek letters.
  • Note that you can display the value of a variable as the label of a point using special label ${v}
    Example here .

Arrays / lists / tables

Expressions and thus resulting variables and functions accept arrays: it’s like using vectors instead of scalar. It also allows to graph a full family of curves of areas instead of one, whatever the plotting method (Cartesian, polar, implicit, inequations…).

DesmosFig3.png

e.g.:desmos-graph (6) A = [1,...,10]  →  sin(A*x) ,
2*A/10-1 , etc. More: here.
sin(x)*sin(y) <= -1+2*[0,.3,...1]

Complex examples:
Array of threads   ,  Fractal braid  ,  Push hole in param
desmos-graph (1).png desmos-graph (2)  desmos-graph (2)

Visualizing the content of an array:

  • Create a table and replace column y1 (or nexts ) by the array name
  • plot: ( [ 1...length(L)], L )
    you can even label dots with their value, using  label ${L}
  • use histograming & plotting tools ( see below )

Complex operations on arrays:

  • L[N]  where N is an array of integers
  • sublist: L[3...] or L[3..5]
  • reversed order : L[length(L)...1]
  • L[  joint([1,...length(L)],[1]) ] to make it cyclical (e.g. for a closed contour )
  • d(n) = L[ 1+ mod( [0...length(L)-1] +n,length(L) ) ] to roll it by n
  •  sublist obeying a criterion: L[ L>0 ] or L [ f(L)>0 ]
  • → indexes of item v in L:  [1...length(L)][L=v]
       ( indeed you can think of [L=v] or [cond(L)] already doing it, but not directly authorized as this syntax is ambiguous )
  • sorted version of the list: sort(L) or L.sort
  • shuffled : shuffle(L) or L.shuffle

Indeed, about anything can be a table: parameters, results, even some attributes (e.g. colors).
See use for geometry, defining complexes, or function selectors.

Variable length

  • Array can be set as [1,...,N] , or [0,1/N...1]
  • Slider can be set between 0 and expressions like a+pi/2

Functions

  • All trigonometrics also have their inverse, comprising sinh(x), etc.
    Moreover, you can also get them using sin^-1(x)  (alas, this does not work for custom functions).
  • log are available in any base with logn . Attention, log alone is log10, use ln for base e.
  • min , max  works with any number or parameters, as well as lists (like all the stats functions).
  • nth root (e.g., cubic):  nthroot
  • The gamma function, generalization of the factorial, is just x!
  • Piecewise function / expression: f(x) = {cond1: expr1, cond2: expr2, ... , default_expr}
  • Derivatives: d/dx f(x) , f'(x) , f''(x) , d/dx d/dx f(x)
  • Summation, product, integrals:  sum, prod, int
  • From statistical distributions: f = normaldist(0,1)
    → draw: g(x) = pdf(f,x) or g(x) = f.pdf(x) . Same with cdf.
    Distributions: uniformdist(), normaldist(), poissondist(), binomialdist(), tdist() (student)
  • random(N) creates an array of N uniform random numbers in range 0..1.
    random(N,s) provides a seed s allowing producing different sequences.
  • random(normaldist(...) , ... ) or normaldist(...).random(...) :
    same for normal law (or any distribution).
    → See example.

Restrictions / Range

  • Domain limited function / expression: f(x) = expr {cond}

    • Range condition: 0 <= x < 1
    • AND of conditions: {cond1}{cond2}
    • For parametrics curve, the condition must be *in* the parenthesis:
      ( t,  sin ( t ) { t > 0 }  )
  • Variable slider: a reminder to tune the bounds, and possibly the step ( 1 for integers).
  • For points used as (bi)sliders, remember to set limits on the associated variable.
    If you want the point to only move in one axis, or not at all, the settings menu let you restrain it (and do many other things).
  • For parametric and polar curves, a reminder than you can tune the bounds as well. You can even abuse of it to generate 2D parameters using mod() and floor() :-).

Geometry & drawing:

  • There are undocumented operators and features for geometry ! We explain these here.
  • histogram(A [,step]) : plot the histogram of array A for values every steps.
    dotplot(A [,step]) :  same with points instead of bars
    boxplot(A) :  draw a box encoding mean, stddev, range.

More about: