没有中间文件的gnuplot?

问题描述 投票:1回答:2

我得到的python代码看起来像这样

import subprocess

outdata = """0 45
1 35
2 45
3 35
4 45
5 35
6 45
7 35
8 45""" # etc... one for every minute of a day
f = open("data.txt", 'w')
f.write(outdata)
f.close()

filename = "graph"
title    = "today"
plottext = """
set terminal svg size 2560,1440 enhanced font 'Arial,40'
set output '""" + filename + """.svg'
set title '""" + title + """'
set xrange [0:1440]
set yrange [0:]
set xtics ("00" 0, "01" 60, "02" 120, "03" 180, "04" 240, "05" 300, "06" 360, "07" 420, "08" 480, "09" 540, "10" 600, "11" 660, "12" 720, "13" 780, "14" 840, "15" 900, "16" 960, "17" 1020, "18" 1080, "19" 1140, "20" 1200, "21" 1260, "22" 1320, "23" 1380, "24" 1440 )
plot 'data.txt' using 1:2 with lines notitle
"""
f = open("plotfile.plt", 'w')
f.write(plottext)
f.close()

p = subprocess.call(["gnuplot", "plotfile.plt"])

这就像一个魅力。但是如何在不使用临时文件'data.txt'和'plotfile.plt'的情况下使用Python(或语言)中的gnuplot创建图形?

每分钟,每小时,每年每分钟执行30次以上,因此跳过临时文件可以节省磁盘时间,因为它不是正在处理的少量数据。

后续问题,有可能跳过out文件并在变量中捕获svg文件的xml?这将在cgi-bin中进行,所以我希望能够像这样调用它:

<img src="http://www.example.com/cgi-bin/plot.py?table=table1&date=2016-12-07">

编辑:gnuplot的Python模块不适用于我。

Edit2:PHP中的另一个例子,几乎可以满足我的需求

$outdata="0 33
1 44
2 55
3 44
4 33
5 44
 6 55";

$plottext = "set terminal svg size 2560,1440 enhanced font 'Arial,40'
set term svg size 2560,1440 enhanced font 'Arial,40'
set title ''
set xrange [0:1440]
set yrange [0:]
set xtics ('00' 0, '01' 60, '02' 120, '03' 180, '04' 240, '05' 300, '06' 360, '07' 420, '08' 480, '09' 540, '10' 600, '11' 660, '12' 720, '13' 780, '14' 840, '15' 900, '16' 960, '17' 1020, '18' 1080, '19' 1140, '20' 1200, '21' 1260, '22' 1320, '23' 1380, '24' 1440)
plot '-' using 1:2 with lines notitle\n". $outdata;

file_put_contents("plotfile.plt", $plottext);

exec("gnuplot plotfile.plt", $out);

foreach($out as $line)
{
    print $line."\n";
}

我想用exec(“gnuplot $ plottext”,$ out)之类的东西来称呼它;所以我可以跳过文件plotfile.plt,因为如果两个人同时尝试访问绘制的图形,这个设置可能搞砸了,因为每个人都使用了plotfile.plt这不是最好的解决方案。我们可以为每个http请求使用一个长的随机名称,但跟踪那么多临时文件并删除它们并不优雅。

php python svg gnuplot cgi-bin
2个回答
0
投票

用gnuplot用Python绘制文件并不是最好的解决方案。使用pyplot要好得多。这样你就可以在python代码中输入数据并将svg保存在字符串中。

import matplotlib.pyplot
import io

plotfile = io.StringIO()
matplotlib.pyplot.plot([1,2,3,4], [1,2,1,4])
matplotlib.pyplot.ylabel('Y-axis')
matplotlib.pyplot.xlabel('X-axis')
matplotlib.pyplot.savefig(plotfile, format="svg", dpi = 100)
plotfile.seek(0)
svgstring = plotfile.read()
print(svgstring)

这正是我在我的问题中所希望的。在灌封中没有文件I / O,我将图形保存在python代码中,因此它可以用于Web应用程序中的动态图像。


0
投票

......这是品味问题......

正如@Christoph所写,你也可以使用gnuplot在Python中创建你的情节。将数据放入数据块并将其与设置和绘图命令一起传递给gnuplot。不需要中间文件。像这样的东西(用Python3.6测试)(Python专业人员可能希望改进它......)

from subprocess import Popen, PIPE, STDOUT

settings = '''
reset session
set term svg
'''

# create some data and put it into datablock $Data
data_lines = ['$Data <<EOD']
for i in range(-10,11):
    data_lines.append(str(i) + '\t' + str(i*i))
data_lines.append('EOD\n')
data_str = '\n'.join(data_lines) + '\n'

plot_cmd ='''
plot $Data u 1:2 w lp pt 7
'''

gnuplot_str = settings + data_str + plot_cmd

gnuplot_path = r'C:\Programs\gnuplot\bin\gnuplot.exe'
# plot = Popen([gnuplot_path,'-p'],stdin=PIPE,stdout=PIPE,stderr=PIPE)
plot = Popen([gnuplot_path],stdin=PIPE,stdout=PIPE,stderr=PIPE)
output, error = plot.communicate(gnuplot_str.encode())

print(gnuplot_str)
print(output) # or use it elsewhere

#...

gnuplot代码:

reset session
set term svg

$Data <<EOD
-10 100
-9  81
-8  64
-7  49
-6  36
-5  25
-4  16
-3  9
-2  4
-1  1
0   0
1   1
2   4
3   9
4   16
5   25
6   36
7   49
8   64
9   81
10  100
EOD

plot $Data u 1:2 w lp pt 7

输出SVG:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.