4
$\begingroup$

I want to generate a square matrix of squares with parallel lines/stripes colored with different colors:

columnNumber = 10;
rowNumber = 10;
icolumn = 1;

Graphics[{EdgeForm[Black],
 Table[{
  If[(i == icolumn  || i == icolumn + 2 || i == icolumn + 4 ||
      i == icolumn + 6 || i == icolumn + 8),
   Blue,
   Green],
  Rectangle[{1.07*i, 1.07*j}]},
 {i, 1, columnNumber, 1.}, {j, 1, rowNumber, 1.}]},
AspectRatio -> 1, ImageSize -> 240]

Here is the result:

enter image description here

I substitute for the If condition,

(i == icolumn || i == icolumn+2 || i == icolumn+4 || i == icolumn+6 || i == icolumn+8)

the For loop

For[icol = 1, icol < 10, icol = icol + 2, If[i == icol, Blue, Green]]

like this:

Graphics[{EdgeForm[Black],
 Table[{
  For[icol = 1, icol < 10, icol = icol + 2,
   If[i == icol, Blue, Green]],
  Rectangle[{1.05*i, 1.05*j}]},
  {i, 1, columnNumber, 1}, {j, 1, rowNumber, 1}]},
 AspectRatio -> 1, ImageSize -> 240]

But then it returns a black image:

enter image description here

Can anyone suggest what is wrong with my code that combines For and If?

$\endgroup$
  • $\begingroup$ Why must you use For[]? In any event: With[{rowNumber = 10, columnNumber = 10}, Graphics[{EdgeForm[Black], Table[{If[OddQ[i], Blue, Green], Rectangle[{1.07*i, 1.07*j}]}, {j, rowNumber}, {i, columnNumber}]}]] $\endgroup$ – J. M. will be back soon May 18 '17 at 12:14
  • $\begingroup$ J.M. thanks for replying. I thought it is simpler to implement. Do you have other suggestion? $\endgroup$ – surfAliq May 18 '17 at 12:18
  • $\begingroup$ Thanks for this suggestion but I want to use differnt periods, not only 2. For instance any integer number: period=3, 4,...: icol=icol+m*period. $\endgroup$ – surfAliq May 18 '17 at 12:21
  • $\begingroup$ Then, use Mod[] or something. $\endgroup$ – J. M. will be back soon May 18 '17 at 12:24
  • $\begingroup$ @J.M, thanks. But, I want to generate binary (two-color) periodic strip pattern with certain period (stripPeriod) and strip width (stripWidth). For instance for 4-line strip pattern with period of 11 lines I apply one-by-one the conditions (Mod[i, stripPeriod] == 0) || (Mod[i + 1, stripPeriod] == 0) || (Mod[i + 2, stripPeriod] == 0) || (Mod[i + 3, stripPeriod] == 0). $\endgroup$ – surfAliq May 19 '17 at 4:27
3
$\begingroup$

Try this for a start:

    lst = Table["", {i, 1, 10}, {j, 1, 10}];
lst1 = Flatten[Table[{{{1, 10}, {i, i}} -> Blue}, {i, 1, 10, 2}], 1];
lst2 = Flatten[Table[{{{1, 10}, {i, i}} -> Green}, {i, 2, 10, 2}], 1];
lst3 = Join[{None, None}, {Join[lst1, lst2]}];

Grid[lst, Dividers -> Directive[White, AbsoluteThickness[0.3]], 
 Background -> lst3, ItemSize -> {2, 2}]

returning this:

enter image description here

Have fun!

$\endgroup$
  • $\begingroup$ Thanks a lot Alexei Boulbitch !!! $\endgroup$ – surfAliq May 18 '17 at 13:43
  • $\begingroup$ @Alexei Boulbitch. Thanks!!! it is a nice solution for my initial question. But, in general I want to generate binary (two-color) periodic strip pattern with certain period (stripPeriod) and strip width (stripWidth). For instance for 4-line strip pattern with period of 11 lines I have to apply one-by-one the conditions (Mod[i, stripPeriod] == 0) || (Mod[i + 1, stripPeriod] == 0) || (Mod[i + 2, stripPeriod] == 0) || (Mod[i + 3, stripPeriod] == 0). $\endgroup$ – surfAliq May 19 '17 at 4:45
  • $\begingroup$ @Alexei Boulbitch. If I need strips with many lines, then I have to enter all the conditions one-by-one, which is kind of annoying. I am trying to get “condition generation” or in other words “strip generation” using stripWidth parameter in any kind of loop, but it does not work properly. Since the strips will also be tilted, I believe the best way would defining condition separately and then apply to generate Table, Matrix, Array or Grid. Is there any way to realize it? $\endgroup$ – surfAliq May 19 '17 at 4:47
  • $\begingroup$ @surfAliq That's what I have shown you. The formation of stripes is fixed by the list lst3. Now it is constructed of two sublists: lst1 giving the blue squares and lst2 giving the green ones. Check, how they are organized. If you need more stripes, make more such lists, and, of course, reorganize them correspondingly. $\endgroup$ – Alexei Boulbitch May 19 '17 at 7:01
3
$\begingroup$

In:

matrixPlot[xs_] := 
 MatrixPlot[xs, ColorRules -> {0 -> Green, 1 -> Blue}, Mesh -> All ]
matrixPlot@Array[Mod[#2, 2] &, {10, 10}]

Out:

Mathematica graphics

(Using ColorRules instead of ColorFunction, Thanks to J. M.)

$\endgroup$
  • $\begingroup$ ColorRules seems to be the more appropriate option here: MatrixPlot[Array[Mod[#2, 2] &, {10, 10}], ColorRules -> {1 -> Green, 0 -> Blue}, Mesh -> All] $\endgroup$ – J. M. will be back soon May 18 '17 at 19:32
3
$\begingroup$

You can use Array pretty much anywhere you can use Table, and when the input is naturally thought of as a function, it is more natural to use Array. In this case the function is

f = Function[{i, j}, {If[OddQ[i], Blue, Green], Rectangle[{1.05*i, 1.05*j}]}]

You can then create the 2d list of rectangles

arr = Array[f, {10, 10}];

and make your graphic:

Graphics[{EdgeForm[Black], arr}]

Naturally you could also use this function with Table, but it is more verbose:

arr2 = Table[f[i, j], {i, 10}, {j, 10}];
Graphics[{EdgeForm[Black], arr2}]

Edit:

Finally, as suggested by bill_s, you might find ArrayPlot adequate to your needs:

f3 = Function[{i, j}, If[OddQ[j], 0, 1]];
arr3 = Array[f3, {10, 10}]
ArrayPlot[arr3, ColorRules -> {0 -> Blue, 1 -> Green}, Mesh -> True, MeshStyle -> Black]

However, the display is a bit different, and you won't have direct access to your array of rectangles.

Edit:

You can change the function however you wish. E.g., To change the width of the strips to 4, just change the f3 to f4:

f4 = Function[{i, j}, If[EvenQ@Floor[(j - 1)/4], 0, 1]]
$\endgroup$
  • $\begingroup$ much better, Thanks! $\endgroup$ – rhermans May 18 '17 at 13:15
  • $\begingroup$ @surfAliq stackoverflow.com/help/someone-answers $\endgroup$ – Alan May 18 '17 at 15:33
  • $\begingroup$ @Alan. Thanks!!! it is a nice solution for my initial question. But, in general I want to generate binary (two-color) periodic strip pattern with certain period (stripPeriod) and strip width (stripWidth). For instance for 4-line strip pattern with period of 11 lines I have to apply one-by-one the conditions (Mod[i, stripPeriod] == 0) || (Mod[i + 1, stripPeriod] == 0) || (Mod[i + 2, stripPeriod] == 0) || (Mod[i + 3, stripPeriod] == 0). $\endgroup$ – surfAliq May 19 '17 at 4:41
  • $\begingroup$ @Alan. If I need strips with many lines, then I have to enter all the conditions one-by-one, which is kind of annoying. I am trying to get “condition generation” or in other words “strip generation” using stripWidth parameter in any kind of loop, but it does not work properly. Since the strips will also be tilted, I believe the best way would defining condition separately and then apply to generate Table, Matrix, Array or Grid. Is there any way to realize it? $\endgroup$ – surfAliq May 19 '17 at 4:43
  • $\begingroup$ @surfAliq See edit. $\endgroup$ – Alan May 19 '17 at 11:45
3
$\begingroup$

You mentioned wanting to do it for multiple patterns. Here is a 3-stripe version:

ArrayPlot[ConstantArray[Mod[Range[10], 3], 10],ColorFunction->"Rainbow", Mesh->True]

enter image description here

Change the Mod (change the 3) for a different number of stripes, the colorspace for the coloring, and the size of the array (change the 10) to achieve what you want.

If you want to specify an arbitrary pattern of columns, one approach is to do it with a simple list: for instance a two color pattern with 11 element might be:

pat = {0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1};
ArrayPlot[ConstantArray[pat, 10], ColorFunction -> "Rainbow", Mesh -> True]

enter image description here

Of course, you can generate the pat in many ways, depending on the exact pattern you want.

$\endgroup$
  • $\begingroup$ b@bill s Thanks!!! it is a nice solution for my initial question. But, I in general I want to generate binary (two-color) periodic strip pattern with certain period (stripPeriod) and strip width (stripWidth). For instance for 4-line strip pattern with period of 11 lines I have to apply one-by-one the conditions (Mod[i, stripPeriod] == 0) || (Mod[i + 1, stripPeriod] == 0) || (Mod[i + 2, stripPeriod] == 0) || (Mod[i + 3, stripPeriod] == 0). $\endgroup$ – surfAliq May 19 '17 at 4:32
  • $\begingroup$ If I need strips with many lines, then I have to enter all the conditions one-by-one, which is kind of annoying. I am trying to get “condition generation” or in other words “strip generation” using stripWidth parameter in any kind of loop, but it does not work properly. Since the strips will also be tilted, I believe the best way would defining condition separately and then apply to generate Table, Matrix, Array or Grid. Is there any way to realize it? $\endgroup$ – surfAliq May 19 '17 at 4:36
2
$\begingroup$

I made some changes to YOUR code

Graphics[{EdgeForm[Black], 
Table[{If[EvenQ@i, Green, Blue], Rectangle[{1.05*i, 1.05*j}]}, {i, 
columnNumber}, {j, rowNumber}]}, AspectRatio -> 1, 
ImageSize -> 240]

enter image description here

$\endgroup$
  • $\begingroup$ Dear ALL (J.M., Alexei Boulbitch, bill s, Alan, Jenny_mathy, UnchartedWorks) Many THANKS for your helps-suggestions!!!!!!!! They all are nice solution for my initial question. But, I want to generate binary (two-color) periodic strip pattern with certain period (stripPeriod) and strip width (stripWidth). For instance here I generate 4-line strip pattern with period of 11 lines by applying one-by-one the conditions (Mod[i, stripPeriod] == 0) || (Mod[i + 1, stripPeriod] == 0) || (Mod[i + 2, stripPeriod] == 0) || (Mod[i + 3, stripPeriod] == 0). $\endgroup$ – surfAliq May 19 '17 at 4:13
  • $\begingroup$ But if I need strips with many lines, then I have to enter all the conditions one-by-one, which kind of annoying. I am trying to get “condition generation” or in other words “strip generation” using stripWidth in loops, but it does not work properly. Since the strips will also be tilted, believe the best way would defining condition separately and then apply to generate Table, Matrix or Array. $\endgroup$ – surfAliq May 19 '17 at 4:14
  • $\begingroup$ columnNumber = 40; rowNumber = 15; stripPeriod = 11; stripWidth = 3;(I want to use this parameter in condition) Graphics[{EdgeForm[Black], Table[{If [(Mod[i, stripPeriod] == 0) || (Mod[i + 1, stripPeriod] == 0) || (Mod[i + 2, stripPeriod] == 0) || (Mod[i + 3, stripPeriod] == 0), Blue, Green], Rectangle[{1.07*i, 1.07*j}]}, {i, 1, columnNumber, 1.}, {j, 1, rowNumber, 1.}]}, AspectRatio -> rowNumber/columnNumber, ImageSize -> 500] $\endgroup$ – surfAliq May 19 '17 at 4:16
1
$\begingroup$

If you're contemplating complicated coloring patterns, as seems to be the case in the comments, I would suggest creating a function to compute the color of the i,j rectangle.

colorfn[i_, j_] := < your code here >;

Graphics[{EdgeForm[Black],
 Table[{
  colorfn[i, j],
  Rectangle[{1.07*i, 1.07*j}]},
 {i, 1, columnNumber, 1.}, {j, 1, rowNumber, 1.}]},
AspectRatio -> 1, ImageSize -> 240]

For example, the following, with an extra error check, reproduces the OP's figure:

colorfn[i_, j_] :=
  If[(i == icolumn  || i == icolumn + 2 || i == icolumn + 4 ||
      i == icolumn + 6 || i == icolumn + 8),
   Blue,
   Green,
   Red];  (* should not happen; if Red shows up, there's a coding error somewhere *)

See If for an explanation of the fourth argument.

$\endgroup$
  • $\begingroup$ Thanks for this suggestion. Still inside If I have to add all the conditions one-by-one, whereas I wanted to do it with For, but it turns out For is not the best option. $\endgroup$ – surfAliq May 19 '17 at 14:52
  • 2
    $\begingroup$ @surfAliq You're welcome. (1) No one who knows Mathematica wants to use For :) -- there are usually better alternatives. (2) You have to write the colorfn[] code the way you want; I just used your code as an example of how to use a colorfn. J.M. showed you a way to avoid the conditions one-by-one (usuing OddQ[] or Mod[]), but it's hard to show a generic way except in a particular example. E.g {Red, Green, Blue}[[ Mod[i, 3, 1] ]] will cycle through the three colors. Or more generally colorlist[[ Mod[i, Length@colorlist, 1] ]], where colorlist is a list of colors, if desired. $\endgroup$ – Michael E2 May 19 '17 at 15:33
0
$\begingroup$

Finally I got four solutions: via ArrayPlot, Graphics, MatrixPlot, and Grid.

columns = 70; (*column numbers*)
rows = 20; (*row numbers*)
j0 = 1; (*first column*)
period = 8;(*period*)
strip = 3; (*strip width*)

Solution with ArrayPlot:

Manipulate[
fStrips = Function[{i, j}, If[Floor[Mod[((j - j0) + period), period], strip] == strip, 
1(*Even numbers*), 0(*Odd numbers*)]];
arrStrips = Array[fStrips, {rows, columns}];
ArrayPlot[arrStrips, ColorRules -> {1 -> Blue, 0 -> Green}, Mesh -> True,   MeshStyle -> Black, ImageSize -> 700], {j0, 1, 10, 
1}, {strip, 1, 6, 1}, {period, 3, 20, 1}]

Solutionwith Graphics:

Manipulate[
colorfn[i_, j_] := If[Floor[Mod[((i - j0) + period), period], strip] == strip, Blue, Green];
Graphics[{EdgeForm[Black], 
Table[{colorfn[i, j], Rectangle[{1.05*i, 1.05*j}]}, {i, 1, columns,
  1}, {j, 1, rows, 1}]}, AspectRatio -> rows/columns, 
ImageSize -> 700], {j0, 1, 10, 1}, {strip, 1, 6, 1}, {period, 3, 20,1}]

enter image description here

Solution with MatrixPlot:

Manipulate[
matrixPlot[xs_] := MatrixPlot[xs, ColorRules -> {0 -> Blue, 1 -> Green, 2 -> Green}, Mesh -> All, AspectRatio -> rows/columns];
matrixPlot@
Array[If[Floor[Mod[(((#2 - j0) - j0) + period), period], strip] == 
  strip, 0, 1] &, {rows, columns}], {j0, 1, 10, 1}, {strip, 1, 6, 1}, {period, 3, 20, 1}]

enter image description here

Solution with Grid:

tableSize = 30;
j0 = 1; (*first column*)
period = 5;(*period*)
strip = 3; (*strip width: used via lstStrip[1], lstStrip[2], and lstStrip[3]*)

lst = Table["", {i, 1, tableSize}, {j, 1, tableSize}];
lst0 = Flatten[Table[{{{1, tableSize}, {i, i}} -> Green}, {i, 1, tableSize, 1}], 1];
lstStrip[veticalLine_] := Flatten[Table[{{{1, tableSize}, {i, i}} -> Blue}, {i, -j0 + veticalLine, tableSize, period}], 1];

lstFinal = Join[{None, 
None}, {Join[lst0, lstStrip[1], lstStrip[2], lstStrip[3]]}];
Grid[lst, Dividers -> Directive[White, AbsoluteThickness[0.3]], Background -> lstFinal, ItemSize -> {2, 2}]

enter image description here

Thanks!!!

$\endgroup$

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.