修改 x 和 y 范围?

发布于 2024-10-19 04:57:15 字数 413 浏览 2 评论 0原文

以下脚本:

set view map
set dgrid3d 2,2
splot "-" with points title "Data"
0 0 1
0 1 2
1 0 3
1 1 4
e

在图的四个角上绘制四个点。有没有办法扩大范围,使边框和点之间有一个小边距?

我知道这可以使用 xrange 或 yrange 命令来完成。但我更喜欢一种方式来表示最外点和边框之间有 10pt 的空间。

解决方案如下:

  1. 获取当前的 xmin 和 xmax 值
  2. 对返回的值进行一些数学运算,并相应地设置新的 xmin 和 xmax 值。

也会很好。

任何提示、链接和帮助都值得赞赏!

提前感

谢沃尔坦

The following script:

set view map
set dgrid3d 2,2
splot "-" with points title "Data"
0 0 1
0 1 2
1 0 3
1 1 4
e

plots four dots on the four corners of the diagram. Is there a way to extend the range, so that there is a small margin between the border and the dots?

I know that this can be accomplished using the xrange or yrange commands. But I'd rather like a way to say that a 10pt space is between the outer most point and the border.

A solution like:

  1. Get the current xmin and xmax values
  2. Do some math stuff with the returned values and set new xmin and xmax values accordingly.

Would be nice as well.

Any hint, link and help is appreciated!

Thanks in advance

Woltan

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

卷耳 2024-10-26 04:57:15

这取决于你想做什么。

AFAIK(我不是 gnuplot 内部的专家)gnuplot 将大部分绘图的实际制作方式传递到终端。因此 xrange 和 yrange 将能够在两侧为您提供一点额外的空间,但实际上(确切)有多少空间将取决于绘图的大小(因此对于 png 小到 png 大,它会有所不同 - 例如)。

如果您想精确控制大小,那么我认为您需要直接使用特定终端而不是使用 gnuplot。然而,Gnuplot 确实支持多种终端。对于此任务,使用 Metapost 终端 mp 可能是最简单的。
这可以让您准确地改变边框和抽搐的位置。

要使其正常工作,您将需要脚本

set term mp latex
set output "xrange_example.mp"
set view map
set dgrid3d 2,2
splot "-" with points title "Data"
0 0 1
0 1 2
1 0 3
1 1 4
e
set output 
set term pop

和乳胶文档(假设您正在使用它)

\documentclass{scrartcl}

\usepackage{emp,ifpdf}
\ifpdf
 \DeclareGraphicsRule{*}{mps}{*}{}
\fi
\begin{document}

\includegraphics{xrange_example.0}

\end{document} 

,然后使用它生成图像,

> TEX=latex
> gnuplot your_gnuplot.gp
> mpost  xrange_example.mp
> pdflatex xrange.tex

它是 xrange_example。您更改的 mp 文件。如果你打开它,你会发现(大约向下一半)

beginfig(0);
w:=5.000in;h:=3.000in;
a:=w/1200.0;b:=h/720.0;

a和b指定宽度和高度的缩放。
在这些之后添加

numeric x[], y[];
  x[0] = -10pt;
  x[1] =  10pt;
  y[0] = -10pt;
  y[1] =  10pt;

这些介绍您要添加到边界和抽动部分的距离。
抽搐的定义如下

draw (193.0a,591.2b)--(193.0a,569.6b); % On the left
draw (355.8a,165.4b)--(355.8a,187.0b); % on the right
put_text( btex  0.2 etex, 355.8a, 117.8b, 0, 2); % the text

您想要像这样修改它们

draw (193.0a+x[0],591.2b)--(193.0a+x[0],569.6b); % On the left
draw (355.8a+x[1],165.4b)--(355.8a+x[1],187.0b); % on the right
put_text( btex  0.2 etex, 355.8a+x[0], 117.8b, 0, 2); % the text

如您所见,这通过搜索和替换(或在脚本中)很容易做到,因为您只修改数字 193.0a、355.8a。

你需要对 xtics 和边框做同样的事情

draw (192.9a,591.2b)--(192.9a,165.3b)--(1007.0a,165.3b)--(1007.0a,591.2b)--(192.9a,591.2b);

总共我认为你必须改变 8 个数字(很多次 - 非常适合脚本化)。

作为示例,我添加了带有修改边框的 plot sin(x) 的 pdf。边框已修改恰好 10pt。 (您同样可以选择毫米、厘米或英寸等单位)

image

It depends what you want to do.

AFAIK (I'm not an expert on the internals of gnuplot) gnuplot passes much of how the plot is actually be made to the terminal. So xrange and yrange will be able to give you a little bit extra on either side but how much space this actually is (exactly) will depend upon the size of the plot (so it will be different for png small to png large - for example).

If you want to control the size exactly, then then I think you need to work directly with a specific terminal rather than with gnuplot. However, Gnuplot does support a wide range of terminals. For this task it is probably easiest to work with the metapost terminal mp.
This lets you alter the positions of the border and tics exactly

To get this working you will need your script

set term mp latex
set output "xrange_example.mp"
set view map
set dgrid3d 2,2
splot "-" with points title "Data"
0 0 1
0 1 2
1 0 3
1 1 4
e
set output 
set term pop

And your latex document (presuming you are using this)

\documentclass{scrartcl}

\usepackage{emp,ifpdf}
\ifpdf
 \DeclareGraphicsRule{*}{mps}{*}{}
\fi
\begin{document}

\includegraphics{xrange_example.0}

\end{document} 

You then generate your image with

> TEX=latex
> gnuplot your_gnuplot.gp
> mpost  xrange_example.mp
> pdflatex xrange.tex

It is the xrange_example.mp file that you alter. If you open it up you will find (about half way down)

beginfig(0);
w:=5.000in;h:=3.000in;
a:=w/1200.0;b:=h/720.0;

The a and the b specify the scaling to the width and height.
After these add

numeric x[], y[];
  x[0] = -10pt;
  x[1] =  10pt;
  y[0] = -10pt;
  y[1] =  10pt;

These introduce the distances that you are going to add to the border and the tics.
The tics are defined like so

draw (193.0a,591.2b)--(193.0a,569.6b); % On the left
draw (355.8a,165.4b)--(355.8a,187.0b); % on the right
put_text( btex  0.2 etex, 355.8a, 117.8b, 0, 2); % the text

You want to modify these like so

draw (193.0a+x[0],591.2b)--(193.0a+x[0],569.6b); % On the left
draw (355.8a+x[1],165.4b)--(355.8a+x[1],187.0b); % on the right
put_text( btex  0.2 etex, 355.8a+x[0], 117.8b, 0, 2); % the text

As you can see this is easy to do with search and replace (or in a script) because you are only modifying the numbers 193.0a, 355.8a.

You need to do the same for xtics and the border

draw (192.9a,591.2b)--(192.9a,165.3b)--(1007.0a,165.3b)--(1007.0a,591.2b)--(192.9a,591.2b);

In total I think you have to change 8 numbers (lots of times - very scriptable).

As an example, I include the pdf of the plot sin(x) with the modified border. The border has been modified by exactly 10pt. (you could equally choose this in mm or cm or inches etc)

image

三生殊途 2024-10-26 04:57:15

我发现以下可能性可以通过某种因素偏移边框:

set view map
set dgrid3d 2,2
splot "-" with points title "Data"
0 0 1
0 1 2
1 0 3
1 1 4
e
save set "Tmp.txt"
system("python SetRange.py Tmp.txt 1.1")
load "Tmp.txt"
splot "-" with points title "Data"
0 0 1
0 1 2
1 0 3
1 1 4
e

如您所见,gnuplot 的状态保存在文件 Tmp.txt 中。在其他情况下,如果从文件中读取数据,则可以用 replot 替换较低的 splot 命令。

通过系统调用,您可以修改临时文件中的 xrange 和 yrange 条目。我用 python 脚本做到了这一点,因为我不太擅长 awk^^。

import os
import sys

class Range(object):
    def __init__(self, line, factor):
        self.Line = line
        self.Factor = factor
        self.min, self.max = self._GetRange(self.Line)

        self.min_new, self.max_new = self._SetRange(self.min, self.max, self.Factor)

    def Write(self, file):
        Line_new = self.Line[0:self.Line.find("*")]
        Line_new = Line_new + str(self.min_new) + ":" + str(self.max_new)
        Line_new = Line_new + self.Line[self.Line.find("]") : self.Line.find("#")]

        file.write(Line_new + "\n")

    def _GetRange(self, line):
        min, max = (line[line.rfind("[") + 1 : line.rfind("]")]).split(":")
        return (float(min), float(max))

    def _SetRange(self, min, max, factor):
        dist_new = (max - min) * factor
        mean = (max - min) / 2 + min

        min_new = mean - dist_new / 2
        max_new = mean + dist_new / 2
        return (min_new, max_new)


if __name__ == '__main__':
    if not os.path.exists(sys.argv[1]):
        raise Exception("Cannot find file " + sys.argv[1])

    file = open(sys.argv[1])
    fileContents = file.read().split("\n")
    file.close()

    if len(sys.argv) > 2:
        factor = float(sys.argv[2])
    else:
        factor = 1.05

    for line in fileContents:
        if line.find("set xrange") != -1:
            xrange = Range(line, factor)
        elif line.find("set yrange") != -1:
            yrange = Range(line, factor)

    file = open(sys.argv[1], "w")
    xrange.Write(file)
    yrange.Write(file)
    file.close()

如果有一种更短的方法可以用 awk 做到这一点,我会非常高兴知道;)

Cherio Woltan

I found the following possibility to offset the border by some factor:

set view map
set dgrid3d 2,2
splot "-" with points title "Data"
0 0 1
0 1 2
1 0 3
1 1 4
e
save set "Tmp.txt"
system("python SetRange.py Tmp.txt 1.1")
load "Tmp.txt"
splot "-" with points title "Data"
0 0 1
0 1 2
1 0 3
1 1 4
e

As you can see, the state of gnuplot is saved in a file Tmp.txt. In other cases if the data is read from a file, the lower splot command could be replaced with a replot.

With the system call you can modify the entries of the xrange and yrange in the temp file. I did that with a python script, since I am not too good with awk^^.

import os
import sys

class Range(object):
    def __init__(self, line, factor):
        self.Line = line
        self.Factor = factor
        self.min, self.max = self._GetRange(self.Line)

        self.min_new, self.max_new = self._SetRange(self.min, self.max, self.Factor)

    def Write(self, file):
        Line_new = self.Line[0:self.Line.find("*")]
        Line_new = Line_new + str(self.min_new) + ":" + str(self.max_new)
        Line_new = Line_new + self.Line[self.Line.find("]") : self.Line.find("#")]

        file.write(Line_new + "\n")

    def _GetRange(self, line):
        min, max = (line[line.rfind("[") + 1 : line.rfind("]")]).split(":")
        return (float(min), float(max))

    def _SetRange(self, min, max, factor):
        dist_new = (max - min) * factor
        mean = (max - min) / 2 + min

        min_new = mean - dist_new / 2
        max_new = mean + dist_new / 2
        return (min_new, max_new)


if __name__ == '__main__':
    if not os.path.exists(sys.argv[1]):
        raise Exception("Cannot find file " + sys.argv[1])

    file = open(sys.argv[1])
    fileContents = file.read().split("\n")
    file.close()

    if len(sys.argv) > 2:
        factor = float(sys.argv[2])
    else:
        factor = 1.05

    for line in fileContents:
        if line.find("set xrange") != -1:
            xrange = Range(line, factor)
        elif line.find("set yrange") != -1:
            yrange = Range(line, factor)

    file = open(sys.argv[1], "w")
    xrange.Write(file)
    yrange.Write(file)
    file.close()

If there is a shorter way to do that with awk, I'd be more than happy to know ;)

Cherio Woltan

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文