我得到了如下所示的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"])
它的作用就像一个护身符。但是,如何在Python (或一种语言)中使用gnuplot创建图形,而不使用临时文件'data.txt‘和'plotfile.plt’呢?
这是每分钟、每小时、全年每分钟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请求使用一个长的随机名称,但跟踪这么多临时文件并删除它们并不是一件优雅的事情。
发布于 2019-02-25 22:19:10
使用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)
这正是我在问题中所希望的。potting中没有文件I/O,我可以将图形保存在python代码中,这样它就可以用于web应用程序中的动态图像。
发布于 2019-02-28 04:09:31
...这是品味的问题...
正如@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:
https://stackoverflow.com/questions/41013389
复制相似问题