修复图形大小并自动调整 canvas

Fix graph size and automatically adjust canvas

我想为我的论文制作许多不同的图,它们在视觉上应该看起来彼此一致。 IE。我希望每个图的图形大小(可见边框)具有相同的大小。 我的挑战是 (x/x2/y/y2)tics 和标签有时存在,有时不存在。一种相当粗略的方法是使用固定的 canvas 大小和固定的边距,但是如果没有 x 或 x2 抽动和标签,这会在图的上方和下方产生不希望有的大空白 space。

我将使用 cairolatex 终端。是否可以修复图形大小,但允许 canvas 自动缩放?一些伪代码是:

# desired graph size in cm
graph_width = 10
graph_height = 7
# calculate extra space that is needed for tics and labels
extra_space_bottom = 0
if [xtics = on]
 extra_space_bottom = extra_space_bottom + <space for xtics>
if [xlabel = on]
 extra_space_bottom = extra_space_bottom + <space for xlabel>
# ...
# the same for y, x2, y2, title, colorbox etc.
# now the canvas size will be:
set terminal cairolatex size graph_width+extra_space_left+extra_space_right, graph_height+extra_space_bottom+extra_space_top

Maybe this could be a starting point?

这是一个简单的问题,但是,我不确定在 gnuplot 中是否有一种简单的方法可以做到这一点。我以为我之前看到过类似的问题,但我找不到了。 至少,gnuplot 有设置图形纵横比的选项,检查 help size。有了这个图形将具有所需的纵横比,并最终在左侧和右侧或顶部和底部具有额外的宽边距,具体取决于 canvas 纵横比。

此解决方法的想法如下;

  1. 将图表的纵横比设置为所需的比例 GraphSizeFixedY/GraphSizeFixedX
  2. 将 canvas 设置为 GraphSizeFixedXGraphSizeFixedY 大小,绘制图形并记住边距(左、右、下、上)
  3. 将您的 canvas 设置为“反向”纵横比 GraphSizeFixedYGraphSizeFixedX,重新绘制并记住边距
  4. 将 canvas 设置为所需的宽度和高度,并添加记住的相应边距的最小值并重新绘制。

缺点是要画3次。 我为 wxtpdfcairo 终端试过了。我希望它也适用于 pdflatex 终端。 也许有一个我没有想到的更简单的解决方案。

代码:

### fixed graph size and variable canvas size
reset session

myTerminal = 'wxt'
GraphSizeFixedX = 500
GraphSizeFixedY = 350
Unit = ''

# uncomment these lines if you want to use pdfcairo terminal
# myTerminal = 'pdfcairo'
# GraphSizeFixedX = 10
# GraphSizeFixedY = 7
# Unit = 'cm'

FILE = 'tbSizeGraphFixed.pdf'
set output FILE

set size ratio real(GraphSizeFixedY)/GraphSizeFixedX   # real() to avoid integer division

LMargin(n) = GPVAL_TERM_XMIN
RMargin(n) = GPVAL_TERM_XSIZE/GPVAL_TERM_SCALE+1-GPVAL_TERM_XMAX
BMargin(n) = GPVAL_TERM_YMIN
TMargin(n) = GPVAL_TERM_YSIZE/GPVAL_TERM_SCALE+1-GPVAL_TERM_YMAX

# set canvas ratio
set term @myTerminal size GraphSizeFixedX @Unit, GraphSizeFixedY @Unit

# actual plotting command
set xlabel "x-label"
set ylabel "y-label"
# set x2label "x2-label"    # uncomment for comparison
# set y2label "y2-label"    # uncomment for comparison
plot sin(x)

Lmargin1 = LMargin(0)
Rmargin1 = RMargin(0)
Bmargin1 = BMargin(0)
Tmargin1 = TMargin(0)

# set "inverse" canvas ratio
set term @myTerminal size GraphSizeFixedY @Unit, GraphSizeFixedX @Unit
replot
Lmargin2 = LMargin(0)
Rmargin2 = RMargin(0)
Bmargin2 = BMargin(0)
Tmargin2 = TMargin(0)

min(a,b) = a<b ? a : b
Factor = myTerminal eq "wxt" ? 1: GPVAL_TERM_SCALE    # not completely clear why this is needed

TermSizeVarX = GraphSizeFixedX + \
               real(min(Lmargin1,Lmargin2) + min(Rmargin1,Rmargin2)) / Factor
TermSizeVarY = GraphSizeFixedY + \
               real(min(Bmargin1,Bmargin2) + min(Tmargin1,Tmargin2)) / Factor

set term @myTerminal size TermSizeVarX @Unit, TermSizeVarY @Unit
set output FILE
replot

set output
### end of code

结果:wxt 终端,图形大小 500,350 像素,背景颜色仅供说明)

仅限 x 和 y 标签。 Canvas 大小 586 x 418 像素

x、y、x2 和 y2 标签。 Canvas 大小 610 x 434 像素

修改后的答案使用 \input{figure} 而不是生成包含的独立数字

在查看源代码并使用 set term tikz plotsize x,y 之后,我得出的结论是这个选项没有经过深思熟虑,无法轻易修复。然而,有一个不同的 tikz 选项 tightboundingbox 似乎完全符合您的要求,并且不需要修改源代码。

我的建议:

(1) 在 gnuplot 的 set term 命令中定义固定大小的输出,并在其中定义固定的绘图边界,为最 space 消耗的标签留出足够的 space 边距你期望处理。这个修改后的答案需要 tikz 终端,因为我们将使用 tightboundingbox 终端选项

 set term tikz tightboundingbox size 5in, 3in
 set output 'figure_N.tex'
 set lmargin at screen 0.15
 set rmargin at screen 0.85
 set tmargin at screen 0.85
 set bmargin at screen 0.15

(2) 绘制图形并关闭输出 TeX 文件

 set output 'figure_1.tex'
 plot <whatever>
 set output 'figure_2.tex'
 plot <something else>
 unset output

(3) 在您的 TeX 文档中,做 而不是 给它 set term 中指定的原始大小。让它拾取由 tikz/pgf 计算的边界框。例如

\usepackage{gnuplot-lua-tikz}
\usepackage{wrapfig}
\begin{document}

Some text\

\begin{wrapfigure}{r}{}
\input{figure_1}
\end{wrapfigure}

Some more text\

\begin{wrapfigure}{r}{}
\input{figure_2}
\end{wrapfigure}

Yet more text\
\end{document}

基于@theozh 的方法,我找到了一种正确计算 canvas 大小的方法。这个想法是让 gnuplot 自动处理边距,测量它们的大小,将它们添加到总 canvas 大小并重新绘制。幸运的是边距的大小是“恒定的”,即无论 terminal size 有多大,tic 标签和轴标签总是采用相同数量的 space。

  1. cairolatex 绘制所有内容,并对大小进行一些初步猜测
  2. 从内部变量GPVAL_TERM_*读取边距的大小
  3. 将计算出的边距添加到 size 并重新绘图。

如果某些边距由用户设置,同样的过程也适用。

注意:未测试放置在图表外的多列键

### fixed graph size and variable canvas size
reset session

myTerminal = 'cairolatex'
XSize = 10 #cm
YSize = 7 #cm

set term @myTerminal size XSize cm, YSize cm
FILE = 'tbSizeGraphFixed.tex'
set out FILE

# actual plotting command
set xlabel "x-label"
set ylabel "y-label"
plot sin(x)

# cairolatex is calculating the size in bp, convert it to cm.
# _*MIN and _*MAX are the borders of the graph
# _*SIZE is canvas size, scaled by _SCALE
# for whatever reason, _*SIZE is 1bp smaller than the actual canvas, and is scaled by a factor of 20
bp2cm = 0.03528
LSpace = bp2cm * (GPVAL_TERM_XMIN)
RSpace = bp2cm * (GPVAL_TERM_XSIZE/GPVAL_TERM_SCALE -GPVAL_TERM_XMAX +1)
BSpace = bp2cm * (GPVAL_TERM_YMIN)
TSpace = bp2cm * (GPVAL_TERM_YSIZE/GPVAL_TERM_SCALE -GPVAL_TERM_YMAX +1)

unset out
set term myTerminal size (XSize+LSpace+RSpace) cm, (YSize+BSpace+TSpace) cm
set out FILE
replot
unset out