1

I have a dataset (available at the bottom of this post) named q which illustrates 70 (x,y) coordinates to study electric fields around charges (7 electric field value, therefore 10 coordinate per given electric field). I want to draw equipotential lines for every electric field. Here is the scatter plot of that data using ggplot2: enter image description here You can clearly see where the lines should be drawn if you were to trace them (on a per series basis).

After coming across this post, I tried using the geom_density2d but here is what I get:enter image description here

Changing the h parameter did not have the desired effect either: enter image description here How could I get ggplot2s geom_density2d to display a single line per series and have that line be as close as possible to my data?

P.S. Here is the original data (in a csv format):

"E";"x";"y";"Voltage"
"E=4.368 (V)"; 33;-6;4.368
"E=4.368 (V)"; 39;-16;4.368
"E=4.368 (V)"; 54;-22;4.368
"E=4.368 (V)"; 66;-17;4.368
"E=4.368 (V)"; 70;-14;4.368
"E=4.368 (V)"; 71;-2;4.368
"E=4.368 (V)"; 36;6;4.368
"E=4.368 (V)"; 51;12;4.368
"E=4.368 (V)"; 64;13;4.368
"E=4.368 (V)"; 70;4;4.368
"E=3.745 (V)";  6;-69;3.745
"E=3.745 (V)"; 44;-48;3.745
"E=3.745 (V)"; 64;-35;3.745
"E=3.745 (V)"; 77;-15;3.745
"E=3.745 (V)"; 80;-2;3.745
"E=3.745 (V)"; 78;8;3.745
"E=3.745 (V)"; 71;22;3.745
"E=3.745 (V)"; 63;30;3.745
"E=3.745 (V)"; 46;40;3.745
"E=3.745 (V)"; 24;46;3.745
"E=3.120 (V)"; 64;-90;3.120
"E=3.120 (V)"; 70;-73;3.120
"E=3.120 (V)"; 74;-58;3.120
"E=3.120 (V)"; 80;-45;3.120
"E=3.120 (V)"; 88;-18;3.120
"E=3.120 (V)"; 89;-2;3.120
"E=3.120 (V)"; 88;10;3.120
"E=3.120 (V)"; 84;29;3.120
"E=3.120 (V)"; 75;49;3.120
"E=3.120 (V)"; 68;66;3.120
"E=2.495 (V)";102;-96;2.495
"E=2.495 (V)";101;-73;2.495
"E=2.495 (V)";101;-44;2.495
"E=2.495 (V)";102;-22;2.495
"E=2.495 (V)";101;-1;2.495
"E=2.495 (V)";101;10;2.495
"E=2.495 (V)";100;25;2.495
"E=2.495 (V)";100;39;2.495
"E=2.495 (V)";100;48;2.495
"E=2.495 (V)"; 99;52;2.495
"E=1.870 (V)";139;-89;1.870
"E=1.870 (V)";132;-66;1.870
"E=1.870 (V)";124;-46;1.870
"E=1.870 (V)";115;-24;1.870
"E=1.870 (V)";112;-5;1.870
"E=1.870 (V)";114;18;1.870
"E=1.870 (V)";115;23;1.870
"E=1.870 (V)";123;41;1.870
"E=1.870 (V)";127;54;1.870
"E=1.870 (V)";131;69;1.870
"E=1.247 (V)";175;-53;1.247
"E=1.247 (V)";158;-47;1.247
"E=1.247 (V)";142;-37;1.247
"E=1.247 (V)";127;-20;1.247
"E=1.247 (V)";121;-6;1.247
"E=1.247 (V)";124;11;1.247
"E=1.247 (V)";140;30;1.247
"E=1.247 (V)";145;34;1.247
"E=1.247 (V)";155;39;1.247
"E=1.247 (V)";168;45;1.247
"E=0.625 (V)";149;-21;0.625
"E=0.625 (V)";157;-20;0.625
"E=0.625 (V)";137;-16;0.625
"E=0.625 (V)";164;-15;0.625
"E=0.625 (V)";131;-8;0.625
"E=0.625 (V)";169;-5;0.625
"E=0.625 (V)";167;7;0.625
"E=0.625 (V)";161;14;0.625
"E=0.625 (V)";137;18;0.625
"E=0.625 (V)";149;20;0.625
Benjamin Chausse
  • 1,437
  • 2
  • 10
  • 20
  • 1
    Are you saying that you want to plot a line running through each group (by color) of points that are displayed in the first figure? – Dodge Oct 13 '19 at 02:37
  • 1
    @Dodge Yes! But a simple line (`geom_line` or `geom_smooth`) would require R to consider that each series is a function (a **single** value of `y` for every given `x`. That is however not the case with 2d electrical fields maps... – Benjamin Chausse Oct 13 '19 at 04:03

1 Answers1

1

So this might be a partial answer on how to plot this, and there are some drawbacks. The solution to the geom_smooth / geom_line problems, may be in geom_path, which doesn't require the datapoints to be ordered along the y-axis, but it does require it to be ordered in the data.

A solution with geom_path might look as follows (assume zz is the data you posted enclosed with quote characters):

df <- read.csv(text = zz, sep = ";", header = F)

ggplot(df, aes(V2, V3, colour = V1)) +
  geom_point() + # For visualisation purposes
  geom_path()

enter image description here

Now obviously, this is not ideal. From your earlier examples, I would assume you would like some smoothing of the path between the points. Secondly, since the E=0.625 (V) group is not ordered along the path we would expect, this group doesn't display nicely.

To solve the first problem, we could fit splines instead of paths using the ggforce package:

library(ggforce)
ggplot(df, aes(V2, V3, colour = V1)) +
  geom_point() +
  geom_bspline()

enter image description here

To solve the second problem, you would have to reorder the data, in the example below I did it manually, but perhaps there might be an easier way.

# Note that the 27th row is included twice to close the ellipse
df2 <- df[c(1:27, 29, 31, 35, 36, 34, 33, 32, 30, 28, 27),]

ggplot(df2, aes(V2, V3, colour = V1)) +
  geom_point() +
  geom_bspline()

enter image description here

Also, you could try and implement what they did here.

teunbrand
  • 33,645
  • 4
  • 37
  • 63