3
$\begingroup$

I have 2d data in the form {x,y,f(x,y)} which is randomly stored. the random {x,y} for specific shape (square for simplification here) can be created as

Regn = {{-\[Pi], -\[Pi]}, {-\[Pi], \[Pi]}, {\[Pi], \[Pi]}, {\[Pi], -\
\[Pi]}, {-\[Pi], -\[Pi]}};
xylist=Select[RegionMember[Polygon@(Regn)]][
 Join @@ CoordinateBoundsArray[CoordinateBounds@(Regn), Into[50]]]

then these points are passed to a function f here it is just sin and we get

datxy = Table[{xylist[[i, 1]], xylist[[i, 2]], 
    Sin[xylist[[i, 1]] xylist[[i, 2]]]}, {i, 1, Length[xylist]}];
ListDensityPlot[datxy, ColorFunction -> "TemperatureMap"]   

enter image description here

my question is how can I plot the x or y derivative of such data?

Update

here I will compare the solution provided by the answers which indicate that the built-in interpolation gives bad results compared to the method provided by @Shin Kim

enter image description here

I used PlotPoints->50 in DensityPlot for the interpolated data

$\endgroup$
3
  • 1
    $\begingroup$ I think this is problem of interpolation on an unstructured set of data points. [This question]mathematica.stackexchange.com/q/235681/12558 should give you an interpolation function for your problem. You can then calculate the derivative as if you had an equation. $\endgroup$
    – Hugh
    Feb 16, 2022 at 12:51
  • $\begingroup$ @Hugh, I know how to use listinterpolate for structured data..but I don't understand how the mentioned question can do that? may you please elaborate? $\endgroup$
    – MMA13
    Feb 16, 2022 at 13:04
  • $\begingroup$ The comparison in the edit is useful. They all look the same to me. It may be you are after some smoothing for your derivatives -that would be a new question. If you have limited data you can't expect perfect derivatives. $\endgroup$
    – Hugh
    Feb 17, 2022 at 14:57

3 Answers 3

3
$\begingroup$

If you want to produce the derivatives directly using only the raw data,

(*w.r.t y*)
datxy = Sort[Sort[datxy, #1[[1]] < #2[[1]] &],
    Which[ #1[[1]] == #2[[1]] && #1[[2]] < #2[[2]], True,
           #1[[1]] == #2[[1]] && #1[[2]] > #2[[2]], False ] &];
Dy = {};
Do[If[datxy[[i, 1]] == datxy[[i + 1, 1]],
  AppendTo[Dy, Flatten@{datxy[[i, 1 ;; 2]], (datxy[[i + 1, {2, 3}]] - datxy[[i, {2, 3}]]) /. {dy_, df_} -> df/dy}]
 ], {i, Length@datxy - 1}]

(*w.r.t x*)
datxy = Sort[Sort[datxy, #1[[2]] < #2[[2]] &],
    Which[ #1[[2]] == #2[[2]] && #1[[1]] < #2[[1]], True,
           #1[[2]] == #2[[2]] && #1[[1]] > #2[[1]], False] &];
Dx = {};
Do[If[datxy[[i, 2]] == datxy[[i + 1, 2]],
  AppendTo[Dx, Flatten@{datxy[[i, 1 ;; 2]], (datxy[[i + 1, {1, 3}]] - datxy[[i, {1, 3}]]) /. {dx_, df_} -> df/dx}]
 ], {i, Length@datxy - 1}]

then form the gradient:

grad = {};
i = 1;
Do[
 Do[If[Dx[[i, 1 ;; 2]] == Dy[[j, 1 ;; 2]], 
   AppendTo[grad, {Dx[[i, 1 ;; 2]], {Dx[[i, 3]], Dy[[j, 3]]}}]],
 {j, Length@Dy}];
i++;
, Length@Dx]
ClearAll[i]

Following is a comparison with the actual gradient (right):

enter image description here

I coded this without any concern of performance, so there's a lot of room for optimization, if anyone's interested.

$\endgroup$
3
$\begingroup$

You can first calculate an interpolation of your data. As your arguments are not on a grid, only Interpolation order of 1 can be used:

fun = Interpolation[datxy, InterpolationOrder -> 1];

enter image description here

With a function we may now calculate the derivatives like:

derx[x_, y_] = D[fun[x, y], x]

enter image description here

dery[x_, y_] = D[fun[x, y], y]

enter image description here

$\endgroup$
1
  • $\begingroup$ the results are fuzzy? kindly, see my update $\endgroup$
    – MMA13
    Feb 17, 2022 at 14:24
2
$\begingroup$

Here is my suggestion for interpolation. I start by making your data.

Regn = {{-π, -π}, {-π, π}, {π, π}, {π, -\
π}, {-π, -π}};
xylist = Select[RegionMember[Polygon@(Regn)]][
   Join @@ CoordinateBoundsArray[CoordinateBounds@(Regn), Into[50]]];

datxy = Table[{xylist[[i, 1]], xylist[[i, 2]], 
    Sin[xylist[[i, 1]] xylist[[i, 2]]]}, {i, 1, Length[xylist]}];
ListDensityPlot[datxy, ColorFunction -> "TemperatureMap"]

enter image description here

I extract the coordinate points from your data and make a mesh.

pts = datxy /. {x_, y_, z_} :> {x, y};
Needs["NDSolve`FEM`"]
mesh = ToElementMesh[pts];

Now I interpolate the data and we can use the interpolated data as if it was an equation or function.

int = ElementMeshInterpolation[{mesh}, datxy[[All, 3]]];
Plot3D[int[x, y], {x, y} ∈ mesh]

enter image description here

To take the derivative we use the usual derivative operation.

dx = Head[D[int[x, y], x]];
Plot3D[dx[x, y], {x, y} ∈ mesh]

enter image description here

Possibly we need some smoothing after taking the derivative but that's another question. Hope that helps.

$\endgroup$
1
  • $\begingroup$ the results are fuzzy? kindly, see my update $\endgroup$
    – MMA13
    Feb 17, 2022 at 14:24

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.