Drawing a really large binary matrix as colored grid
This is MWE
using Asymptote
:
The sample 30x500 file was generated with
//
// "gendata.asy" :
//
int m=30, n=500;
file fout=output("binmatrix.txt");
srand(1717177);
string s;
for(int i=0;i<m;++i){
s="";
for(int j=0;j<n;++j){
s+=string(round(unitrand()));
}
write(fout,s+'\n');
}
flush(fout);
close(fout);
And the Asymptote
code for the image is
//
// "m1.asy" :
//
settings.tex="pdflatex";
file fin=input("binmatrix.txt");
string[] s=fin;
int m=s.length, n=length(s[1]);
real h=1cm;
real w=h/m*n;
size(w,h);
import graph;
import palette;
real[][] v=new real[n][m];
for(int i=0; i < m; ++i){
for(int j=0; j < n; ++j){
v[j][i]=(real)substr(s[i],j,1);
}
}
pen[] Palette=new pen[]{deepblue,orange};
bounds range=image(v,(0,0),(n,m),Palette);
You can also combine bits into colors, for example, like this:
settings.tex="pdflatex";
file fin=input("binmatrix.txt");
string[] s=fin;
int m=s.length, n=length(s[1]);
real h=1cm;
real w=h/m*n/3;
size(w,h);
import graph;
import palette;
pen[][] v=new pen[(int)(n/3)][m];
for(int i=0; i < m; ++i){
for(int j=0; j < (int)(n/3); ++j){
v[j][i]=rgb((real)substr(s[i],3*j,1),(real)substr(s[i],3*j+1,1),(real)substr(s[i],3*j+2,1));;
}
}
image(v,(0,0),(n/3,m));
If you want efficiency, primitive is generally better. Note, the Op for this question specified tikz in the solution.
\documentclass{standalone}
\usepackage{xcolor}
\newlength{\cellwidth}
\newlength{\cellheight}
\let\END=\eof
\newcommand{\colormatrix}[1]% #1 = binary matrix
{\parbox{\CMcolumns\cellwidth}{%
\baselineskip=\cellheight
\lineskip=0pt
\def\one{1}%
\def\zero{0}%
\bgroup
\countdef\col=1
\col=0
\CMParse#1\END
\egroup
}}
\def\CMParse#1{\ifx#1\END\else
\if#1\one\relax{\color{\onecolor}\rule{\cellwidth}{\cellheight}}\fi
\if#1\zero\relax{\color{\zerocolor}\rule{\cellwidth}{\cellheight}}\fi
\advance\col by 1
\ifnum\col<\CMcolumns\relax\else
\hfil
\col=0
\fi
\expandafter\CMParse\fi}% expand \fi first
\newcommand{\setcolormatrix}[6]% #1=width, #2=height, #3=number columns, #4=number rows, #5=one color, #6=zero color
{\global\cellwidth=\dimexpr #1/#3\relax
\global\cellheight=\dimexpr #2/#4\relax
\global\def\CMcolumns{#3}%
\global\def\onecolor{#5}%
\global\def\zerocolor{#6}%
}
\begin{document}
\setcolormatrix{1in}{1in}{11}{7}{blue}{yellow}%
\colormatrix{%
10110101010
10010101010
01010111010
11110010100
01100011001
11101010111
10101010111}
\end{document}
The file image.tex
(created by the editor) consists of
10110101010
10010101010
01010111010
11110010100
01100011001
11101010111
10101010111
and the updated solution is given by
\documentclass{standalone}
\usepackage{xcolor}
\newlength{\cellwidth}
\newlength{\cellheight}
\newread\imagefile
\let\END=\eof
\newcommand{\colormatrix}[1]% #1 = filename
{\parbox{\CMcolumns\cellwidth}{%
\baselineskip=\cellheight
\lineskip=0pt
\def\one{1}%
\def\zero{0}%
\def\empty{\par}%
\openin\imagefile=#1
\loop\ifeof\imagefile\else
\read\imagefile to \buffer%
\ifx\buffer\empty\relax\else
\expandafter\CMParse\buffer\END
\hfil
\fi
\repeat
\closein\imagefile
}}
\long\def\CMParse#1{\ifx#1\END\else
\if#1\one\relax{\color{\onecolor}\rule{\cellwidth}{\cellheight}}\fi
\if#1\zero\relax{\color{\zerocolor}\rule{\cellwidth}{\cellheight}}\fi
\expandafter\CMParse\fi}% expand \fi first
\newcommand{\setcolormatrix}[6]% #1=width, #2=height, #3=number columns, #4=number rows, #5=one color, #6=zero color
{\global\cellwidth=\dimexpr #1/#3\relax
\global\cellheight=\dimexpr #2/#4\relax
\global\def\CMcolumns{#3}%
\global\def\onecolor{#5}%
\global\def\zerocolor{#6}%
}
\begin{document}
\setcolormatrix{1in}{1in}{11}{7}{blue}{yellow}%
\colormatrix{image}
\end{document}