2
$\begingroup$

I am using ListPlot to plot a set a data, as shown below. However, I don't want any joining line between two points {-0.1, 0.042} and {0.1, 0.042} crossing the y-axis. Could you suggest any way to do that?

ARRAY = {{-1, 0.235}, {-0.4, 0.23}, {-0.3, 0.21}, {-0.2, 
   0.15849025910785963`}, {-0.1, 0.042}, {0.1, 0.042}, {0.2, 
   0.158}, {0.3, 0.214}, {0.4, 0.233}, {0.9, 0.235}}


ListPlot[ARRAY, Joined -> True, Mesh -> All]

$\endgroup$
3
  • 4
    $\begingroup$ try ListPlot[SplitBy[ARRAY, Sign@*First], Joined -> True, Mesh -> All]? $\endgroup$
    – kglr
    Sep 1, 2022 at 21:13
  • $\begingroup$ @kglr Thanks. It worked. However, if there are two arrays (e.g. ListPlot[{ARRAY1,ARRAY2}, Joined -> True, Mesh -> All]), it does not work. Any suggestion, please? $\endgroup$
    – PoreyS
    Sep 1, 2022 at 22:27
  • 1
    $\begingroup$ @PoreyS Please post {ARRAY1,ARRAY2} in the question. $\endgroup$
    – cvgmt
    Sep 2, 2022 at 10:20

3 Answers 3

4
$\begingroup$

Completing @kglr 's answer for several lists. Suppose the second list is array2=2 array. (Sorry, using uppercase for your symbols is bad programming practice because they may interfere with built-in symbols such as E, I, N, and others; get used to starting your symbols with lowercase). The code that does what you want is

ListPlot[Flatten[SplitBy[#, Sign@*First] & /@ {array, array2}, 1], 
 Joined -> True, Mesh -> All]

To explain, Sign@First gives the sign of the first element of each member of your list; but we use the Composition sign, @* to nest the commands. You could get the same result by making them into a pure fuction, replacing that part with Sign[First[#]]&. As the second argument of SplitBy, it splits your list and produces separate lists when the sign changes. Using # in the position where @kglr had your list and following with a & creates a pure function which can apply to any list. We could apply it to array by SplitBy[#,...]&@array but instead we thread it over each member of {array, array2} by following it with /@. So that Plot sees four lists, we flatten the result by one with Flatten[...,1]. If you want to make the two halves of each plot have the same color, then define them so, e.g., with PlotStyle->{Green,Green,Red,Red}.

$\endgroup$
3
$\begingroup$

Using the same data as @NicholasG, another variant could be to do post processing.

array = {{-1, 0.235}, {-0.4, 0.23}, {-0.3, 0.21}, {-0.2, 
   0.15849025910785963`}, {-0.1, 0.042}, {0.1, 0.042}, {0.2, 
   0.158}, {0.3, 0.214}, {0.4, 0.233}, {0.9, 0.235}}
array2 = 2 array


ListLinePlot[{array, array2}
  , PlotStyle -> {Red, Darker@Green}
  , PlotLegends -> Placed[
    LineLegend[{Red, Darker@Green}, {"a1", "a2"}], {0.8, 0.2}]
  , Epilog -> {
    AbsolutePointSize[5]
    , Red, Point /@ array
    , Darker@Green, Point /@ array2
    }
  ] /. Line[j__] :> Line[SplitBy[j, Sign@*First]]

enter image description here

$\endgroup$
3
$\begingroup$
L = ListPlot[ARRAY[[#, All]] & /@ {1 ;; 5}, Joined -> True, Mesh -> All, PlotStyle -> Red];

R = ListPlot[ARRAY[[#, All]] & /@ {6 ;; 10}, Joined -> True, Mesh -> All];

Show[R, L, PlotRange -> Full]

enter image description here

$\endgroup$

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.