1
$\begingroup$

I have a graph that I made that has 2 sets of data, and plots these as 2 lines using LineLinePlot, does some simple calculations and writes these as an Epilog on the plot.

enter image description here

However, this was done by hand, there's just 2 sets of all the code. Which made me start thinking, how would I go about generalising this to n-many data sets, so I could just enter the stack of data, and the code would produce that line and it's calculations and epilog box (I appreciate I might run into problems with limited space on the graph to put the epilog boxes - I guess they could be put to the right hand side off the graph)

Would it use a loop in some way?

Current 'manual' version for 2 lines included below (minimised where i can):

dataSet = {{63, 1.26}, {92, 1.74}, {156, 1.88}, {250, 2.33}, {317, 
    2.69}, {351, 2.85}, {357, 3.42}, {391, 3.43}, {422, 3.44}};
dataSet2 = {{50, 0.55}, {167, 1.6}, {169, 2.47}, {182, 3.2}, {227, 
    3.32}, {232, 3.39}, {262, 3.91}, {281, 1.26}, {310, 1.74}, {374, 
    1.88}, {468, 2.33}, {535, 2.69}, {575, 3.42}, {609, 3.43}, {640, 
    3.44}};

set[1] = Cases[dataSet, {x_, y_} /; x < 423];
set[2] = Cases[dataSet2, {x_, y_} /; x < 263];
set[3] = Cases[dataSet2, {x_, y_} /; x > 264];


avgCurrent = 
 Integrate[
     Interpolation[dataSet, InterpolationOrder -> 1][x], {x, 
      dataSet[[1, 1]], dataSet[[-1, 1]]}]/(Subtract @@ 
      dataSet[[{-1, 1}, 1]]) // N // SetPrecision[#, 3] &
maxCurrent = MaximalBy[dataSet, Last][[1, 2]];
noPoints = Length[dataSet];
lifeTime = dataSet[[-1, 1]];

avgCurrent2 = 
 Integrate[
     Interpolation[dataSet2, InterpolationOrder -> 1][x], {x, 
      dataSet2[[1, 1]], dataSet2[[-1, 1]]}]/(Subtract @@ 
      dataSet2[[{-1, 1}, 1]]) // N // SetPrecision[#, 3] &
maxCurrent2 = MaximalBy[dataSet2, Last][[1, 2]];
noPoints2 = Length[dataSet2];
lifeTime2 = dataSet2[[-1, 1]];

ListLinePlot[{set[1], set[2], set[3]}, 
 PlotRange -> {{0, 700}, {0, 6}}, 
 PlotStyle -> {Directive[RGBColor[0.4, 0.5, 0.6], 
    AbsoluteThickness[2.5]], 
   Directive[RGBColor[0.8, 0.5, 0.6], AbsoluteThickness[2.5]], 
   Directive[RGBColor[0.8, 0.5, 0.6], AbsoluteThickness[2.5]]}, 
 PlotTheme -> "Detailed", 
 Epilog -> {{Blue, AbsolutePointSize[4], Point[dataSet]}, {Dashed, 
    Line[{{262, 3.91`}, {281, 1.26`}}]}, {Purple, 
    AbsolutePointSize[4], Point[dataSet2]}, 
   Inset[Framed[
     Grid[{{Style["Cathode 284 - Drilled", 
         Bold]}, {"Average Current: ", avgCurrent, 
        " \[Mu]A"}, {"Maximum Current: ", maxCurrent, 
        " \[Mu]A"}, {"Active Cathode Lifetime: ", lifeTime, 
        "minutes"}, {"Number of Data Points: ", noPoints}}], 
     Background -> White, RoundingRadius -> 5], Scaled[{.40, .85}]], 
   Inset[Framed[
     Grid[{{Style["Cathode 285 - Undrilled", Bold, 
         TextAlignment -> Center]}, {"Average Current: ", avgCurrent2,
         " \[Mu]A"}, {"Maximum Current: ", maxCurrent2, 
        " \[Mu]A"}, {"Active Cathode Lifetime: ", lifeTime2, 
        "minutes"}, {"Number of Data Points: ", noPoints2}}], 
     Background -> White, RoundingRadius -> 5], Scaled[{.80, .85}]]}, 
 PlotLabel -> 
  "Current Yield: Drilled Iron Cathode vs. Undrilled Iron Cathode", 
 PlotLegends -> 
  Placed[LineLegend[{"Iron (Cathode 284 - Drilled)", 
     "Iron (Cathode 285 - Undrilled)"}, 
    LegendFunction -> "Panel"], {0.80, 0.28}], 
 LabelStyle -> {Black, Bold}, Frame -> {{True, False}, {True, False}},
  FrameLabel -> {"Cathode Runtime (minutes)", "Current (\[Mu]A)"}, 
 ImageSize -> {550, 550}, InterpolationOrder -> 1]
$\endgroup$
3
  • $\begingroup$ maxCurrent2 is nowhere defined. $\endgroup$ Nov 28, 2022 at 11:35
  • $\begingroup$ It's defined on this line, I think: maxCurrent2 = MaximalBy[dataSet2, Last][[1, 2]]; $\endgroup$
    – Epideme
    Nov 28, 2022 at 12:03
  • $\begingroup$ Okay, I've tried using something closer to my actual code, which definitely works $\endgroup$
    – Epideme
    Nov 28, 2022 at 12:06

1 Answer 1

1
$\begingroup$
Clear["Global`*"]

n = 2;

Use indexed variables, e.g., dataSet[2] rather than dataSet2. This will facilitate mapping of repetitive code.

dataSet[1] = {{63, 1.26}, {92, 1.74}, {156, 1.88}, {250, 2.33}, {317, 
    2.69}, {351, 2.85}, {357, 3.42}, {391, 3.43}, {422, 3.44}};
dataSet[2] = {{50, 0.55}, {167, 1.6}, {169, 2.47}, {182, 3.2}, {227, 
    3.32}, {232, 3.39}, {262, 3.91}, {281, 1.26}, {310, 1.74}, {374, 
    1.88}, {468, 2.33}, {535, 2.69}, {575, 3.42}, {609, 3.43}, {640, 3.44}};

Automatically detect the break in the data

data = Sequence @@@ (Split[#, #1[[2]] < #2[[2]] &] & /@ (dataSet /@ 
       Range[n]));

Evaluate[set /@ Range[Length@data]] = data;

(avgCurrent[#] =
     SetPrecision[
      Integrate[
        Interpolation[dataSet[#],
          InterpolationOrder -> 1][x],
        {x, dataSet[#][[1, 1]], dataSet[#][[-1, 1]]}]/
       (Subtract @@ dataSet[#][[{-1, 1}, 1]]),
      3]) & /@
  Range[n];

(maxCurrent[#] =
     MaximalBy[dataSet[#], Last][[1, 2]]) & /@ Range[n];
(noPoints[#] =
     Length[dataSet[#]]) & /@ Range[n];
(lifeTime[#] =
     dataSet[#][[-1, 1]]) & /@ Range[n];

Plotting,

ListLinePlot[data,
 PlotRange -> {{0, 700}, {0, 6}},
 PlotStyle -> (
   Directive[RGBColor[#, 0.5, 0.6],
      AbsoluteThickness[2.5]] & /@
    {0.4, 0.8, 0.8}),
 PlotMarkers -> (Style["●", #, 8] & /@
    {Blue, Purple, Purple}),
 PlotTheme -> "Detailed",
 Epilog -> {
   {Dashed, Line[{Last@set[2], First@set[3]}]},
   Inset[
      Framed[
       Grid[{
         {Style[#[[2]], Bold, TextAlignment -> Center]},
         {"Average Current: ", avgCurrent[#[[1]]], " μA"},
         {"Maximum Current: ", maxCurrent[#[[1]]], " μA"},
         {"Active Cathode Lifetime: ", lifeTime[#[[1]]], "minutes"},
         {"Number of Data Points: ", noPoints[#[[1]]]}}],
       Background -> White, RoundingRadius -> 5],
      Scaled[{#[[3]], .85}]] & /@ {
     {1, "Cathode 284 - Drilled", 0.4},
     {2, "Cathode 285 - Undrilled", 0.8}}},
 PlotLabel ->
  "Current Yield: Drilled Iron Cathode vs. Undrilled Iron Cathode", 
 PlotLegends ->
  Placed[
   LineLegend[{
     "Iron (Cathode 284 - Drilled)",
     "Iron (Cathode 285 - Undrilled)"},
    LegendFunction -> "Panel"],
   {0.8, 0.25}],
 LabelStyle -> {Black, Bold},
 Frame -> {{True, False}, {True, False}},
 FrameLabel -> {"Cathode Runtime (minutes)", "Current (μA)"},
 ImageSize -> 550,
 InterpolationOrder -> 1]

enter image description here

$\endgroup$
1
  • $\begingroup$ Okay, so for the most part, it's replace variable# for variable[#]? Thanks for the help :) $\endgroup$
    – Epideme
    Dec 1, 2022 at 9:45

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.