Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Let matrix styles for specific column overwrite styles for even/odd column #867

Closed
septatrix opened this issue May 28, 2020 · 36 comments
Closed

Comments

@septatrix
Copy link

Currently the order in which column/row styles are applied seems to be the following:

  1. general cell
  2. individual column
  3. odd/even column
  4. individual row
  5. odd/even row
  6. row-column combo (specific cell)

I find this to be rather counterintuitive as I expect styles for a specific single column to overwrite styles for e.g. a general odd column. Instead I would like to propose changing the order to:

  1. general cell
  2. odd/even column
  3. odd/even row
  4. individual column
  5. individual row
  6. row-column combo (specific cell)

There are ways to achieve the wanted styles without this change but they require dwelling into the source code and using some more advanced commands. TeX.SE link of this exact problem: https://tex.stackexchange.com/questions/546396/tikz-matrix-overwrite-every-column-row-style-for-specific-column-row

@hmenke
Copy link
Member

hmenke commented May 28, 2020

Sorry, rejected. Changing the order will silently break existing pictures. You'll have to live with the current situation.

@septatrix
Copy link
Author

I know this is a breaking change but couldn't this be enabled through a boolean option to the matrix or implemented in a future breaking version?

@hmenke
Copy link
Member

hmenke commented May 28, 2020

There will be no future breaking version. I have implemented a mechanism to configure the order of these styles, but I will not change the default. It looks pretty sketchy and definitely does not help with the cargo-cultyness of LaTeX, but I couldn't come up with a better configurable way for this.

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{matrix}

\begin{document}
\begin{tikzpicture}
\matrix [
  matrix of nodes,
  matrix/inner style order={
      every cell,
      even odd column,
      even odd row,
      column,
      row,
      cell
  },
  row sep=-\pgflinewidth,
  column sep=-\pgflinewidth,
  nodes={draw, anchor=center, minimum size=.75cm},
  every odd row/.style={nodes={fill=yellow!10}},
  column 6/.style={column sep=5pt},
  column 7/.style={nodes={fill=green!10, font=\bfseries}},
  row 5/.style={row sep=5pt},
  row 6/.style={nodes={fill=green!10, font=\bfseries}}
] {
  1 & 1 & 1 & 0 & 1 & 0 & 0 \\
  0 & 0 & 1 & 0 & 1 & 1 & 1 \\
  0 & 1 & 0 & 1 & 1 & 0 & 1 \\
  0 & 1 & 1 & 0 & 0 & 0 & 0 \\
  1 & 0 & 1 & 1 & 0 & 1 & 0 \\
  0 & 1 & 0 & 0 & 1 & 0 & \\
};
\end{tikzpicture}
\end{document}

@septatrix
Copy link
Author

Okay thank you very much. This honestly seems like a great solution. Personally I wouldn't mind a breaking version but I can see why you choose to go this route.

hmenke added a commit to hmenke/pgf that referenced this issue May 28, 2020
@hmenke
Copy link
Member

hmenke commented May 28, 2020

I've changed it a little bit so that you don't have to fully qualify the default styles. You can also install your own (which you then do have to fully quality).

\tikzset{
  my style/.code={%
    \ifnum\pgfmatrixcurrentcolumn=2
        \tikzset{font=\itshape}%
    \fi
  },
  matrix/inner style order={
      every cell,
      even odd column,
      even odd row,
      column,
      row,
      cell,
      /tikz/my style
  }
}

@hmenke
Copy link
Member

hmenke commented May 28, 2020

Would you consider this as fixed, even though I rejected your original request to change the default order?

@septatrix
Copy link
Author

Yes I consider this as fixed. You may go ahead and close this

@hmenke hmenke closed this as completed May 28, 2020
@hmenke hmenke added this to the 3.1.6 milestone May 28, 2020
@Mo-Gul
Copy link
Contributor

Mo-Gul commented May 29, 2020

Awesome. Thank you for that.

But I agree with septatrix, that it would be even better to make this proposal the new default. I would consider the current default being a bug (and/or bad design decision). One could add a "Note" to the manual that this was changed in v3.x and also state the old order, so it would be quite easy to restore the old behavior if someone really relied on that "bug".

If you still decide to stick to the current implementation I'll suggest to add a new label v4. If in the future there should be a new major version, than one should implement the suggested new order as default. With this label the stuff can easily be found then. (We have something similar in the PGFPlotsToDo list.)

Two more notes to your additions:

  • Could you add a note to the manual that if one misses to add an item to the matrix/inner style order, e.g. row, then all of these styles will be ignored (and maybe add an example).
  • The given example of /tikz/my style is trivial and could be achieved also with column 2/.style. It would be better to add an example that can't be achieved with the default styles, e.g. "color columns 1 and 2, then not 3 and 4, then color 5 and 6 again, then not 7 and 8 (again) ..." (sorry that I cannot currently state it in a better way.)

@hmenke
Copy link
Member

hmenke commented May 29, 2020

Sorry, no way I'm breaking old documents. I'm trying to only break with default behaviour where it was previously an error, but that is not the case here.

@septatrix
Copy link
Author

I agree that changing the default behaviour can't be classified as a bug fix and therefore shall not be done in a minor release. Instead I very much like the addition of an extra option which furthermore also allows one to let column styles overwrite row styles etc. However I would also like to support @Mo-Gul's suggestion that should there be a new major version changing the default order is something you may reconsider. I have yet to find a matrix drawing which would get broken by this change as the majority either does not need per column styles or uses the workaround to achieve the order I propose at that is what most people expect/want.

Sadly however TeX does not allow package selection using semver though maybe an option similar to compat=3.0 like pgfplots uses may be a good addition for 4.0 as I could really see strict backwards compatibility even acros major version to become a burden in the future (also 2.0 and 3.0 had minor backwards incompatible changes...)

@hmenke
Copy link
Member

hmenke commented May 29, 2020

I am definitely not going to maintain a compatibility layer for PGF. That is way too much work. Also, unless Till returns, there will be no further major version of PGF. The current status is maintenance, not development.

And furthermore I absolutely do not care whether your documents work fine with a breaking change, because after all I am not maintaining PGF specifically for you.

@Mo-Gul
Copy link
Contributor

Mo-Gul commented May 29, 2020

@septatrix, you wrote

Instead I very much like the addition of an extra option which furthermore also allows one to let column styles overwrite row styles etc

I am not sure if I have understood that right. But with the new implementation you can overwrite row styles by column styles with (e.g.)

matrix/inner style order={
    every cell,
    even odd row,
    even odd column,
    row,
    column,
    this cell,
},

@septatrix
Copy link
Author

Yes I know. That is why I like this option :D

@Mo-Gul
Copy link
Contributor

Mo-Gul commented May 29, 2020

@hmenke , I thought that will not change your mind, and that is totally fine. I also agree that a compatibility layer for PGF would be (let's call it positive) "challenging". But maybe you could consider my suggestions for the manual.

So the only point left is the label for v4. One never knows what future brings. Not that far in the past I guess not many people were thinking any more that PGF will improve that much in the near future. But then you came around the corner and did all the great stuff !! So I'll try to be optimistic for the future as well and I guess the label will not hurt anybody. So I'll add it in a second ...

@Mo-Gul Mo-Gul added the v4 label May 29, 2020
@hmenke hmenke modified the milestones: 3.1.6, 4.0.0 May 29, 2020
@hmenke
Copy link
Member

hmenke commented May 29, 2020

GitHub has Milestones for this kind of stuff. I've opened a new, generic issue for that because this one is already closed.

@hmenke hmenke removed the v4 label May 29, 2020
@ghost
Copy link

ghost commented May 29, 2020

@Mo-Gul All these things can be trivially achieved already. You only need to add something along the lines of the first part of https://tex.stackexchange.com/a/546401/194703. It is way more powerful than the reordering of a handful of styles IHMO. If anything I'd add a key similarly to visualization depends on from pgfplots which allows the user some directive that depends on the column and row in such a way that this will not be perceived as a "hack". To this end it would be great if one could add a pgf function based on the LaTeX2e macro \in@ which expands the lists and allows the user to add options like ifthenelse(member(\pgfmatrixcurrentrow,{1,2,7}),....

@ilayn
Copy link
Member

ilayn commented May 29, 2020

There is some logic to this actually. Suppose you want to generate tables via tikz matrices (as an example I wrote this some years ago https://tex.stackexchange.com/a/67736). To be able to override the striping pattern as the whole column the default order makes quite some sense (i'm doing some nested styles but nevermind that. Those were the crazy times). Otherwise you have to walk through every stripe to override the settings. Thus this actually takes us out of the latex table hell as you can perform fine surgery per column. Especially if you need funky styles per column. But I understand that this makes simple stripe override not-extremely-simple.

Also notice that these are not content styles but cell styles. You can always override individual cells and much easily by appending to execute at begin/end cell styles. As a last resort, the individual node styles are convenient way-outs. Hence I don't think it is unintuitive but probably not suited to your use case.

@ilayn
Copy link
Member

ilayn commented May 29, 2020

I haven't been TikZing for years now but for your particular example I'd go about it as the following for minimal low levelness and maximum lazyness.

\documentclass[tikz]{standalone}
\usetikzlibrary{matrix}
\tikzset{
  foreach col/.append style={
    column #1/.style={every odd row/.style={nodes={fill=yellow!10}}}
  }
}
\begin{document}
\begin{tikzpicture}
\matrix [
  matrix of nodes,
  row sep=-\pgflinewidth,
  column sep=-\pgflinewidth,
  nodes={draw, anchor=center, minimum size=.75cm},
  foreach col/.list={1,2,3,4,5,6},
  column 6/.append style={column sep=5pt},
  column 7/.style={nodes={fill=green!10, font=\bfseries}},
  row 5/.style={row sep=5pt},
  row 6/.style={nodes={fill=green!10, font=\bfseries}}
] {
  1 & 1 & 1 & 0 & 1 & 0 & 0 \\
  0 & 0 & 1 & 0 & 1 & 1 & 1 \\
  0 & 1 & 0 & 1 & 1 & 0 & 1 \\
  0 & 1 & 1 & 0 & 0 & 0 & 0 \\
  1 & 0 & 1 & 1 & 0 & 1 & 0 \\
  0 & 1 & 0 & 0 & 1 & 0 & \\
};
\end{tikzpicture}
\end{document}

image

@Mo-Gul
Copy link
Contributor

Mo-Gul commented May 30, 2020

@tallmarmot, "trivial" is very "subjective" I would say. What might be trivial to you can be impossible to come up with for me (as a lot of your TeX.SX answers are for me). And of there might be people who are even (way) below my level. So my point only is that it could be confusing to find examples in the manual which might offer new possibilities but could be done with the shown keys.

Then I would expect a note that this is an alternative. And if it is not, I (personally) would see an example that shows me something new. Feel free to choose an example yourself and a way of showing this new feature. I would do it myself, but unfortunately currently my level is too low for that.

Now coming back to your "wish". Also there I don't understand everything because it is above my level. But at least it sounds like a new feature. If I am right, then you should/could open a new issue for that.

@Mo-Gul
Copy link
Contributor

Mo-Gul commented May 30, 2020

@ilayn, here I am not sure if this was for me or in general. But if you (still) have your TeX.SX account I suggest that you post your answer above there too.

@ilayn
Copy link
Member

ilayn commented May 30, 2020

Ah sorry if it wasn't clear. I just wanted to emphasize how these keys can be viewed as "column-first" principle and how other keys can be subsumed into column specifications. Then why the defaults are the way they are becomes clearer (I hope since I'm putting words into Till's mouth). The example is to demonstrate that you don't need to modify any low-level code or defaults. If I was starting from scratch I would have drawn the separated column/row separate anyways.

I guess I could have just said "don't build broken-up tables with TikZ matrices but use actual tables with tikzmark etc. embellishments"

@ghost
Copy link

ghost commented May 30, 2020

@Mo-Gul These TeX.SX and, IMHO even more https://topanswers.xyz/tex, which does not have all the flaws of TeX.SX, can be viewed as example data-bases. There are examples at various levels. All I can say is that (a) I can see how the pgfmanual is confusing when it comes to matrices, and (b) I do not understand how an \ifnum\pgfmatrixcurrentcolumn=... is more complicated than offering the users a reordering of styles of low customizability. IMHO the more structured approach is the main difference between TikZ/pgfplots and PSTricks, say, where you can achieve something only if someone else had anticipated this very situation and written a macro for that.

@Mo-Gul
Copy link
Contributor

Mo-Gul commented Jun 1, 2020

Here a suggestion for a better example, for the documentation

\documentclass[border=5pt]{standalone}
\usepackage{tikz}
    \usetikzlibrary{matrix}
\begin{document}
\begin{tikzpicture}[
    my block by block style/.code={%
        \pgfmathparse{isodd(int((\pgfmatrixcurrentcolumn+1)/2))}
%        \pgfmathparse{isodd(int((\pgfmatrixcurrentcolumn-1+#1)/#1))}
        \ifnum\pgfmathresult=1
            \tikzset{nodes={fill=yellow!10}}%
        \fi
    },
    matrix/inner style order={
        every cell,
        even odd column,
        even odd row,
        column,
        row,
        this cell,
        /tikz/my block by block style,
%        /tikz/my block by block style=3,
    },
]
    \matrix [
        matrix of nodes,
        row sep=-\pgflinewidth,
        column sep=-\pgflinewidth,
        nodes={draw, anchor=center, minimum size=.75cm},
    ] {
        1 & 1 & 1 & 0 & 1 & 0 & 0 & 1 & 1 & 0 & 1 & 0 & 0 \\
        0 & 0 & 1 & 0 & 1 & 1 & 1 & 0 & 1 & 0 & 1 & 1 & 1 \\
    };
\end{tikzpicture}
\end{document}

resulting in

image showing the result of above code

Of course even better would be a more generic solution as the commented parts of the code (instead of the lines above the commented ones). But unfortunately I couldn't make it work. Anybody an idea?

If there are no dissenting votes I would otherwise exchange the code tomorrow morning in the manual.

@hmenke
Copy link
Member

hmenke commented Jun 1, 2020

The matrix/inner style order is nothing magic. It is just a comma-separated list that is processed like this

\pgfutil@for\pgf@temp:=\tikz@common@matrix@code@styleorder\do{%
\expandafter\def\expandafter\pgf@temp\expandafter{\romannumeral-`0\expandafter\pgfutil@trimspaces\expandafter{\pgf@temp}}%
\pgfutil@ifempty\pgf@temp{}{\expandafter\tikzset\expandafter{matrix/inner style/.cd,\pgf@temp/.try}}%
}%

so anything fancy inside will not work. As I said before (and as I have documented) you have to perform any style definition outside of this list.

Moreover, I am aware that the example in the manual can be achieved easily with the existing styles, but that is not the point. I wanted to show how to use the new feature without adding too much unnecessary complexity.

@hmenke
Copy link
Member

hmenke commented Jun 1, 2020

The construct

matrix/inner style order={
    ...
    /tikz/my block by block style=3,
},

should work with hmenke@5c96618. I also used the opportunity to rename this cell to just cell.

@ilayn
Copy link
Member

ilayn commented Jun 1, 2020

I have no dog in this race, hence please ignore it at will but I don't see how default order is causing problems. In fact I would recklessly claim that any problem that can be solved with this new addition was already possible with the old behavior

Here is @Mo-Gul 's example + some other rule with zero modifications to the machinery:

\documentclass[tikz]{standalone}
\usetikzlibrary{matrix}
\begin{document}
\tikzset{
  every column/.style={every odd column/.append style={#1},
                       every even column/.append style={#1}},
  mo-guls rule/.code={%
        \pgfmathparse{isodd(int((\pgfmatrixcurrentcolumn-1+#1)/#1))}%
        \ifnum\pgfmathresult=1\tikzset{nodes={fill=yellow!10}}\fi%
    },
  another rule/.code={\pgfmathparse{int(Mod(\pgfmatrixcurrentcolumn, 4))}%
    \ifnum\pgfmathresult=0\tikzset{nodes={fill=red!10}}\fi}
}

\begin{tikzpicture}[]
    \matrix [
        matrix of nodes,
        row sep=-\pgflinewidth,
        column sep=-\pgflinewidth,
        nodes={draw, anchor=center, minimum size=.75cm},
        every column={mo-guls rule=3,another rule}
    ] {
        1 & 1 & 1 & 0 & 1 & 0 & 0 & 1 & 1 & 0 & 1 & 0 & 0 \\
        0 & 0 & 1 & 0 & 1 & 1 & 1 & 0 & 1 & 0 & 1 & 1 & 1 \\
    };
\end{tikzpicture}
\end{document}

I would argue that the documentation should mention that these keys can be used inside each other as I showed in my previous example. Hence the order is not really an issue.

This also gives another design issue from Till that I really appreciate. The absence of every row or every column style. If you spend 5 seconds over it, it becomes obvious; if you are setting something for every row/column that means it is valid for the whole matrix. So we could just skip all this and write directly to the nodes without this rows/column business.

Hence my bold claim.

@hmenke
Copy link
Member

hmenke commented Jun 1, 2020

@ilayn You are very right with your assertion. In principle all these styles are not needed and not even the every column style that you define is needed. You can achieve the same with just every cell/.style={mo-guls rule=3, another rule}.

Nevertheless, for most users it is much more natural to think in terms of even and odd column or rows and they are generally not comfortable writing complicated TeX conditionals. This little convenience of the abstraction is the only reason that these styles exist.

@Mo-Gul
Copy link
Contributor

Mo-Gul commented Jun 1, 2020

@hmenke, @ilayn that is great news. From that -- I think -- we can agree that the "problem" is, that there isn't any such example in the manual. And maybe that is the point why beginners (like me) can't come up with such solutions. Maybe a small section should be added, e.g. as section 20.3.4, should be added to the manual with the above examples and your explanations, i.e. almost none of the commands of the previous section are needed. Then I think way more people will have a chance to come up with good solutions themselves for their problems.

@ilayn, would you be so kind to do so? I'll be very happy to prove-read it. And if I understand it, then hopefully a lot of others will as well ;) That would really be awesome.

@hmenke
Copy link
Member

hmenke commented Jun 1, 2020

@Mo-Gul Ha! If anything the problem is that nobody reads the manual.

@ghost
Copy link

ghost commented Jun 1, 2020

@hmenke While it is true that users are almost perfect at ignoring the manual, certain techniques have more impact when they are documented there. That is, if someone writes an answer on one of these sites that works, users are less inclined that this is "the way this should be done" than if this is also written in the manual. So I agree with @Mo-Gul that one should at least make an effort.

@ilayn
Copy link
Member

ilayn commented Jun 4, 2020

PR submitted. All feedback is appreciated.

@ghost
Copy link

ghost commented Jun 4, 2020

@ilayn (Nice to meet you here;-). I have a comment, if you don't mind. The example is great, but I feel that by far the biggest issue is that the pgfmanual discusses matrices in two separate sections, namely in 20 Matrices and Alignment and in 60 Matrix Library, where, as far as I can see, in section 60 section 20 does not even get mentioned. I actually do not even see a point in having section 60 separately since the matrix library gets loaded in the earlier examples, too. It could just become a subsection of 20. Then I would also add examples using the counts \pgfmatrixcurrentrow and \pgfmatrixcurrentcolumn. Then I'd add the documentation of the keys execute at begin matrix and execute at end matrix to the manual, and an example using those.

@ilayn
Copy link
Member

ilayn commented Jun 4, 2020

Yes @tallmarmot I agree but I guess it comes from the tikz/pgf layer distinction. 60 is more at the pgf layer manipulations and 20 is for tikz based straightforward key/value stuff. Years of usage proved that it is often required to mix them but I guess that's more of a lack of documentation issue. Section 20 can mention section 60 more maybe. Or include more examples. Or these counters can be converted into usable keys like every nth row, every nth column like pgfplotstable does so people don't need to bother writing pgf code. Because as far as I can see that covers most of the pgf usage cases by doing modular indexing. Speaking of which I might do that 😁

@ghost
Copy link

ghost commented Jun 5, 2020

@ilayn Naively I'd say the opposite. Section 20 deals also with examples that do not require the TikZ library matrix, but only the pgf module. Maybe for most users it is obvious, but one does not need the matrix library to make use of the matrix. I also have no strong opinion, personally I am more and more getting used to the mode "ignore the manual and read the library". 😉

@ilayn
Copy link
Member

ilayn commented Jun 6, 2020

Ah OK my bad by 60 I am apparently meaning 108. Then yes they can be combined but the 20-like sections were kind of introductory tutorials and the 60-like library sections were kind of a reference. So I guess there is not enough meat in 20 and can be populated. But I don't have a good solution.

@Mo-Gul
Copy link
Contributor

Mo-Gul commented Jun 12, 2020

@tallmarmot are willing to make a proposal for a better documentation of the matrix command/library that than can be discussed/reviewed by us? If your answer is yes, I suggest to file a new issue for that referencing this issue. Because this is really another topic than this issue and also would (still) be open instead of closed like this issue ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

4 participants