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}
3
  • 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.
    – user121799
    Aug 21, 2018 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, 2018 at 6: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.
    – user121799
    Aug 22, 2018 at 10:44

2 Answers 2

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}
11
  • 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, 2018 at 6: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}. Aug 22, 2018 at 7:04
  • That's a really cool solution!
    – user121799
    Aug 22, 2018 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, 2018 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! Aug 22, 2018 at 20:26
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

1
  • 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, 2018 at 6:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .