3
$\begingroup$

I have a matrix called sigmaelement

sigmaelement[[All, a, e]] = Ce.Belement[[All, All, e]].ELd[[All, e]];

sigmaelement[[1,All,1]] will have values I want to contour plot

I also have a matrix called

coordinates = {{x1,y1}, {x2,y2}} 

When I look at the documentation, I find an example like

ListContourPlot[Table[Sin[i + j^2], {i, 0, 3, 0.1}, {j, 0, 3, 0.1}]]

but in my case, instead of Sin[i+j^2], I want to use sigmaelement[[1, All, 1]]. and instead of i and j, I want to use coordinates.

Could you tell me what could be the answer?

$\endgroup$
3
  • 2
    $\begingroup$ Is Length @ sigmaelement[[1, All, 1]] the same as Length @ coordinates? I.e. are coordinates ordered to match sigmaelement[[1, All, 1]]? $\endgroup$ Jan 4 '17 at 14:41
  • $\begingroup$ Yes @MariusLadegårdMeyer they match $\endgroup$
    – user45055
    Jan 4 '17 at 14:42
  • $\begingroup$ ListContourPlot[ Transpose@{coordinates, sigmaElement[[1,All,1]]} /. {{x_, y_}, z_} -> {x, y, z}] $\endgroup$
    – BlacKow
    Jan 4 '17 at 14:45
3
$\begingroup$

You have to get your data into the form

{{x1, y1, sigmaelement1},{x2, y2, sigmaelement2}, ..., {xn, yn, sigmaelementn}}

ListContourPlot doesn't require the coordinates to be a rectangular array, but it gives better results when they are.

Since you don't supply any usable data, I will contrive some.

coordinates = Catenate @ CoordinateBoundsArray[{{0, 9}, {0, 9}}];
coordinates // Short

{{0, 0}, {0, 1}, {0, 2}, {0, 3}, <<92>>, {9, 6}, {9, 7}, {9, 8}, {9, 9}}

SeedRandom[42]; sigmaelement = RandomReal[1., 100];
sigmaelement // Short

{0.425905, <<98>>, 0.0792812}

Now I put the two lists, coordinates and sigmaelement into the form needed. I show two ways to do this.

data = MapThread[{#1[[1]], #1[[2]], #2} &, {coordinates, sigmaelement}];
data = {#1[[1]], #1[[2]], #2} & @@@ Transpose[{coordinates, sigmaelement}];
data // Short

{{0, 0, 0.425905}, <<98>>, {9, 9, 0.0792812}}

Now the contour plot is very simple.

ListContourPlot[data]

plot

$\endgroup$
2
  • $\begingroup$ Thank you for your answer @m_goldberg. I understand your first way which is data = MapThread[{#1[[1]], #1[[2]], #2} &, {coordinates, sigmaelement}]; but the problem is my x coordinate matrix dimension is 1x231x2 in fact I have 1 row 231 columns but since I have two elements third dimension is for 2 elements. I have 231 x coordinates for element 1 and other 231 x coordinates for element 2 ; similarly y coordinate matrix dimension is 1x231x2 and my sigmaelement matrix dimension is 3x231x2; here I want to use only first row 1x231x2. How could we arrange MapThread ? $\endgroup$
    – user45055
    Jan 6 '17 at 6:05
  • $\begingroup$ @m_goldberg, I was analyzing your answer. I found your answer was so amazing and enjoyable! $\endgroup$ Jan 7 '17 at 18:52
4
$\begingroup$

The second form of ListContourPlot expects a list of triplets: {{x1,y1,f1},{x2,y2,f2},...}. So your question is how to combine two lists coordinates and values=sigmaelement[[1,All,1]] in one list of correct form. There are many possible ways to do this.

Straightforward using Table:

tab[coordinates_, values_]:= Table[{coordinates[[i, 1]], coordinates[[i, 2]], values[[i]]}, {i, 1, Length@values}]

Using Transpose and mapping transformation function over the list:

map[coordinates_, values_]:={#1[[1, 1]], #1[[1, 2]], #[[2]]} & /@Transpose@{coordinates, values};

or using replacement rules (in my opinion this one is the most clear):

repl[coordinates_, values_]:=Transpose@{coordinates, values} /. {{x_, y_}, z_} -> {x, y, z}

or using Flatten (thanks to @corey979):

cor1[coordinates_, values_]:=Flatten[#, 1] & /@ Transpose[{coordinates, values}]

or using ArrayReshape (thanks to @corey979 again):

cor2[coordinates_, values_]:=ArrayReshape[Transpose@{coordinates, values}, {Length@values, 3}]

Using MapThread to avoid transposing

mapTr[coordinates_, values_]:=MapThread[#1~Join~{#2} &, {coordinates, values}]

Since we have many options let's run quick performance benchmark for $10^6$ elements. I added two other functions from @m_goldberg's answer.

genData[n_] := {RandomReal[1.0, {n, 2}], RandomReal[1.0, {n}]};
funList = {tab, map, mapTr, cor1, cor2, repl, mg1, mg2};    
timingFun[funList_, {c_, v_}] := First@AbsoluteTiming[#[c, v]] & /@ funList;
timings = timingFun[funList, genData[10^6]]    
BarChart[{timings}, ChartElementFunction -> "GlassRectangle", 
 ChartStyle -> "Pastel", ChartLabels -> funList]

enter image description here

So Table is a clear winner.

$\endgroup$
2
  • 1
    $\begingroup$ Also Flatten[#, 1] & /@ Transpose[{coordinates, values}] and ArrayReshape[Transpose@{coordinates, values}, {Length@values, 3}]. $\endgroup$
    – corey979
    Jan 4 '17 at 15:41
  • $\begingroup$ I don't know if this applies to the OP or not, but if the coordinates form a rectangular grid, then it is better to use the ListContourPlot[array] form, as you get better interpolation. $\endgroup$
    – Jason B.
    Jan 4 '17 at 17:04

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.