将Python函数传递给Gnuplot [英] Passing Python functions to Gnuplot

查看:71
本文介绍了将Python函数传递给Gnuplot的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尽管在Gnuplot中绘制Python函数并不简单 是一些解决方案.例如,可以将其值转换为数组或 手动将其表达式转换为Gnuplot的语法.这是一个 使用模块 作为界面:

Plotting a Python function in Gnuplot is not straightforward although there are some solutions. For example, one could either cast its values into an array or manually translate its expression into Gnuplot’s syntax. Here is an example that uses the module Gnuplot.py as an interface:

#!/usr/bin/env python

import Gnuplot
import numpy as np

## define function ##
func = lambda x, x0, y0, w: y0 * np.exp( -4*np.log(2) * ( (x-x0) / w )**2 )
# also works with a regular function:
# def func(x, x0, y0, w):
    # return y0 * np.exp( -4*np.log(2) * ( (x-x0) / w )**2 )
popt = (10.1, 5, 2)

## linspace ##
x = np.linspace(0, 20, num=1000) # (x min, x max, number of points)
y = func(x, *popt)
func_linspace = Gnuplot.Data(x, y, with_='lines', title='linspace')

## expression "translation" (lambda only) ##
func_translation = Gnuplot.Func(
    '{y0} * exp( -4*log(2) * ( (x-{x0}) / {w} )**2 )'.format(
        x0=popt[0],
        y0=popt[1],
        w=popt[2],
        ),
    title='expression translation')

## plot ##
g = Gnuplot.Gnuplot()
g.plot(func_linspace, func_translation)

第一种方法可以在相当数量的点上正常工作,但是在以下情况下会失败 放大过多或将窗口更改为超出阵列的限制,而 第二个可以在任何缩放级别上使用.为了说明这一点,让我们放大 上一个脚本的输出:

The first method works fine with a decent number of points but fails when zooming-in too much or changing the window out of the array’s limits, while the second one works at any zoom level. To illustrate this point, let’s zoom-in the output of the previous script:

由于这个原因,找到一种绘制Python函数的方法将很有趣 (lambda或常规函数)作为 Gnuplot函数.我可以想到两个 解决方案:自动翻译表达式(仅适用于简单" lambda函数"),或者让Gnuplot直接使用Python函数.

For this reason, it would be interesting to find a way to plot Python functions (lambda or regular functions) as Gnuplot functions. I can think of two solution: automatically translating the expression (works only for "simple" lambda functions"), or having Gnuplot directly use the Python function.

此方法不仅要棘手自动化,而且不可能 用精细的功能来实现.但是我们仍然可以使用这种方法 用于简单的lambda函数.要勾画实现的行为,请执行以下操作:

This method would not only be tricky to automate, it would also be impossible to implement with elaborate functions. However we could still use this method for simple lambda functions. To sketch the behaviour of an implementation:

>>> def lambda_to_gnuplot(func, popt):
...     # determine if translation is possible
...     # extract function expression and replace parameters with values
...     return func_expression # str
>>> lambda_to_gnuplot(
...     lambda x, x0, y0, w: y0 * np.exp( -4*np.log(2) * ( (x-x0) / w )**2),
...     (10.1, 5, 2))
'5 * exp( -4*log(2) * ( (x-10.1) / 2 )**2 )'

是否可以在python中实现此lambda_to_gnuplot函数?

完美"的解决方案是让Gnuplot使用Python函数.在我的 最大胆的梦想,是这样的:

The "perfect" solution would be having Gnuplot use the Python function. In my most daring dreams, it is something like:

>>> def func(x, x0, y0, w):
...     if x < x0:
...         return 0
...     else:
...         return y0 * np.exp( -4*np.log(2) * ( (x-x0) / w )**2)
>>> func_direct = Gnuplot.PyFunction(lambda x: func(x, 10.1, 5, 2))
>>> g.plot(func_direct)

这是最容易使用的解决方案,但是其实现将非常 强硬,即使不是不可能. 有关此解决方案可能如何的任何提示 答案当然可以绕过Gnuplot.py.

This is the easiest solution to use, but its implementation would be very tough, if not impossible. Any hints on how this solution might be implemented? The answer may of course bypass Gnuplot.py.

推荐答案

我不确定我是否能完全回答您的问题,但是您可以尝试在gnuplot中作为传递参数的系统调用来执行python脚本

I am not sure if I'm fully answering your question, but you could try executing your python script as a system call within gnuplot passing the argument(s).

例如,想象一下简单的python脚本test.py:

For instance, imagine the simple python script test.py:

import sys

x=float(sys.argv[1])

print x**2

当从shell中这样调用时,它将返回参数的平方:

which will return the square of the argument when called like this from a shell:

:~$ python test.py 2
4.0
:~$ python test.py 3
9.0
:~$ python test.py 4
16.0

现在,在gnuplot中,将其转换为函数:

Now, within gnuplot, turn this into a function:

gnuplot> f(x) = real(system(sprintf("python test.py %g", x)))
gnuplot> print f(1)
1.0
gnuplot> print f(2)
4.0
gnuplot> print f(3)
9.0
gnuplot> print f(4)
16.0

我添加了real(),以便将系统调用输出的字符串转换为float.现在,您可以将其用作常规的gnuplot函数.我不必说这将花费比plot x**2更长的时间:

I added the real() so that the string output from the system call is converted to float. This now allows you to use it as a regular gnuplot function. I don't need to mention this will take a lot longer to execute than just plot x**2:

f(x) = real(system(sprintf("python test.py %g", x)))
plot f(x)

这篇关于将Python函数传递给Gnuplot的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆