UPDATE
Here is one way to do it. The steps are laid out in my original answer below. Not claiming this is the best way, one could optimise the steps certainly, but it works for this particular matrix.
Seeing as you need to draw coloured boxes around certain subsets of this matrix anyway, you can use the fit
library for that and subsequently use those coordinates to help guide where your braces go.
\documentclass[margin=0.5cm]{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix,decorations.pathreplacing,calc,fit}
\pgfkeys{tikz/mymatrixenv/.style={decoration=brace,every left delimiter/.style={xshift=4.7pt},every right delimiter/.style={xshift=-4.7pt}}}
\pgfkeys{tikz/mymatrix/.style={matrix of math nodes, nodes in empty cells, left delimiter=[,right delimiter={]},inner sep=2pt,column sep=1em,row sep=0.5em,nodes={inner sep=0pt}}}
\pgfkeys{tikz/mymatrixbrace/.style={decorate,thick}}
% The hack required for foreach loops in fit. Code from https://tex.stackexchange.com/questions/4751/fitting-a-list-of-points-with-tikz-and-its-foreach?noredirect=1&lq=1
\makeatletter
\def\tikz@lib@fit@scan{%
\pgfutil@ifnextchar\pgf@stop{\pgfutil@gobble}{%
\pgfutil@ifnextchar\foreach{\tikz@lib@fit@scan@handle@foreach}{%
\tikz@scan@one@point\tikz@lib@fit@scan@handle}}}
\def\tikz@lib@fit@scan@handle@foreach\foreach#1in#2#3{%
\foreach #1 in {#2}
{\tikz@scan@one@point\tikz@lib@fit@scan@handle@foreach@#3}
\tikz@lib@fit@scan}
\def\tikz@lib@fit@scan@handle@foreach@#1{%
\iftikz@shapeborder
\tikz@lib@fit@adjust{%
\pgfpointanchor{\tikz@shapeborder@name}{west}}%
\tikz@lib@fit@adjust{%
\pgfpointanchor{\tikz@shapeborder@name}{east}}%
\tikz@lib@fit@adjust{%
\pgfpointanchor{\tikz@shapeborder@name}{north}}%
\tikz@lib@fit@adjust{%
\pgfpointanchor{\tikz@shapeborder@name}{south}}%
\else
\tikz@lib@fit@adjust{#1}%
\fi
\global\pgf@xa=\pgf@xa
\global\pgf@ya=\pgf@ya
\global\pgf@xb=\pgf@xb
\global\pgf@yb=\pgf@yb}
\makeatletter
\begin{document}
\begin{tikzpicture}[baseline=0cm,mymatrixenv]
\matrix [mymatrix,outer ysep=0.7pt,inner sep=4pt,row sep=1em] (m)
{
v_{1,1} & v_{1,2} & v_{1,3} & & & \\
v_{2,1} & v_{2,2} & v_{2,3} & & & \\
v_{3,1} & v_{3,2} & v_{3,3} & v_{3,4} & & \\
& & v_{4,3} & v_{4,4} & v_{4,5} & v_{4,6} \\
& & & v_{5,4} & v_{5,5} & v_{5,6} \\
& & & v_{6,4} & v_{6,5} & v_{6,6} \\
};
% Colours
\definecolor{brightpurple}{HTML}{C151EF}
% Fitting - note to get a \foreach loop in these fits requires the hack from https://tex.stackexchange.com/questions/4751/fitting-a-list-of-points-with-tikz-and-its-foreach
\node [fit= \foreach \X in {1,...,3}{(m-\X-1)}
\foreach \X in {1,...,3}{(m-\X-2)}
\foreach \X in {1,...,3}{(m-\X-3)}]
[draw=green, thick,inner sep=2.6pt] (fit-a) {};
\node [fit= \foreach \X in {4,...,6}{(m-\X-4)}
\foreach \X in {4,...,6}{(m-\X-5)}
\foreach \X in {4,...,6}{(m-\X-6)}]
[draw=cyan, thick,inner sep=2.6pt] (fit-b) {};
\node [fit= \foreach \X in {1,...,4}{(m-\X-3)}] [draw=brightpurple,fill=brightpurple,fill opacity=0.1, thick,inner sep=1.8pt] (fit-purple-a) {};
\node [fit= \foreach \X in {3,...,6}{(m-\X-4)}] [draw=brightpurple,fill=brightpurple,fill opacity=0.1, thick,inner sep=1.8pt] (fit-purple-b) {};
\node [fit= \foreach \X in {1,...,4}{(m-3-\X)}] [draw=brown,fill=brown,fill opacity=0.1, thick,inner sep=1pt] (fit-brown-a) {}; \node [fit= \foreach \X in {3,...,6}{(m-4-\X)}] [draw=brown,fill=brown,fill opacity=0.1, thick,inner sep=1pt] (fit-brown-b) {};
\node [fit = (m-3-3) (m-3-4) (m-4-3) (m-4-4)] [draw=orange,fill=orange,fill opacity=0.1, thick,inner sep=2.6pt] {};
% FINDING VERTICAL MIDPOINT
\node [fit= \foreach \X in {1,...,3}{
(m-\X-1)}] (fit-one) {};
\node [fit= \foreach \X in {4,...,6}{
(m-\X-6)}] (fit-two) {};
\path (fit-one.south) -- (fit-two.north) coordinate[midway] (X);
% FINDING HORIZONTAL MIDPOINT
\node [fit= \foreach \X in {1,...,3}{
(m-1-\X)}] (fit-one) {};
\node [fit= \foreach \X in {4,...,6}{
(m-6-\X)}] (fit-two) {};
\path (fit-one.east) -- (fit-two.west) coordinate[midway] (Y);
\newcommand\mymatrixbraceoffseth{0.3em}
\newcommand\mymatrixbraceoffsetv{0.3em}
% LHS BRACES
\draw [mymatrixbrace] ($(m.north west)!(fit-a.south)!(m.south west)-(\mymatrixbraceoffseth,0)$) -- node[left=2pt] {$B'$} ($(m.north west)!(fit-a.north)!(m.south west)-(\mymatrixbraceoffseth,0)$);
\draw [mymatrixbrace] ($(m.north west)!(fit-b.south)!(m.south west)-(\mymatrixbraceoffseth,0)$) -- node[left=2pt] {$B''$} ($(m.north west)!(fit-b.north)!(m.south west)-(\mymatrixbraceoffseth,0)$);
% RHS BRACES
\draw [mymatrixbrace] ($(m.north east)!([yshift=-0.02cm]X)!(m.south east)+(\mymatrixbraceoffseth,0)$) -- node[right=2pt] {$E''$} ($(m.north east)!(fit-brown-b.south)!(m.south east)+(\mymatrixbraceoffseth,0)$);
\draw [mymatrixbrace] ($(m.north east)!(fit-brown-a.north)!(m.south east)+(\mymatrixbraceoffseth,0)$) --node[right=2pt] {$E'$} ($(m.north east)! ([yshift=+0.02cm]X)!(m.south east)+(\mymatrixbraceoffseth,0)$);
% TOP BRACES
\draw[mymatrixbrace] ($(m.north west)!([xshift=0.05cm]Y)!(m.north east)+(0,\mymatrixbraceoffsetv)$) -- node[above=2pt] {$C''$} ($(m.north west)!(fit-b.east)!(m.north east)+(0,\mymatrixbraceoffsetv)$);
\draw[mymatrixbrace] ($(m.north west)!(fit-a.west)!(m.north east)+(0,\mymatrixbraceoffsetv)$)-- node[above=2pt] {$C'$} ($(m.north west)!([xshift=-0.05cm]Y)!(m.north east)+(0,\mymatrixbraceoffsetv)$);
% BOTTOM BRACES
\draw[mymatrixbrace] ($(m.south west)!([xshift=-0.05cm]Y)!(m.south east)-(0,\mymatrixbraceoffsetv)$)-- node[below=2pt] {$F'$} ($(m.south west)!(fit-purple-a.west)!(m.south east)-(0,\mymatrixbraceoffsetv)$);
\draw[mymatrixbrace] ($(m.south west)!(fit-purple-b.east)!(m.south east)-(0,\mymatrixbraceoffsetv)$) -- node[below=2pt] {$F''$} ($(m.south west)!([xshift=0.05cm]Y)!(m.south east)-(0,\mymatrixbraceoffsetv)$);
\end{tikzpicture}
\end{document}
ORIGINAL ANSWER
Here is a proof of concept to show how you can remove the gap between the two braces. I've drawn boxes around all the nodes to illustrate where the boundaries lie. The reason why in your example above the lower bracket B''
was shorter than the upper bracket B'
was because it was only measuring the coordinates from cells in the first column. (It's just a limitation of the custom command \mymatrixbraceright
as its been defined in your MWE). But see how in the first column cell (6,1) has a smaller bounding box than say cell (6,6)?
The method I've used here is to perform a fit around cells (1,1), (2,1) and (3,1) and perform a fit around cells (4,6), (5,6) and (6,6). Using these two fits I can find the midway point between them. This takes inspiration from Automatically find which nodes are closest, to aid drawing lines within a TikZ matrix.
Using this midpoint I can then manually draw the braces starting from the top of (1,1) to (X). And from (X) to the bottom of (6,6).
\documentclass[margin=0.5cm]{standalone}
\usepackage{mathtools}
\usepackage{tikz}
\usetikzlibrary{matrix,decorations.pathreplacing,calc,fit}
\pgfkeys{tikz/mymatrixenv/.style={decoration=brace,every left delimiter/.style={xshift=3pt},every right delimiter/.style={xshift=-3pt}}}
\pgfkeys{tikz/mymatrix/.style={matrix of math nodes, nodes in empty cells, left delimiter=[,right delimiter={]},inner sep=2pt,column sep=1em,row sep=0.5em,nodes={inner sep=0pt}}}
\pgfkeys{tikz/mymatrixbrace/.style={decorate,thick}}
\newcommand\mymatrixbraceoffseth{0.5em}
\newcommand\mymatrixbraceoffsetv{0em}
% CODE from https://tex.stackexchange.com/questions/4751/fitting-a-list-of-points-with-tikz-and-its-foreach?noredirect=1&lq=1
\makeatletter
\def\tikz@lib@fit@scan{%
\pgfutil@ifnextchar\pgf@stop{\pgfutil@gobble}{%
\pgfutil@ifnextchar\foreach{\tikz@lib@fit@scan@handle@foreach}{%
\tikz@scan@one@point\tikz@lib@fit@scan@handle}}}
\def\tikz@lib@fit@scan@handle@foreach\foreach#1in#2#3{%
\foreach #1 in {#2}
{\tikz@scan@one@point\tikz@lib@fit@scan@handle@foreach@#3}
\tikz@lib@fit@scan}
\def\tikz@lib@fit@scan@handle@foreach@#1{%
\iftikz@shapeborder
\tikz@lib@fit@adjust{%
\pgfpointanchor{\tikz@shapeborder@name}{west}}%
\tikz@lib@fit@adjust{%
\pgfpointanchor{\tikz@shapeborder@name}{east}}%
\tikz@lib@fit@adjust{%
\pgfpointanchor{\tikz@shapeborder@name}{north}}%
\tikz@lib@fit@adjust{%
\pgfpointanchor{\tikz@shapeborder@name}{south}}%
\else
\tikz@lib@fit@adjust{#1}%
\fi
\global\pgf@xa=\pgf@xa
\global\pgf@ya=\pgf@ya
\global\pgf@xb=\pgf@xb
\global\pgf@yb=\pgf@yb}
\makeatletter
\begin{document}
\begin{tikzpicture}[baseline=0cm,mymatrixenv]
\matrix [mymatrix,inner sep=4pt,row sep=1em,draw,nodes={draw}] (m)
{
v_{1,1} & v_{1,2} & v_{1,3} & & & \\
v_{2,1} & v_{2,2} & v_{2,3} & & & \\
v_{3,1} & v_{3,2} & v_{3,3} & v_{3,4} & & \\
& & v_{4,3} & v_{4,4} & v_{4,5} & v_{4,6} \\
& & & v_{5,4} & v_{5,5} & v_{5,6} \\
& & & v_{6,4} & v_{6,5} & v_{6,6} \\
};
\node [fit= \foreach \X in {1,...,3}{
(m-\X-1)}] (fit-a) [draw] {};
\node [fit= \foreach \X in {4,...,6}{
(m-\X-6)}] (fit-b) [draw] {};
\path (fit-a.south) -- (fit-b.north) coordinate[midway] (X);
\draw [mymatrixbrace] ($(m.north west)!(X)!(m.south west)-(\mymatrixbraceoffseth,0)$)
-- node[left=2pt] {$B'$}
($(m.north west)!(m-1-1.north west)!(m.south west)-(\mymatrixbraceoffseth,0)$);
\draw [mymatrixbrace] ($(m.north west)!(m-6-6.south)!(m.south west)-(\mymatrixbraceoffseth,0)$)
-- node[left=2pt] {$B'$}
($(m.north west)!(X)!(m.south west)-(\mymatrixbraceoffseth,0)$);
\end{tikzpicture}
\end{document}
To get something closer to the image you posted. I suggest adding shifting the y coordinate of (X)
slightly. Here I've used yshift=0.05cm
on the upper brace and yshift=-0.05cm
on the lower brace. Also, to make the braces reach the extremities of the matrix bracket, instead of drawing them from the north boundary of (1,1) and the south boundary of (6,6), I've changed it so they are drawn from m.north
and from m.south
. I've also added outer ysep=0.5pt
to increase the length of the square brackets slightly. These numbers can be played with as you see fit.
\documentclass[margin=0.5cm]{standalone}
\usepackage{mathtools}
\usepackage{tikz}
\usetikzlibrary{matrix,decorations.pathreplacing,calc,fit}
\pgfkeys{tikz/mymatrixenv/.style={decoration=brace,every left delimiter/.style={xshift=3pt},every right delimiter/.style={xshift=-3pt}}}
\pgfkeys{tikz/mymatrix/.style={matrix of math nodes, nodes in empty cells, left delimiter=[,right delimiter={]},inner sep=2pt,column sep=1em,row sep=0.5em,nodes={inner sep=0pt}}}
\pgfkeys{tikz/mymatrixbrace/.style={decorate,thick}}
\newcommand\mymatrixbraceoffseth{0.5em}
\newcommand\mymatrixbraceoffsetv{0em}
% CODE from https://tex.stackexchange.com/questions/4751/fitting-a-list-of-points-with-tikz-and-its-foreach?noredirect=1&lq=1
\makeatletter
\def\tikz@lib@fit@scan{%
\pgfutil@ifnextchar\pgf@stop{\pgfutil@gobble}{%
\pgfutil@ifnextchar\foreach{\tikz@lib@fit@scan@handle@foreach}{%
\tikz@scan@one@point\tikz@lib@fit@scan@handle}}}
\def\tikz@lib@fit@scan@handle@foreach\foreach#1in#2#3{%
\foreach #1 in {#2}
{\tikz@scan@one@point\tikz@lib@fit@scan@handle@foreach@#3}
\tikz@lib@fit@scan}
\def\tikz@lib@fit@scan@handle@foreach@#1{%
\iftikz@shapeborder
\tikz@lib@fit@adjust{%
\pgfpointanchor{\tikz@shapeborder@name}{west}}%
\tikz@lib@fit@adjust{%
\pgfpointanchor{\tikz@shapeborder@name}{east}}%
\tikz@lib@fit@adjust{%
\pgfpointanchor{\tikz@shapeborder@name}{north}}%
\tikz@lib@fit@adjust{%
\pgfpointanchor{\tikz@shapeborder@name}{south}}%
\else
\tikz@lib@fit@adjust{#1}%
\fi
\global\pgf@xa=\pgf@xa
\global\pgf@ya=\pgf@ya
\global\pgf@xb=\pgf@xb
\global\pgf@yb=\pgf@yb}
\makeatletter
\begin{document}
\begin{tikzpicture}[baseline=0cm,mymatrixenv]
\matrix [mymatrix,outer ysep=0.5pt,inner sep=4pt,row sep=1em] (m)
{
v_{1,1} & v_{1,2} & v_{1,3} & & & \\
v_{2,1} & v_{2,2} & v_{2,3} & & & \\
v_{3,1} & v_{3,2} & v_{3,3} & v_{3,4} & & \\
& & v_{4,3} & v_{4,4} & v_{4,5} & v_{4,6} \\
& & & v_{5,4} & v_{5,5} & v_{5,6} \\
& & & v_{6,4} & v_{6,5} & v_{6,6} \\
};
\node [fit= \foreach \X in {1,...,3}{
(m-\X-1)}] (fit-a) {};
\node [fit= \foreach \X in {4,...,6}{
(m-\X-6)}] (fit-b) {};
\path (fit-a.south) -- (fit-b.north) coordinate[midway] (X);
\draw [mymatrixbrace] ($(m.north west)!([yshift=0.05cm]X)!(m.south west)-(\mymatrixbraceoffseth,0)$)
-- node[left=2pt] {$B'$}
($(m.north west)!(m.north west)!(m.south west)-(\mymatrixbraceoffseth,0)$);
\draw [mymatrixbrace] ($(m.north west)!(m.south)!(m.south west)-(\mymatrixbraceoffseth,0)$)
-- node[left=2pt] {$B''$}
($(m.north west)!([yshift=-0.05cm]X)!(m.south west)-(\mymatrixbraceoffseth,0)$);
\end{tikzpicture}
\end{document}
nodes in empty cells
key to your matrix and it should work.