16
$\begingroup$

Is it possible to change the Dashed Style of a curve into circles with Plot command ?

Plot[Cos[x], {x, 0, 2*Pi}, PlotStyle -> Directive[Dashed, Thickness[0.005]]]

enter image description here

$\endgroup$
4
  • $\begingroup$ Please post your code ... as always $\endgroup$ Commented Dec 25, 2013 at 4:25
  • $\begingroup$ Plot[Cos[x], {x, 0, 2*Pi}, PlotStyle -> Directive[Dashed, Thickness[0.005]]] $\endgroup$
    – kamran
    Commented Dec 25, 2013 at 4:29
  • $\begingroup$ An easy way is to use ListPlot with PlotMarker. For example, ListPlot[Array[{#1, Cos[#1]} &, 200, {0., 4 Pi }], PlotMarkers -> Graphics[{Red, Circle[]}, ImageSize -> 10], PlotRange -> All],however, it violates your demand to use Plot command. $\endgroup$ Commented Dec 25, 2013 at 8:50
  • 1
    $\begingroup$ Related, if not possible duplicates: (8454), (8970), (21993) $\endgroup$
    – Mr.Wizard
    Commented Dec 25, 2013 at 12:18

4 Answers 4

6
$\begingroup$

Perhaps this approach, using Mesh, MeshStyle, and Opacity, will give you what you looking for.

Plot[Cos[x], {x, 0, 2 Pi},
  PlotStyle -> {Opacity[0]}, Mesh -> 50, MeshStyle -> {PointSize[Medium]}]

plot.png

Update

To show two curves, one as dots and the other as a normal plot, I would make two plots and combine them with Show.

p1 = 
  Plot[Cos[x], {x, 0, 2 Pi}, 
   PlotStyle -> {Opacity[0]}, Mesh -> 30, MeshStyle -> {PointSize[Large], Blue}];
p2 = Plot[Sin[x], {x, 0, 2 Pi}, PlotStyle -> {Thick, Blue}];
Show[{p1, p2}]

show.png

You can use Show to combine as many plots as you wish.

$\endgroup$
4
  • 2
    $\begingroup$ The problem is that the density isn't uniform along the curve. Any spike will give you an accumulation point $\endgroup$ Commented Dec 25, 2013 at 5:58
  • $\begingroup$ If the OP wants open circles, the post-process with Plot[..] /. Point[pts_] :> (Circle[#, 0.05] & /@ pts). Can either change aspect ratio of the plot or use Circle[#, 0.05 {1, 1/GoldenRatio}]. $\endgroup$
    – Michael E2
    Commented Dec 25, 2013 at 5:59
  • 1
    $\begingroup$ @MichaelE2 As I understand it, the OP wants a circle where he has a dash. And that isn't easy (I think) $\endgroup$ Commented Dec 25, 2013 at 6:27
  • $\begingroup$ @ m_goldberg, with the help of Plot command I want to get one curve in form if circles and other like a solid line. Plot[{Cos[x], Sin[x]}, {x, 0, 2 Pi}, PlotStyle -> {Opacity[0]}, Mesh -> 30, MeshStyle -> {PointSize[Large], Blue}] $\endgroup$
    – kamran
    Commented Dec 26, 2013 at 9:52
18
$\begingroup$

If you want to roll your own solution to evenly distrubute circles along the path you could use the so called arc length parametrization of the path $p(t)=(t,\cos(t))$. For this particular curve, it will need to be computed numerically.

p[t_] := {t, Cos[t]};
$Assumptions = {t > 0};
speed[t_] = Simplify[Norm[p'[t]]];
arcLength[t_?NumericQ] := NIntegrate[speed[tau], {tau, 0, t}]
phi[s_?NumericQ] := t /. FindRoot[arcLength[t] == s, {t, 1}];
p1[s_?NumericQ] := p[phi[s]];
Graphics[Table[
  Circle[p1[s], 0.05], {s, 0, arcLength[2 Pi], arcLength[2 Pi]/30}],
 Axes -> True]

enter image description here

$\endgroup$
4
  • $\begingroup$ Nice. By the way, Mma can solve for the arc length exactly for this particular curve (in terms of EllipticE), but the numerical way will handle arbitrary curves better than Integrate, of course. $\endgroup$
    – Michael E2
    Commented Dec 25, 2013 at 16:43
  • $\begingroup$ Thanks! I was aware of the EllipticE thing, but figured the resulting function would need to be inverted numerically anyway. As I think of it further, perhaps the special function representation arcLength could be passed to InverseFunction or some such? Seems overly mysteriious, though. $\endgroup$ Commented Dec 25, 2013 at 18:36
  • $\begingroup$ I think InverseFunction is just going to use FindRoot anyway. It certainly works with InverseFunction and the "exact" arc length. (Of course in graphics, even addition and multiplication are a numerical procedures, so "exact" is not as important as "accurate.") $\endgroup$
    – Michael E2
    Commented Dec 25, 2013 at 18:59
  • 1
    $\begingroup$ Of course, one can use MeshFunctions -> {"ArcLength"} these days. $\endgroup$ Commented Dec 11, 2015 at 17:24
11
$\begingroup$

A dash of length zero is rendered as a "dot", according to the documentation for Dashing. To get a circular dot use CapForm["Round"].

Plot[Cos[x], {x, 0, 2*Pi}, 
 PlotStyle -> Directive[CapForm["Round"], Dashing[{0, 0.05}], Thickness[0.02]]]

Mathematica graphics

$\endgroup$
5
  • 1
    $\begingroup$ Curious, I am getting this i.sstatic.net/6Tyhw.png . Mma 9.0.1 for Win32 $\endgroup$ Commented Dec 25, 2013 at 18:16
  • $\begingroup$ @belisarius That is odd. Works on a Mac for V7, V8.0.4, and V9.0.1. $\endgroup$
    – Michael E2
    Commented Dec 25, 2013 at 18:46
  • $\begingroup$ Also fails in v7 under Windows. :-( $\endgroup$
    – Mr.Wizard
    Commented Dec 26, 2013 at 14:39
  • $\begingroup$ Fails in v.8.04 under Windows 7 x64. $\endgroup$ Commented Dec 27, 2013 at 9:36
  • 1
    $\begingroup$ There seems to be an issue amongst the various graphics drivers whether CapForm applies to the ends of dash segments or only the ends of the whole line. This example "fails" with v9/Windows but works if exported to pdf or eps. $\endgroup$
    – george2079
    Commented Mar 24, 2014 at 20:57
8
$\begingroup$

This is an alternate compute-your-own-arc-length approach, based directly on the line produced by plot, (ie not differentiating its functional form as in Mark's answer)

p1 = Plot[Cos[x], {x, 0, 2 Pi}]
linepoints[plist_, n_] := Module[{arc, tlen},
  arc = Interpolation[
        Transpose@{{0}~Join~
                  Accumulate@(Norm@(Subtract @@ #) & /@ 
                       Partition[plist, 2, 1]), plist},
        InterpolationOrder -> 3];
  tlen = Last@First@First@(arc);
  Table[ arc[tlen iz / n], {iz, 0, n}]];
ListPlot[
       linepoints[
          First@(First@Cases[FullForm[ p1], Line[__], Infinity]),  25],
       PlotMarkers -> ({Graphics@Circle[{0, 0}], .025})]

enter image description here

A nice illustration comparing equal spaced points vs a more simple ListPlot[Table]] approach:

p1 = Plot[Cos[x^2], {x, 0, Pi}];
Show[
 {ListPlot[
     linepoints[First@(First@Cases[FullForm[ p1], Line[__], Infinity]), 
     120], PlotMarkers -> ({Graphics@Circle[{0, 0}], .025})],
  ListPlot[Table[{x, -Cos[x^2]}, {x, 0, Pi, 2 Pi/120}], 
          PlotMarkers -> ({Graphics@Rectangle[{0, 0}], .025})]}, 
    PlotRange -> All]

enter image description here

$\endgroup$
1
  • 2
    $\begingroup$ Very nice! One big advantage is that your approach is independent of the AspectRatio of the figure, while mine only works in true aspect ratio, though that shouldn't be hard to adjust. It might be work mentioning that your interpolated function arc has the form arc[s]={x,y}, where s is distance traveled along the arc and {x,y} is the resulting point, i.e. it is exactly the arc length parametrization. $\endgroup$ Commented Dec 27, 2013 at 1:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.