Here is my solution made with LuaLaTeX and TikZ without any white filling and using some inverse clipping so any background color will be shown thorugh the holes (see second picture):


\documentclass[a4paper]{article}
\usepackage{luacode}
\usepackage{tikz}
\usetikzlibrary{calc}
% inverse clipping from: http://tex.stackexchange.com/a/59168/8844
\tikzset{
invclip/.style={clip,%
insert path={{[reset cm] %
(-16383.99999pt,-16383.99999pt) rectangle (16383.99999pt,16383.99999pt)%
}}
}
}
\begin{luacode*}
function draw_figure()
tex.sprint([[\begin{tikzpicture}]])
tex.sprint([[\begin{scope}[rotate=11.25] ]])
tex.sprint([[\draw (2.25cm, 0.25cm) rectangle (4.75cm, -0.25cm)]])
tex.sprint([[(2.75cm, 0) circle [radius=0.15cm] ]])
tex.sprint([[(3.25cm, 0) circle [radius=0.15cm] ]])
tex.sprint([[(3.75cm, 0) circle [radius=0.15cm] ]])
tex.sprint([[(4.25cm, 0) circle [radius=0.15cm];]])
tex.sprint([[\end{scope}]])
-- inverse clipping from: http://tex.stackexchange.com/a/59168/8844
tex.sprint([[\begin{pgfinterruptboundingbox}]])
tex.sprint([[\path[invclip, rotate=11.25] (2.25cm, 0.25cm) rectangle (4.75cm, -0.25cm)]])
tex.sprint([[(2.75cm, 0) circle [radius=0.15cm] ]])
tex.sprint([[(3.25cm, 0) circle [radius=0.15cm] ]])
tex.sprint([[(3.75cm, 0) circle [radius=0.15cm] ]])
tex.sprint([[(4.25cm, 0) circle [radius=0.15cm];]])
tex.sprint([[\end{pgfinterruptboundingbox}]])
for radius = 2.5, 4.5, 0.5 do
tex.sprint([[\draw (0,0) circle [radius=]])
tex.sprint(radius)
tex.sprint([[cm];]])
end
for angle = 0, 359, 22.5 do
tex.sprint([[\draw[rotate=]])
tex.sprint(angle)
tex.sprint([[] (2.5cm, 0) -- (4.5cm, 0);]])
end
fillmatrix = {{0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0},
{1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1},
{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1},
{0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0}}
cols = #fillmatrix[1]
rows = #fillmatrix
offset = 2.5
for i = 1, rows do
angle = 0
for j = 1, cols do
if fillmatrix[i][j] == 1 then
tex.sprint([[\fill ($(0, 0) + (]])
tex.sprint(angle)
tex.sprint([[:]])
tex.sprint(offset)
tex.sprint([[cm)$) arc (]])
tex.sprint(angle)
tex.sprint([[:]])
tex.sprint(22.5 + angle)
tex.sprint([[:]])
tex.sprint(offset)
tex.sprint([[cm) -- ($(0, 0) + (]])
tex.sprint(22.5 + angle)
tex.sprint([[:]])
tex.sprint(offset + 0.5)
tex.sprint([[cm)$) arc (]])
tex.sprint(22.5 + angle)
tex.sprint([[:]])
tex.sprint(angle)
tex.sprint([[:]])
tex.sprint(offset + 0.5)
tex.sprint([[cm) -- cycle;]])
end
angle = angle + 22.5
end
offset = offset + 0.5
end
-- naive filling solution:
-- for angle = 0, 359, 90 do
-- tex.sprint([[\fill[rotate=]])
-- tex.sprint(angle)
-- tex.sprint([[] ($(0, 0) + (22.5:2.5cm)$) arc (22.5:67.5:2.5cm) -- ($(0, 0) + (67.5:3.0cm)$) arc (67.5:22.5:3.0cm) -- cycle;]])
-- end
-- for angle = 0, 359, 180 do
-- tex.sprint([[\fill[rotate=]])
-- tex.sprint(angle)
-- tex.sprint([[] ($(0, 0) + (135:3.0cm)$) arc (135:225:3.0cm) -- ($(0, 0) + (225:3.5cm)$) arc (225:135:3.5cm) -- cycle;]])
-- end
-- tex.sprint([[\fill ($(0, 0) + (180:3.5cm)$) arc (180:360:3.5cm) -- ($(0, 0) + (360:4.0cm)$) arc (360:180:4.0cm) -- cycle;]])
-- tex.sprint([[\fill ($(0, 0) + (90:4.0cm)$) arc (90:270:4.0cm) -- ($(0, 0) + (270:4.5cm)$) arc (270:90:4.5cm) -- cycle;]])
tex.sprint([[\end{tikzpicture}]])
end
\end{luacode*}
\begin{document}
\luadirect{draw_figure()}
\end{document}
I've made this into a parametrized function where you can set the values of the chart's inner radius, outer radius (measured in centimeters), and set the position of the ruler. The following code has some examples included, however I show some of them here also.
\documentclass[a4paper]{article}
\usepackage{luacode}
\usepackage{tikz}
\usetikzlibrary{calc}
% inverse clipping from: http://tex.stackexchange.com/a/59168/8844
\tikzset{
invclip/.style={clip,%
insert path={{[reset cm] %
(-16383.99999pt,-16383.99999pt) rectangle (16383.99999pt,16383.99999pt)%
}}
}
}
\begin{luacode*}
function draw_chart(fillmatrix, inner_radius, outer_radius, ruler_step)
cols = #fillmatrix[1]
rows = #fillmatrix
angle_offset = 360 / cols
radius_offset = (outer_radius - inner_radius) / rows
tex.sprint([[\begin{tikzpicture}]])
if ruler_step >= 1 and ruler_step <= cols then
tex.sprint([[\begin{scope}[rotate=]])
tex.sprint(angle_offset * ruler_step - angle_offset / 2)
tex.sprint([[] ]])
tex.sprint([[\draw (]])
tex.sprint(inner_radius - radius_offset * 0.5)
tex.sprint([[cm, ]])
tex.sprint(radius_offset * 0.5)
tex.sprint([[cm) rectangle (]])
tex.sprint(outer_radius + radius_offset * 0.5)
tex.sprint([[cm, ]])
tex.sprint(radius_offset * -0.5)
tex.sprint([[cm)]])
for i = inner_radius, (outer_radius - radius_offset), radius_offset do
tex.sprint([[(]])
tex.sprint(i + radius_offset * 0.5)
tex.sprint([[cm, 0) circle [radius=]])
tex.sprint(radius_offset * 0.5 * 0.6)
tex.sprint([[cm] ]])
end
tex.sprint([[;]])
tex.sprint([[\end{scope}]])
-- inverse clipping from: http://tex.stackexchange.com/a/59168/8844
tex.sprint([[\begin{pgfinterruptboundingbox}]])
tex.sprint([[\path[invclip, rotate=]])
tex.sprint(angle_offset * ruler_step - angle_offset / 2)
tex.sprint([[] (]])
tex.sprint(inner_radius - radius_offset * 0.5)
tex.sprint([[cm, ]])
tex.sprint(radius_offset * 0.5)
tex.sprint([[cm) rectangle (]])
tex.sprint(outer_radius + radius_offset * 0.5)
tex.sprint([[cm, ]])
tex.sprint(radius_offset * -0.5)
tex.sprint([[cm)]])
for i = inner_radius, (outer_radius - radius_offset), radius_offset do
tex.sprint([[(]])
tex.sprint(i + radius_offset * 0.5)
tex.sprint([[cm, 0) circle [radius=]])
tex.sprint(radius_offset * 0.5 * 0.6)
tex.sprint([[cm] ]])
end
tex.sprint([[;]])
tex.sprint([[\end{pgfinterruptboundingbox}]])
end
for radius = inner_radius, outer_radius, radius_offset do
tex.sprint([[\draw (0,0) circle [radius=]])
tex.sprint(radius)
tex.sprint([[cm];]])
end
for angle = 0, 359, angle_offset do
tex.sprint([[\draw[rotate=]])
tex.sprint(angle)
tex.sprint([[] (]])
tex.sprint(inner_radius)
tex.sprint([[cm, 0) -- (]])
tex.sprint(outer_radius)
tex.sprint([[cm, 0);]])
end
radius = inner_radius
for i = 1, rows do
angle = 0
for j = 1, cols do
if fillmatrix[i][j] == 1 then
tex.sprint([[\fill ($(0, 0) + (]])
tex.sprint(angle)
tex.sprint([[:]])
tex.sprint(radius)
tex.sprint([[cm)$) arc (]])
tex.sprint(angle)
tex.sprint([[:]])
tex.sprint(angle + angle_offset)
tex.sprint([[:]])
tex.sprint(radius)
tex.sprint([[cm) -- ($(0, 0) + (]])
tex.sprint(angle + angle_offset)
tex.sprint([[:]])
tex.sprint(radius + radius_offset)
tex.sprint([[cm)$) arc (]])
tex.sprint(angle + angle_offset)
tex.sprint([[:]])
tex.sprint(angle)
tex.sprint([[:]])
tex.sprint(radius + radius_offset)
tex.sprint([[cm) -- cycle;]])
end
angle = angle + angle_offset
end
radius = radius + radius_offset
end
tex.sprint([[\end{tikzpicture}]])
end
\end{luacode*}
\begin{document}
\setlength{\parindent}{0pt}
With this code you can set the inner and outer radius of the chart, and also set the position of the ruler.
inner radius = 2.5cm\\
outer radius = 4.5cm\\
ruler position = 1
\luadirect{
fillmatrix = {{0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0},
{1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1},
{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1},
{0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0}}
draw_chart(fillmatrix, 2.5, 4.5, 1)
}
inner radius = 1cm\\
outer radius = 3cm\\
ruler position = 10
\luadirect{draw_chart(fillmatrix, 1, 3, 10)}
You can disable the ruler, by setting its position to zero.
inner radius = 0cm\\
outer radius = 2cm\\
ruler position = 0
\luadirect{
fillmatrix = {{0, 0, 0, 0, 1, 1, 1, 1},
{0, 0, 1, 1, 0, 0, 1, 1},
{0, 1, 0, 1, 0, 1, 0, 1}}
draw_chart(fillmatrix, 0, 2, 0)
}
You can also use this chart to visualize binary numbers. The third 3 bit binary number (binary 010 = octal 2 = decimal 2 = hexadecimal 2):
\luadirect{draw_chart(fillmatrix, 1, 2, 3)}
The sixteenth 4 bit binary number (binary 1111 = octal 17 = decimal 15 = hexadecimal F):
\luadirect{
fillmatrix = {{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1},
{0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1},
{0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1},
{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}}
draw_chart(fillmatrix, 2, 3, 16)
}
The sixth 5 bit binary number (00101):
\luadirect{
fillmatrix = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1},
{0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1},
{0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1},
{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}}
draw_chart(fillmatrix, 3, 6, 6)
}
\end{document}

left
- inner radius = 1cm, outer radius = 3cm, ruler position= 10
right
- inner radius = 2.5cm, outer radius = 4.5cm, ruler position = 1
You can also use this chart to visualize binary numbers.

left:
- the third 3 bit binary number (binary 010 = octal 2 = decimal 2 = hexadecimal 2)
- inner radius = 1cm, outer radius = 2cm, ruler position = 3
right:
- the sixteenth 4 bit binary number (binary 1111 = octal 17 = decimal 15 =
hexadecimal F)
- inner radius = 2cm, outer radius = 3cm , ruler position = 16