Drawing a piano diagram with tikz

If I understand the requirements correctly, the musictex part can be stripped out. To simplify further, the coordinates of the keys can be calculated using a regular double for loop over 5 octaves and 7 pitches. The letters from the pitch array can be printed on the key using the calculated x coordinate, and similar for the black keys with a sharp added to the pitch letter.

What remains is some fiddling with the positioning of the keys and pitch labels. Note that, because a new key in the original code was drawn as a rectangle, the left line of the rectangle would overlap the right line of the previous key. Normally this is not a problem, however when the note name is printed in white on the black key then the next white key would be visible on top of the note name. To counter that the white keys are drawn as three lines, only top, right, and bottom. For the very first key an additional left line is drawn before the loop.

MWE:

\documentclass[border=0.25cm]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}

\begin{tikzpicture}

\coordinate (origin) at (0,0);
\coordinate (stave) at (origin);
% left line of first key
\draw (0.25,-1) -- (0.25,-5);

\newif\ifblacknote
\foreach \octave in {0,...,5}
    \foreach \pitch [count=\p] in {A,...,G}{
        % calculate x position from octave and pitch
        \pgfmathparse{\octave*7+\p+0.25}
        \edef\myx{\pgfmathresult}
        % draw three lines for top, right, bottom of this key
        \draw (\myx,-1) -- (\myx,-5);
        \draw (\myx,-1) -- ($(\myx,-1)+(-1,0)$);
        \draw (\myx,-5) -- ($(\myx,-5)+(-1,0)$);
        % print pitch on line
        \node [anchor=base,xshift=-15] at (\pgfmathresult,-4.5) {\pitch};
        \blacknotefalse
        \ifcase\p
        \or
            \blacknotetrue
        \or
        \or
            \blacknotetrue
        \or
            \blacknotetrue
        \or
        \or
            \blacknotetrue
        \or
            \ifnum\octave<5
                \blacknotetrue
            \fi
        \else
        \fi
        \ifblacknote
            % recalculate x
            \pgfmathparse{\octave*7+\p}
                \fill ([xshift=0.25cm, yshift=-1cm]stave.south -| \pgfmathresult,0) ++(-0.25cm,0) rectangle ++(0.5cm,-2.5cm);
                % print pitch on black key
                \node [anchor=base,xshift=0.25cm,white] at (\pgfmathresult,-2.5) {\textbf{\pitch}${}^\sharp$};
        \fi
    }

\end{tikzpicture}
\end{document}

Result (partial screenshot):

enter image description here

Edit: added flats on the black keys. Code:

% recalculate x
\pgfmathparse{\octave*7+\p}
\edef\myx{\pgfmathresult}
% calculate flats
\pgfmathparse{array({"B","C","D","E","F","G","A"},\p-1)}
\edef\nextnote{\pgfmathresult}
\fill ([xshift=0.25cm, yshift=-1cm]stave.south -| \myx,0) ++(-0.25cm,0) rectangle ++(0.5cm,-2.5cm);
% print pitch on black key
\node [anchor=base,xshift=0.25cm,white] at (\myx,-2.5) {\textbf{\pitch}${}^\sharp$};
\node [anchor=base,xshift=0.25cm,white] at (\myx,-3.0) {\textbf{\nextnote}${}^\flat$};

enter image description here


Edit: one octave, different characters for note names.

\documentclass[border=0.5cm]{standalone}
\usepackage{fontspec}
\setmainfont[Script=Devanagari,Mapping=devanagarinumerals]{Shobhika}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{ulem}
\begin{document}

\begin{tikzpicture}

\coordinate (origin) at (0,0);
\coordinate (stave) at (origin);
% left line of first key
\draw (0.25,-1) -- (0.25,-5);

\newif\ifblacknote
 \foreach \pitch [count=\p] in {सा,रे,ग,म,प,ध,नी}{
     % calculate x position from octave and pitch
     \pgfmathparse{\p+0.25}
     \edef\myx{\pgfmathresult}
     % draw three lines for top, right, bottom of this key
     \draw (\myx,-1) -- (\myx,-5);
     \draw (\myx,-1) -- ($(\myx,-1)+(-1,0)$);
     \draw (\myx,-5) -- ($(\myx,-5)+(-1,0)$);
     % print pitch on line
     \node [anchor=base,xshift=-15] at (\pgfmathresult,-4.5) {\pitch};
     \blacknotefalse
     \ifcase\p
     \or
         \blacknotetrue
     \or
         \blacknotetrue
     \or
     \or
         \blacknotetrue
     \or
         \blacknotetrue
     \or
         \blacknotetrue
     \or
     \else
     \fi
     \ifblacknote
         \fill ([xshift=0.25cm, yshift=-1cm]stave.south -| \p,0) ++(-0.25cm,0) rectangle ++(0.5cm,-2.5cm);
         % print pitch on black key
         \pgfmathparse{array({"\underline{रे}","\underline{ग}",,"मऺ","\underline{ध}","\underline{नी}"},\p-1)}
            \edef\nextnote{\pgfmathresult}
         \node [anchor=base,xshift=0.25cm,white] at (\p,-2.5) {\nextnote};
     \fi
 }

\end{tikzpicture}
\end{document}

3

Tags:

Music

Tikz Pgf