
Я часто создаю графики для своих курсов, и я обнаружил, что я всегда копирую и вставляю код, и я хочу ускорить процесс. Я использую свой собственный .cls
файл для своего кода, так что, может быть, я мог бы сохранить некоторые из этих часто используемых настроек там?
Вот мойтекущийкод для типичного графика:
\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[scale=.9]
\def \xmin {-3}
\def \xmax {3}
\def \ymin {-2}
\def \ymax {3}
\draw[help lines] (\xmin, \ymin) grid (\xmax, \ymax);
\draw [<->] (\xmin-.3,0) -- (\xmax+.3,0);
\draw [<->] (0,\ymin-.3) -- (0,\ymax+.3);
\node at (0,\ymax + .6) {$g(x)$};
\node at (\xmax + .6,0) {$x$};
\node at (-2, 1.5) {$y = g(x)$};
\draw[domain=-1.828:1, blue, very thick, smooth] plot
({\x}, {-0.5*(\x-1)^2 + 2});
\draw[domain=1:2.732, blue, very thick, smooth] plot
({\x}, {-1*(\x-1)^2 + 1});
\draw[very thick, blue, fill] (1,1) circle [radius=.08];
\draw[very thick, blue, fill=white] (1,2) circle [radius = .08];
\foreach \x in {1} \draw (0,\x)node[right]{\x};
\foreach \x in {1} \draw (\x,0)node[below]{\x};
\end{tikzpicture}
\end{document}
Повторяющиеся вещи:
- Стили линий всегда «очень толстые, синие».
- Я всегда рисую вспомогательные линии, указанные выше значениями.
- Круги (закрашенные белым или синим цветом) встречаются часто.
- Последние две команды я использую для добавления меток.
Некоторые вещи плохо масштабируются. Если я установлю масштаб .5, например, стрелки будут выглядеть неправильно, а текст будет перемещаться. Интересно, можно ли изменить положение стрелок и меток на осях в зависимости от коэффициента масштабирования?
Если у вас есть какие-то мысли по этому поводу, я был бы очень признателен. Я думаю, что я запутался и в tikz, и в файлах классов.
решение1
Вы можете использовать \tikzset
и \newcommand
для создания общего кода, который нужно поместить в ваш .cls
файл.
Например, я создал:
- стиль
myblue
, который можно использовать вместо «очень густой, синий» - команда
myhelp
для линий помощи - a
whitepoint
иbluepoint
pic
s для кругов (заполненных белым или синим цветом, вы также можете создать уникальныйpic
с параметром для передачи опции цвета) - команда
mylabels
для добавления меток.
Посмотрите код, чтобы узнать, как их использовать:
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric,shapes.symbols,positioning,decorations.pathmorphing}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% you may put a code like this in your .cls file
\tikzset{%
myblue/.style={blue, very thick},
pics/bluepoint/.style={code={%
\draw[very thick, blue, fill] (0,0) circle [radius=.08];
}},
pics/whitepoint/.style={code={%
\draw[very thick, blue, fill=white] (0,0) circle [radius = .08];
}},
}
\newcommand{\myhelp}{\draw[help lines] (\xmin, \ymin) grid (\xmax, \ymax);}
\newcommand{\mylabels}{%
\foreach \x in {1} \draw (0,\x)node[right]{\x};
\foreach \x in {1} \draw (\x,0)node[below]{\x};}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
\begin{tikzpicture}[scale=.9]
\def \xmin {-3}
\def \xmax {3}
\def \ymin {-2}
\def \ymax {3}
\myhelp
\draw [<->] (\xmin-.3,0) -- (\xmax+.3,0);
\draw [<->] (0,\ymin-.3) -- (0,\ymax+.3);
\node at (0,\ymax + .6) {$g(x)$};
\node at (\xmax + .6,0) {$x$};
\node at (-2, 1.5) {$y = g(x)$};
\draw[domain=-1.828:1, myblue, smooth] plot
({\x}, {-0.5*(\x-1)^2 + 2});
\draw[domain=1:2.732, myblue, smooth] plot
({\x}, {-1*(\x-1)^2 + 1});
\pic at (1,1) {bluepoint};
\pic at (1,2) {whitepoint};
\mylabels
\end{tikzpicture}
\end{document}
Конечно, результат будет точно таким же:
Если это может быть полезно, вот версия с параметрической настройкой цвета кончика стрелки, по blue
умолчанию:
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric,shapes.symbols,positioning,decorations.pathmorphing}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% you may put a code like this in your .cls file
\tikzset{%
myblue/.style={blue, very thick},
pics/mypoint/.style={code={%
\draw[very thick, blue, fill=#1] (0,0) circle [radius=.08];
}},
pics/mypoint/.default=blue
}
\newcommand{\myhelp}{\draw[help lines] (\xmin, \ymin) grid (\xmax, \ymax);}
\newcommand{\mylabels}{%
\foreach \x in {1} \draw (0,\x)node[right]{\x};
\foreach \x in {1} \draw (\x,0)node[below]{\x};}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
\begin{tikzpicture}[scale=.9]
\def \xmin {-3}
\def \xmax {3}
\def \ymin {-2}
\def \ymax {3}
\myhelp
\draw [<->] (\xmin-.3,0) -- (\xmax+.3,0);
\draw [<->] (0,\ymin-.3) -- (0,\ymax+.3);
\node at (0,\ymax + .6) {$g(x)$};
\node at (\xmax + .6,0) {$x$};
\node at (-2, 1.5) {$y = g(x)$};
\draw[domain=-1.828:1, myblue, smooth] plot
({\x}, {-0.5*(\x-1)^2 + 2});
\draw[domain=1:2.732, myblue, smooth] plot
({\x}, {-1*(\x-1)^2 + 1});
\pic at (1,1) {mypoint};
\pic at (1,2) {mypoint=white};
\mylabels
\end{tikzpicture}
\end{document}
решение2
Один из подходов заключается в использовании \pgfkeys
для хранения различных значений по умолчанию для ваших графиков, а затем в обертке всего в пользовательскую среду с новыми настройками, заданными через пары ключ-значение. Например, код
\pgfkeys{/mygraph/.is family, /mygraph,
xmin/.initial = -3, % defaults for xmin, xmax, ymin,ymax
xmax/.initial = 3,
ymin/.initial = -3,
ymax/.initial = 3,
ylabel/.initial = f(x),% default function name
scale/.initial = 0.9, % tikzpicture scale
xtics/.initial = {1}, % list of marked coordinates on x-axis
ytics/.initial = {1}, % list of marked coordinates on y-axis
}
устанавливает начальные (или значения по умолчанию) значения для максимальных и минимальных значений x и y, метку для оси y и масштаб. Затем вы можете определить среду, например, MyGraph
которая принимает необязательный аргумент, который передается в \pgfkeys
via
\pgfkeys{/mygraph, #1}
для изменения этих настроек. Это будет использоваться как
\begin{MyGraph}[ylabel=g(x)]
\draw[domain=-1.828:1, smooth,-{Circle[blue]}] plot ({\x}, {-0.5*(\x-1)^2 + 2});
\draw[domain=1:2.732, smooth, {Circle[open, fill=white]}-] plot ({\x}, {-1*(\x-1)^2 + 1});
\end{MyGraph}
Это рисует график в вопросе! В частности, обратите внимание, что \usetikzlibrary{arrows.meta}
обеспечивает круглые наконечники "стрелок". В общем, "содержимое" среды MyGraph
будет материалом, специфичным для вашего графика.
Среда MyGraph
откроет среду tikzpicture
и нарисует "начальный код". Вот одно из возможных определений:
\newenvironment{Mygraph}[1][]%
{\pgfkeys{/mygraph, #1}% process settings
\begin{tikzpicture}[scale=\Gval{scale},
draw/.append style={very thick, blue}]
\draw[help lines](\Gval{xmin},\Gval{ymin}) grid (\Gval{xmax},\Gval{ymax});
\draw[thin, black] [<->] (\Gval{xmin}-0.3,0) -- (\Gval{xmax}+0.3,0);
\draw[thin, black] [<->] (0,\Gval{ymin}-0.3) -- (0,\Gval{ymax}+0.3);
\node at (0,\Gval{ymax} + .6) {$\Gval{ylabel}$};
\node at (\Gval{xmax} + .6,0) {$x$};
\node at (-2, 1.5) {$y = \Gval{ylabel}$};
}
{\end{tikzpicture}}
( \Gval
Макрос, являющийся сокращением для \pgfkeysvalueof{/mygraph/#1}
, извлекает значение соответствующей клавиши.)
Обратите внимание draw/.append style={very thick, blue}
на начало среды tikzpicture
: это устанавливает толстые синие линии как значения по умолчанию для \draw
команды. Есть небольшой недостаток в таком подходе, так как теперь необходимо писать \draw[black]....
для меток на осях x и y. Другой способ сделать это — использовать
\tikzset
для определения стиля:
\tikzset{% define styles for commonly used elements
myline/.style={very thick, blue}
}
после чего вы будете использовать , \draw[myline]...
когда вам нужны толстые синие линии. Использование \tikzset
более явно, и поэтому, вероятно, лучше, но если вы хотите, чтобы "почти все" ваши команды рисования давали толстые синие линии, это сэкономит вам немного ввода.
Вот полный MWE, использующий MyGraph
среду для построения двух «разных» графиков:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{arrows.meta}
% Using pgfkeys makes it easier to use key-value settings for the graph
\pgfkeys{/mygraph/.is family, /mygraph,
xmin/.initial = -3, % defaults for xmin, xmax, ymin,ymax
xmax/.initial = 3,
ymin/.initial = -3,
ymax/.initial = 3,
ylabel/.initial = f(x),% default function name
scale/.initial = 0.9, % tikzpicture scale
xtics/.initial = {1}, % list of marked coordinates on x-axis
ytics/.initial = {1}, % list of marked coordinates on y-axis
}
% shortcut to access values of /mygraph
\newcommand\Gval[1]{\pgfkeysvalueof{/mygraph/#1}}
% graph environment with optional argument for changing defaults
\newenvironment{Mygraph}[1][]%
{\pgfkeys{/mygraph, #1}% process settings
\begin{tikzpicture}[scale=\Gval{scale},
draw/.append style={very thick, blue}]
\draw[help lines](\Gval{xmin},\Gval{ymin}) grid (\Gval{xmax},\Gval{ymax});
\draw[thin, black] [<->] (\Gval{xmin}-0.3,0) -- (\Gval{xmax}+0.3,0);
\draw[thin, black] [<->] (0,\Gval{ymin}-0.3) -- (0,\Gval{ymax}+0.3);
\node at (0,\Gval{ymax} + .6) {$\Gval{ylabel}$};
\node at (\Gval{xmax} + .6,0) {$x$};
\node at (-2, 1.5) {$y = \Gval{ylabel}$};
\xdef\xtics{\Gval{xtics}}% for reasons unknown can't use this directly
\foreach \x in \xtics { \draw[black](\x,0)node[below]{\small$\x$}; }
\xdef\ytics{\Gval{ytics}}
\foreach \y in \ytics { \draw[black](0,\y)node[left]{\small$\y$}; }
}
{\end{tikzpicture}}
\begin{document}
\begin{Mygraph}
\draw[domain=-1.828:1, smooth,-{Circle[blue]}] plot ({\x}, {-0.5*(\x-1)^2 + 2});
\draw[domain=1:2.732, smooth, -{Circle[open, fill=white]}] plot ({\x}, {-1*(\x-1)^2 + 1});
\end{Mygraph}
\begin{Mygraph}[ylabel=g(x), xmin=-4, xmax=4, scale=0.5, xtics={1,2,3}, ytics={1,3}]
\draw[domain=-1.828:1, smooth,-{Circle[blue]}] plot ({\x}, {-0.5*(\x-1)^2 + 2});
\draw[domain=1:2.732, smooth, {Circle[open,fill=white]}-] plot ({\x}, {-1*(\x-1)^2 + 1});
\end{Mygraph}
\end{document}
Вот что получилось:
Конечно, вы можете добавить больше настроек для \pgfkeys{/mygraph/,...}
дальнейшей настройки ваших графиков. Например, вы, вероятно, захотите сделать это для обозначенных значений x и y на осях и размещения метки y=g(x)
и т. д. Есть также много других вещей, которые вы можете сделать с \pgfkeys
-- см.тикзруководство для получения более подробной информации.
решение3
Ответы выше от @andrew и @CarLaTeX конструктивны и поучительны. Я перенял части обоих их ответов, чтобы придумать следующий код.
В моем классном файле естьдобавленследующее, к уже значительному объему (не связанного) кода. Я не хочу размещать все это здесь, поэтому соответствующие части:
% This is the setup for the wcgraph environment below
\tikzset{%
myblue/.style={blue, very thick},
pics/closed/.style={code={%
\draw[very thick, blue, fill] (0,0) circle [radius=.08];
}},
pics/open/.style={code={%
\draw[very thick, blue, fill=white] (0,0) circle [radius=.08];
}},
pics/mypoint/.default=blue,
draw/.append style={very thick, blue},
>=latex,
>=stealth,
}
% This is the setup for the wcgraph environment below
\pgfkeys{/mygraph/.is family, /mygraph,
xmin/.initial = -3, % defaults for xmin, xmax, ymin,ymax
xmax/.initial = 3,
ymin/.initial = -3,
ymax/.initial = 3,
ylabel/.initial = f(x), % default function name
xlabel/.initial = x, % default independent variable
scale/.initial = 0.9, % tikzpicture scale
xtics/.initial = {1}, % list of marked coordinates on x-axis
ytics/.initial = {1}, % list of marked coordinates on y-axis
xticsloc/.initial = below, % default location for tick labels
yticsloc/.initial = left,
helplines/.initial = draw, % Default to draw the help lines
}
% A new command to grab values from pgfkeys above
\newcommand\getVal[1]{\pgfkeysvalueof{/mygraph/#1}}
% A command to draw helplines. To not draw them, pass the option "hide"
\newcommand{\helplines}[1]{
\ifthenelse{\equal{#1}{draw}}{
\draw[help lines] (\getVal{xmin},\getVal{ymin}) grid (\getVal{xmax},\getVal{ymax});
}{}
}
% The graph environment with optional arguments for changing defaults
\newenvironment{wcgraph}[1][]%
{\pgfkeys{/mygraph, #1}% process settings
\begin{tikzpicture}[scale=\getVal{scale}]
\helplines{\getVal{helplines}}
\draw[thin, black] [->] (\getVal{xmin}-0.3,0) -- (\getVal{xmax}+0.3,0);
\draw[thin, black] [->] (0,\getVal{ymin}-0.3) -- (0,\getVal{ymax}+0.3);
\node at (0,\getVal{ymax} + .6) {$\getVal{ylabel}$};
\node at (\getVal{xmax} + .6,0) {$\getVal{xlabel}$};
\xdef\xtics{\getVal{xtics}} % Can't use this directly for some reason
\foreach \x in \xtics {
\draw[black](\x,0)node[\getVal{xticsloc}]{\small$\x$};
}
\foreach \x in {\getVal{xmin},...,\getVal{xmax}}{
\draw[black, thin, shift={(\x,0)}] (0pt,1pt) -- (0pt,-1pt);
}
\xdef\ytics{\getVal{ytics}}
\foreach \y in \ytics {
\draw[black](0,\y)node[left]{\small$\y$};
}
\foreach \y in {\getVal{ymin},...,\getVal{ymax}}{
\draw[black, thin, shift={(0,\y)}] (1pt,0pt) -- (-1pt,0pt);
}
}
{\end{tikzpicture}}
В моем .tex
файле я использую worksheet.cls
класс, который (как я уже сказал выше) включает в себя много других вещей, чем те, что я разместил прямо над этим. MWE — это:
\documentclass{worksheet}
\begin{document}
\begin{wcgraph}[xmin=-2, ymin=-2]
\draw[domain=-1.828:1, smooth] plot ({\x}, {-0.5*(\x-1)^2 + 2});
\draw[domain=1:2.732, smooth] plot ({\x}, {-1*(\x-1)^2 + 1});
\pic at (1,2) {open};
\pic at (1,1) {closed};
\end{wcgraph}
\begin{wcgraph}[helplines=hide, xmin=-2, ymin=-2, scale=1.8]
\draw[domain=-1.828:1, smooth] plot ({\x}, {-0.5*(\x-1)^2 + 2});
\draw[domain=1:2.732, smooth] plot ({\x}, {-1*(\x-1)^2 + 1});
\pic at (1,2) {open};
\pic at (1,1) {closed};
\end{wcgraph}
\end{document}
что дает следующие графики:
Возможно, это не то место, чтобы задавать дополнительный вопрос (и я с радостью отредактирую это и опубликую другой вопрос, если кто-то предложит это), но я хотел бы немного расширить тему. Я считаю, что это очень важно для исходного вопроса, поэтому и дополнительный. Я хочу добавить команду для рисования всех «открытых» узлов, необходимых для указания координат. У меня возникли проблемы с передачей «списка» координат в новой команде. Я хочу использовать \foreach
on #1
, аргумент моей новой команды. Это не работает так, как я ожидал, и не будет анализироваться как координаты. Я прочитал руководство PGF и множество сообщений на , \foreach
но безуспешно.
Я хотел бы использовать следующий код для графического отображения вышеизложенного:
\begin{wcgraph}[helplines=hide, xmin=-2, ymin=-2, scale=1.8]
\draw[domain=-1.828:1, smooth] plot ({\x}, {-0.5*(\x-1)^2 + 2});
\draw[domain=1:2.732, smooth] plot ({\x}, {-1*(\x-1)^2 + 1});
\openpics{(1,2)};
\closedpics{(1,1)};
\end{wcgraph}
что было бы очень полезно, когда у меня будут более сложные графики.
Мое лучшее предположение относительно этой новой команды (будет добавлено в мой .cls
файл):
% A new command to draw all open pics I need.
\newcommand{\openpics}[1]{
\foreach \coord in {#1}{
\pic at \coord {open};
}
}
И \closedpics
команда будет аналогичной.
решение4
Возможно, вы захотите рассмотреть pgfplots
пакет для своих целей, полный пример ниже.
% arara: pdflatex
\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{every axis/.append style={
axis x line=middle,
axis y line=middle,
axis line style={<->},
xlabel={$x$},
ylabel={$y$},
line width=1pt,},
% line style
gnatplot/.style={color=blue,mark=none},
soldot/.style={color=blue,only marks,mark=*},
holdot/.style={color=blue,fill=white,only marks,mark=*},
}
% arrows
\tikzset{>=stealth}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
xmin=-3,xmax=3,
ymin=-2,ymax=3,
grid=both,
]
\addplot[gnatplot,domain=-1.828:1]{-0.5*(x-1)^2 + 2};
\addplot[gnatplot,domain=1:2.732]{-1*(x-1)^2 + 1};
\addplot[soldot]coordinates{(1,1)};
\addplot[holdot]coordinates{(1,2)};
\end{axis}
\end{tikzpicture}
\end{document}