7

As a teacher, I really appreciate the venndiagram usepackage with its functionality. Is there a way to fill the sets with patterns instead of a solid color (for better printing)? Something along the lines of \begin{venndiagram2sets}[shade={pattern=horizontal lines}], or \begin{venndiagram2sets}[tikzoptions={pattern=horizontal lines}]?

A working example without pattern fills follows. Thanks in advance!

\documentclass{standalone}
\usepackage{tikz}
   \usetikzlibrary{patterns}
\usepackage{venndiagram}
%
\begin{document}
\begin{venndiagram2sets}[shade=orange,tikzoptions={red}]
   \fillA
\end{venndiagram2sets}
\end{document}
Manuel
  • 321
  • 3
    If you look into the documentation of the venndiagram package, you will recognize that the fills are done with a command \path[fill=\@venn@shade] ..., where =\@venn@shade is the color that you specify with shade=... (orange in your example),The IMHO simplest way to do what you want is to copy the venndiagram.sty file to a new file in which you replace all ``\path[fill=@venn@shade] by\path[@venn@shade]and then do\begin{venndiagram2sets}[pattern=north east lines,tikzoptions={red}]` after loading your own package. Or send a request to the package author. –  Aug 21 '18 at 11:16
  • Thanks, really nice idea. I tried it in different variations (also changing the initial definition of \newcommand*{\@venn@shade}{lightgray} to \newcommand*{\@venn@shade}{pattern=north east lines}, however no luck so far. I'll keep trying, because I really like the idea. – Manuel Aug 22 '18 at 06:08
  • This is because now you are effectively saying fill={pattern=north east lines}. The issue is to get rid of the hardcoded fill= and I think LoopSpace made a brilliant suggestion to accomplish that. –  Aug 22 '18 at 10:44

2 Answers2

6

Something like this (it's just a rough proposition):

\documentclass[border=5pt,tikz]{standalone}
   \usetikzlibrary{patterns}
%\usepackage{venndiagram}
%
\begin{document}
%\begin{venndiagram2sets}[shade=orange,tikzoptions={red}]
%   \fillA
%\end{venndiagram2sets}
\begin{tikzpicture}[red,every node/.style={font=\Large}]
    \draw[pattern=north west lines] (0,0) circle(1.5);
    \draw (2,0) circle(1.5);
        \node[fill=white,inner sep=1pt,rounded corners,below=3] at (90:1.5) {$A$};
        \node[xshift=2cm,below=3] at (90:1.5) {$B$};
\end{tikzpicture}
\end{document}

The output:

Screenshot

EDIT: Here is a proposal with horizontal lines (manually pattern drawn – just for fun):

\documentclass[border=5pt,tikz]{standalone}
   \usetikzlibrary{patterns}
%\usepackage{venndiagram}
%
\begin{document}
%\begin{venndiagram2sets}[shade=orange,tikzoptions={red}]
%   \fillA
%\end{venndiagram2sets}
\begin{tikzpicture}[red,every node/.style={font=\Large}]
\begin{scope}
    \clip (0,0) circle(1.5);
    \foreach \x in {-5,-4.95,...,6}
    {
        \draw[black,yshift=\x cm] (-5,\x) -- (5,\x);
    }
\end{scope}
    \draw (2,0) circle(1.5);
    \draw (0,0) circle(1.5);
        \node[fill=white,inner sep=1pt,rounded corners,below=3] at (90:1.5) {$A$};
        \node[xshift=2cm,below=3] at (90:1.5) {$B$};
\end{tikzpicture}
\end{document}

Here is the output:

Screenshot

current_user
  • 5,235
  • 1
    Thanks, I really appreciate your effort (nice Tikz skills!). Im not sure if Im going this route though, since this would imply that I lose most functionality of the venn diagramm package. I'll see... In any case, thanks again. – Manuel Aug 22 '18 at 06:10
5

I agree with marmot's comment that the best option is to make the package more flexible (my suggestion would be to replace fill=\@venn@shade with something like every venn region/.try). In the meantime, here's a fix that uses a scope to add extra options to the path.

\documentclass{article}
%\url{https://tex.stackexchange.com/q/446941/86}
\usepackage{tikz}
   \usetikzlibrary{patterns}
\usepackage{venndiagram}
%
\begin{document}
\begin{venndiagram2sets}[shade={},tikzoptions={red}]
\begin{scope}[every path/.append style={pattern=north east lines}]
\fillA
\end{scope}
\end{venndiagram2sets}

\end{document}

The shade={} is important. It enables filling (since shade=<colour> becomes fill=<colour> in the code) but doesn't specify a colour. The point here is that the every path style is examined first so putting shade=<actual colour> would override the pattern, while shade=none would disable it. Only shade={} enables the pattern without overwriting it.

patterned venn diagram


Update 2018-08-22

Dealing with intersection regions turns out to be a bit tricky due to how clipping works. The following is definitely in the region of a bit of a hack, but it does seem to work. It appends some code to the clip command which removes the options and turns off any other options. I think this deals with everything that can go bad with passing options to a clipping path.

I've also add a helper command that wraps a venn diagram command in a scope so that this technique works.

\documentclass{article}
%\url{https://tex.stackexchange.com/q/446941/86}
\usepackage{tikz}
   \usetikzlibrary{patterns}
\usepackage{venndiagram}
%

\newcommand*\wrapscope[1]{%
  \expandafter\newcommand\csname o#1\endcsname[1][]{%
    \begin{scope}[##1]
    \csname #1\endcsname
    \end{scope}
  }%
}%

\wrapscope{fillA}
\wrapscope{fillACapB}

\makeatletter
\tikzset{
  clip/.append code={%
    \let\tikz@options=\pgfutil@empty
    \tikz@addmode\tikz@mode@fillfalse%
    \tikz@addmode\tikz@mode@drawfalse%
    \tikz@addmode\tikz@mode@doublefalse%
    \tikz@addmode\tikz@mode@boundaryfalse%
    \tikz@addmode\tikz@mode@fade@pathfalse%
    \tikz@addmode\tikz@mode@fade@scopefalse%
  }
}
\makeatother

\begin{document}
\begin{venndiagram2sets}[shade={},tikzoptions={red}]
%\ofillA[every path/.append style={pattern=north east lines}]
\ofillACapB[every path/.append style={pattern=north east lines}]
\end{venndiagram2sets}

\end{document}
Andrew Stacey
  • 153,724
  • 43
  • 389
  • 751
  • Thanks a lot for your input! The fix worked perfectly for me. Do you see any problems to define a new environment including the scope fix? So far this seems to work perfectly for me. – Manuel Aug 22 '18 at 06:13
  • 2
    I would define a new command based on \fillA that included the scope since it should really only apply to that command (I can envision wanting different patterns on different parts of the same diagram). Something like \newcommand*\ofillA[1][]{\scope[#1]\fillA\endscope}. – Andrew Stacey Aug 22 '18 at 07:04
  • That's a really cool solution! –  Aug 22 '18 at 10:13
  • @Loop Space Thanks again, nice solution! Hopefully last question: This works well for many commands, but not so for e.g. \fillACapB. It seems that the clipping is the problem there. Any possible solution to that? – Manuel Aug 22 '18 at 18:25
  • 1
    @Manuel That was tricky! I want to put a disclaimer on this code - I don't know if it will break something else. So use with caution! – Andrew Stacey Aug 22 '18 at 20:26
  • If anyone wants to take on the maintenance of the venndiagram package to extend it, just let me know. Unfortunately I have way too many packages to support to spend much time on it. – Nicola Talbot Aug 22 '18 at 22:15
  • @NicolaTalbot I'm extremely reluctant to take it over (I feel I have just about as many packages as I can cope with at the moment as well), but I'd be happy to contribute to the code. Is it available in a public repository? – Andrew Stacey Aug 23 '18 at 12:42
  • @LoopSpace Not at the moment. It's currently in a local subversion repository, but I can add it to github and make you a contributor. – Nicola Talbot Aug 23 '18 at 14:21
  • @Loop Space I know I already thanked you a few times :) but thanks again. It worked for me and I really do appreciate all the input, help and effort. I certainly could not have come up myself with the solution you gave us! – Manuel Aug 23 '18 at 14:43
  • @NicolaTalbot That would be fine by me. – Andrew Stacey Aug 23 '18 at 15:17
  • @Manuel Happy to help. I do draw the odd venn diagram myself so I'm also helping a future version of myself! – Andrew Stacey Aug 23 '18 at 15:17