Skip to main content

plotting - Plot of continuous function cuts off


Why the following plot cuts off at integer points ?


Plot[Cos[Pi IntegerPart[x]]
Min[Abs[FractionalPart[x]], Abs[FractionalPart[x] - 1]], {x, 0, 10}]

enter image description here


Update


It gets connected when you add Exclusions -> None as an option, but It is not clear why this function has exclusive points, since it is continuous. Also it gets connected if you increase the PlotPoints (thanks to the comments). Also why at x=9 the cut is more severe than say at x=1 or x=2 ?



Can someone explain what is the issue here, and how these two options solve(or maybe hide) the issue ?



Answer



This behavior has been evolving ever since Mathematica was created. Something different happens in V11 than in V10. (I'm unable to go back further.) I'll describe V10 first, since its behavior conforms to the OP.


IN V10, the gaps are because the functions FractionalPart and IntegerPart are discontinuous, which makes the gaps symmetric. In plotting, Mathematica does not check limits at their discontinuities to see if the expression being plotted happens to be continuous. Rather, it assumes the discontinuities in the component functions propagate to discontinuities in the plot and puts a little gap in the plot at each one.


I assume this choice (not to check limits) was made for the sake of speed. The discontinuities are identified by a time-constrained symbolic analysis of the function.


The size of the gap is determined by the sampling. With higher setting for PlotPoints, the smaller the gap. The sampling can be observed using Mesh -> All. The sampling is a result of an asymmetric recursive subdivision of "active" subintervals, which depends principally on the angles between successive line segments used to approximate the graph. As a result, the gaps are not identical.


Plot[Cos[Pi IntegerPart[x]] Min[Abs[FractionalPart[x]], 
Abs[FractionalPart[x] - 1]], {x, 0, 10}, Mesh -> All,
MeshStyle -> Red]


Mathematica graphics


The gaps are not visible at ordinary size with lots of plot points:


Plot[Cos[Pi IntegerPart[x]] Min[Abs[FractionalPart[x]], 
Abs[FractionalPart[x] - 1]], {x, 0, 10}, PlotPoints -> 1000]

Mathematica graphics


Another approach, mentioned by @kglr in a comment, is to turn off the processing with Exclusions -> None.


Plot[Cos[Pi IntegerPart[x]] Min[Abs[FractionalPart[x]], 
Abs[FractionalPart[x] - 1]], {x, 0, 10}, Exclusions -> None]


IN V11, Plot adds sampling points close to the discontinuity. It still does not connect the lines, but if the function is continuous, the gap should be imperceptible.


plot = Plot[
Cos[Pi IntegerPart[x]] Min[Abs[FractionalPart[x]], Abs[FractionalPart[x] - 1]],
{x, 0, 10}, Mesh -> All, MeshStyle -> Red]
Count[plot, _Line, Infinity]

Mathematica graphics


(*  20  <-- number of continuous lines *)

One continuous line is created with Exclusions -> None:



Count[
Plot[Cos[Pi IntegerPart[x]] Min[Abs[FractionalPart[x]],
Abs[FractionalPart[x] - 1]], {x, 0, 10}, Exclusions -> None],
_Line, Infinity]
(* 1 <-- number of continuous lines *)

Comments

Popular posts from this blog

functions - Get leading series expansion term?

Given a function f[x] , I would like to have a function leadingSeries that returns just the leading term in the series around x=0 . For example: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x)] x and leadingSeries[(1/x + 2 + (1 - 1/x^3)/4)/(4 + x)] -(1/(16 x^3)) Is there such a function in Mathematica? Or maybe one can implement it efficiently? EDIT I finally went with the following implementation, based on Carl Woll 's answer: lds[ex_,x_]:=( (ex/.x->(x+O[x]^2))/.SeriesData[U_,Z_,L_List,Mi_,Ma_,De_]:>SeriesData[U,Z,{L[[1]]},Mi,Mi+1,De]//Quiet//Normal) The advantage is, that this one also properly works with functions whose leading term is a constant: lds[Exp[x],x] 1 Answer Update 1 Updated to eliminate SeriesData and to not return additional terms Perhaps you could use: leadingSeries[expr_, x_] := Normal[expr /. x->(x+O[x]^2) /. a_List :> Take[a, 1]] Then for your examples: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x), x] leadingSeries[Exp[x], x] leadingSeries[(1/x + 2 + (1 - 1/x...

mathematical optimization - Minimizing using indices, error: Part::pkspec1: The expression cannot be used as a part specification

I want to use Minimize where the variables to minimize are indices pointing into an array. Here a MWE that hopefully shows what my problem is. vars = u@# & /@ Range[3]; cons = Flatten@ { Table[(u[j] != #) & /@ vars[[j + 1 ;; -1]], {j, 1, 3 - 1}], 1 vec1 = {1, 2, 3}; vec2 = {1, 2, 3}; Minimize[{Total@((vec1[[#]] - vec2[[u[#]]])^2 & /@ Range[1, 3]), cons}, vars, Integers] The error I get: Part::pkspec1: The expression u[1] cannot be used as a part specification. >> Answer Ok, it seems that one can get around Mathematica trying to evaluate vec2[[u[1]]] too early by using the function Indexed[vec2,u[1]] . The working MWE would then look like the following: vars = u@# & /@ Range[3]; cons = Flatten@{ Table[(u[j] != #) & /@ vars[[j + 1 ;; -1]], {j, 1, 3 - 1}], 1 vec1 = {1, 2, 3}; vec2 = {1, 2, 3}; NMinimize[ {Total@((vec1[[#]] - Indexed[vec2, u[#]])^2 & /@ R...

What is and isn't a valid variable specification for Manipulate?

I have an expression whose terms have arguments (representing subscripts), like this: myExpr = A[0] + V[1,T] I would like to put it inside a Manipulate to see its value as I move around the parameters. (The goal is eventually to plot it wrt one of the variables inside.) However, Mathematica complains when I set V[1,T] as a manipulated variable: Manipulate[Evaluate[myExpr], {A[0], 0, 1}, {V[1, T], 0, 1}] (*Manipulate::vsform: Manipulate argument {V[1,T],0,1} does not have the correct form for a variable specification. >> *) As a workaround, if I get rid of the symbol T inside the argument, it works fine: Manipulate[ Evaluate[myExpr /. T -> 15], {A[0], 0, 1}, {V[1, 15], 0, 1}] Why this behavior? Can anyone point me to the documentation that says what counts as a valid variable? And is there a way to get Manpiulate to accept an expression with a symbolic argument as a variable? Investigations I've done so far: I tried using variableQ from this answer , but it says V[1...