2
$\begingroup$

I would like to fit my set of data (x = time and y = power) as seen below, and obtain function of x describing it as close as possible, in order to manipulate it (applying different SOC, time offsets etc.)

DATA:

data = {{0.351011, 0}, {15.0925, 0}, {35.1011, 0}, {56.8647, 0}, {83.5416, 
  0}, {83.9374, 0.377001}, {84.7178, 1.04716}, {84.4518, 
  1.77324}, {85.2182, 2.32372}, {85.2686, 2.75457}, {94.3968, 
  2.76988}, {102.469, 2.76132}, {102.084, 2.47412}, {102.694, 
  1.68418}, {102.603, 0.902273}, {103.249, 0.423504}, {102.872, 
  0.208105}, {104.253, 0.00853878}, {111.976, 0.0159698}, {112.712, 
  0.303152}, {113.476, 0.837672}, {113.207, 1.53184}, {112.926, 
  2.13026}, {113.673, 2.51319}, {115.106, 2.76841}, {133.714, 
  2.799}, {170.22, 2.80439}, {224.627, 2.80053}, {258.324, 
  2.79814}, {260.437, 2.86182}, {262.188, 2.82181}, {283.596, 
  2.79635}, {304.659, 2.81081}, {307.443, 2.60317}, {308.118, 
  2.37174}, {310.195, 2.12425}, {312.284, 1.98049}, {313.322, 
  1.85275}, {316.109, 1.66905}, {318.55, 1.53323}, {320.99, 
  1.38944}, {323.43, 1.23768}, {326.575, 1.11777}, {331.472, 
  0.973807}, {334.968, 0.853878}, {340.221, 0.749782}, {343.367, 
  0.637857}, {349.325, 0.557647}, {350.353, 0.342149}, {351.026, 
  0.0947606}, {352.419, 0}, {360.141, 0}, {382.607, 0}, {408.229, 
  0}, {437.013, 0}, {449.65, 0}}

Charging curve

I have tried something like this:

d1 = Import[
   "C:/Users/Tomáš/Desktop/data.csv", {"Data", {1, 2, 3, 4, 5}}];
d2 = Import[
   "C:/Users/Tomáš/Desktop/data.csv", {"Data", {10, 11, 12, 25, 26, 
     27, 28, 29, 30, 31, 32, 33, 34}}];
d3 = Import[
   "C:/Users/Tomáš/Desktop/data.csv", {"Data", {34, 35, 36, 37, 38, 
     39, 40, 41, 42, 43, 44, 45, 46, 47, 48}}];
d4 = Import["C:/Users/Tomáš/Desktop/data.csv", {"Data", {48, 49, 50}}];

f1 = LinearModelFit[d1, 1, x];
f2 = LinearModelFit[d2, {1, x}, x];
f3 = LinearModelFit[d3, {0.557647 + (x - 349.325)^2}, x];
f4 = LinearModelFit[d4, {1, (x - 352.419)^-1}, x];

y = If[((0 < x <= 83.5416) || 
     102.469 < x <= 113.673 || (351.026 < x)), f1[x] ,     
   If[((83.5416 < x <= 102.469) || (113.673 < x <= 304.659)), f2[x], 
    If[(304.659 < x < 349.325), f3[x], f4[x]]]];
Plot[y, {x, 0, 500}]

but it does not cooperate with Manipulate. Any suggestions?

Thank you. TZ

$\endgroup$
  • $\begingroup$ Welcome to Mathematica.SE! I suggest the following: 1) As you receive help, try to give it too, by answering questions in your area of expertise. 2) Take the tour! 3) When you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge. Also, please remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign! $\endgroup$ – Michael E2 Mar 14 '16 at 23:01
  • $\begingroup$ Perhaps you might be better off with an Interpolation? Alternatively, we would have to have access to the data to be able to try anything. Can you include it in your question, or put it up on e.g. pastebin.com? $\endgroup$ – MarcoB Mar 15 '16 at 21:43
  • $\begingroup$ I am sorry, i forgot to include it, it is there now. Interpolation does not cooperate with Manipulate as well. $\endgroup$ – Tomáš Zajac Mar 15 '16 at 22:28
  • $\begingroup$ Also, there are going to be multiple of these in one plot, with different time offsets, and I must be able to sum them in every moment. $\endgroup$ – Tomáš Zajac Mar 15 '16 at 22:34
1
$\begingroup$

Your data looks like two square waves except the right hand side of the second has a curved portion.

This answer will help you with the problem you are experiencing plotting y. I am not sure it is really useful for your actual problem.

Using your data there were nine apparent boundaries located at these positions.

boundaries = {{1, 5}, {5, 10}, {10, 12}, {12, 18}, {19, 25}, {25, 
   33}, {33, 48}, {48, 51}, {51, 56}}

This is what it looks like when you plot the data at those boundaries.

ListLinePlot[
 Map[data[[boundaries[[#]][[1]] ;; boundaries[[#]][[2]]]] &, 
  Range[Length[boundaries]]]]

Mathematica graphics

A straight line was created that connected the end points of the boundaries with the exception of interval #7. For that one a parabola was used.

f1 = LinearModelFit[
  data[[{boundaries[[1]][[1]], boundaries[[1]][[2]]}]], {1, x}, x]
f2 = LinearModelFit[
  data[[{boundaries[[2]][[1]], boundaries[[2]][[2]]}]], {1, x}, x]
f3 = LinearModelFit[
  data[[{boundaries[[3]][[1]], boundaries[[3]][[2]]}]], {1, x}, x]
f4 = LinearModelFit[
  data[[{boundaries[[4]][[1]], boundaries[[4]][[2]]}]], {1, x}, x]
f5 = LinearModelFit[
  data[[{boundaries[[5]][[1]], boundaries[[5]][[2]]}]], {1, x}, x]
f6 = LinearModelFit[
  data[[{boundaries[[6]][[1]], boundaries[[6]][[2]]}]], {1, x}, x]
f7 = LinearModelFit[
  data[[boundaries[[7]][[1]] ;; boundaries[[7]][[2]]]], {1, x, x^2}, x]
f8 = LinearModelFit[
  data[[{boundaries[[8]][[1]], boundaries[[8]][[2]]}]], {1, x}, x]
f9 = LinearModelFit[
  data[[{boundaries[[9]][[1]], boundaries[[9]][[2]]}]], {1, x}, x]

Now for how to make this into a function. In principle one could use Piecewise but I found some of the data was not connected. So I ended up using Which.

The key point for you I think is to define a function of x using SetDelayed.

f[x_] := Which[
  x <= data[[boundaries[[1, 2]], 1]], f1[x],
  data[[boundaries[[2, 1]], 1]] < x <= data[[boundaries[[2, 2]], 1]], 
  f2[x],
  data[[boundaries[[3, 1]], 1]] < x <= data[[boundaries[[3, 2]], 1]], 
  f3[x],
  data[[boundaries[[4, 1]], 1]] < x <= data[[boundaries[[4, 2]], 1]], 
  f4[x],
  data[[boundaries[[5, 1]], 1]] < x <= data[[boundaries[[5, 2]], 1]], 
  f5[x],
  data[[boundaries[[6, 1]], 1]] < x <= data[[boundaries[[6, 2]], 1]], 
  f6[x],
  data[[boundaries[[7, 1]], 1]] < x <= data[[boundaries[[7, 2]], 1]], 
  f7[x],
  data[[boundaries[[8, 1]], 1]] < x <= data[[boundaries[[8, 2]], 1]], 
  f8[x],
  data[[boundaries[[9, 1]], 1]] < x, f9[x]
  ]

Now this can be treated just as any other function, including plotting it.

Show[
 ListLinePlot[data, PlotStyle -> Black],
 Plot[f[x], {x, 0, 450}, PlotStyle -> Red]
 ]

Mathematica graphics

$\endgroup$
  • $\begingroup$ For the most part your solution works, thank you. I will aply it to other data I have and try to plot and sum them. $\endgroup$ – Tomáš Zajac Mar 16 '16 at 12:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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