Skip to content

Commit

Permalink
Rework of gnuplot
Browse files Browse the repository at this point in the history
  • Loading branch information
István Bozsó committed Jul 12, 2019
1 parent 439dc9a commit 318a71f
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 117 deletions.
256 changes: 140 additions & 116 deletions gnuplot/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,22 @@
from builtins import str
from numbers import Number
from tempfile import mkstemp
from os import fdopen
from os import fdopen, path as pth
from sys import stderr, platform
from atexit import register
import subprocess as sub
from tempfile import _get_default_tempdir, _get_candidate_names
from time import sleep

from .private import color_palettes, Axis
try:
from IPython.display import Image, display
except ImportError:
Image = None


__all__ = (
"arrow", "call", "colorbar", "debug", "histo", "label", "line", "linedef",
"margins", "multiplot", "obj", "output", "palette", "plot", "data",
"file", "grid", "refresh", "replot", "reset", "save", "set", "silent",
"splot", "style", "term", "title", "unset_multi", "colors",
"x", "y", "z", "sym", "col"
)
# TODO:
# set commands should come after set out and set term
#


config = {
Expand All @@ -44,88 +45,128 @@
"silent": False,
"exe": "gnuplot",
"size": (800, 600),
"startup":
"2D":
"""
set style line 11 lc rgb 'black' lt 1
set border 3 back ls 11 lw 2.5
set tics nomirror
set style line 12 lc rgb 'black' lt 0 lw 1
set grid back ls 12 lw 2.0
""",
"3D":
"""
set style line 11 lc rgb 'black' lt 1
set border 3 back ls 11 lw 2.5
set tics nomirror
set style line 12 lc rgb 'black' lt 0 lw 1
set grid back ls 12 lw 2.5
set grid back ls 12 lw 2.0
"""
}


tmp_path = _get_default_tempdir()

process, multi, debug, silent, plot_items = \
None, None, config["debug"], config["silent"], []

def get_tmp(path=tmp_path):
return pth.join(path, next(_get_candidate_names()))

def startup():
global process

if config["persist"]:
cmd = [config["exe"], "--persist"]
else:
cmd = [config["exe"]]

process = sub.Popen(cmd, stderr=sub.STDOUT, stdin=sub.PIPE)


startup()

def close():
global process
if multi is not None:
call("unset multiplot")

if process is not None:
process.stdin.close()
retcode = process.wait()
process = None
from .private import color_palettes, Axis


register(close)

write = process.stdin.write
flush = process.stdin.flush
__all__ = (
"arrow", "call", "colorbar", "histo", "label", "line", "linedef",
"margins", "multiplot", "obj", "output", "palette", "plot", "data",
"file", "grid", "refresh", "replot", "reset", "save", "set", "silent",
"splot", "style", "term", "title", "unset_multi", "colors",
"x", "y", "z", "sym", "col", "update"
)


def call(*commands):
global debug
def update(**kwargs):
config.update(kwargs)


for command in commands:
if debug:
stderr.write("gnuplot> %s\n" % command)
class Gnuplot(object):
def __init__(self):
self.multi = self.process = None

if config["persist"]:
cmd = [config["exe"], "--persist"]
else:
cmd = [config["exe"]]

self.process = sub.Popen(cmd, stderr=sub.STDOUT, stdin=sub.PIPE)

self.write, self.flush= \
self.process.stdin.write, self.process.stdin.flush

write(bytes(b"%s\n" % bytes(command, encoding='utf8')))
flush()

call(config["startup"])

x = Axis(call, "x")
y = Axis(call, "y")
z = Axis(call, "z")


def refresh(plot_cmd):
global plot_items
plot_cmds = ", ".join(plot.command for plot in plot_items)

if debug:
stderr.write("gnuplot> %s %s\n" % (plot_cmd, plot_cmds))
def __del__(self):
if self.multi is not None:
self("unset multiplot")

process = self.process

if process is not None:
process.stdin.close()
retcode = process.wait()
self.process = None

call(plot_cmd + " " + plot_cmds + "\n")

data = tuple(plot.data for plot in plot_items
if plot.data is not None)
def __call__(self, *commands):
debug, write, flush = config["debug"], self.write, self.flush

for command in commands:
if debug:
stderr.write("gnuplot> %s\n" % command)

write(bytes(b"%s\n" % bytes(command, encoding='utf8')))
flush()

if data:
write("\ne\n".join(data) + "\ne\n")

def refresh(self, plot_cmd, *items):
plot_cmds = ", ".join(plot.command for plot in items)

if config["debug"]:
stderr.write("gnuplot> %s %s\n" % (plot_cmd, plot_cmds))

if debug:
stderr.write("\ne\n".join(data) + "\ne\n")
self(plot_cmd + " " + plot_cmds + "\n")

data = tuple(plot.data for plot in items
if plot.data is not None)

if data:
self.write("\ne\n".join(data) + "\ne\n")

if debug:
stderr.write("\ne\n".join(data) + "\ne\n")

self.flush()

flush()
plot_items = []

def get_debug(self):
return self.debug

def set_debug(self, debug):
print("Set debug.")
self.debug = debug

session = Gnuplot()

call, flush, refresh = session.__call__, session.flush, session.refresh
silent = config["silent"]


# TODO: properly provide access to debug
# debug = property(session.get_debug, session.set_debug)


x = Axis(call, "x")
y = Axis(call, "y")
z = Axis(call, "z")


def data(*arrays, ltype="points", **kwargs):
Expand All @@ -140,7 +181,7 @@ def data(*arrays, ltype="points", **kwargs):

array, text = _convert_data(data, **kwargs)

plot_items.append(PlotDescription(array, text, **kwargs))
return PlotDescription(array, text, **kwargs)


def grid(data, x=None, y=None, **kwargs):
Expand Down Expand Up @@ -178,7 +219,7 @@ def grid(data, x=None, y=None, **kwargs):

array, text = _convert_data(grid, grid=True, **kwargs)

plot_items.append(PlotDescription(array, text, **kwargs))
return PlotDescription(array, text, **kwargs)


def line(pos, mode, start=0.0, stop=1.0, ref="graph", **kwargs):
Expand All @@ -200,7 +241,7 @@ def histo(edges, hist, **kwargs):

vith = "boxes fill solid {}".format(" ".join(gp.parse_kwargs(**kwargs)))

data(edges, hist, vith=vith, **kwargs)
return data(edges, hist, vith=vith, **kwargs)


# TODO: rewrite docs
Expand Down Expand Up @@ -269,16 +310,33 @@ def file(data, matrix=None, binary=None, array=None, endian="default",
elif binary:
text += " binary"

plot_items.append(PlotDescription(None, text, **kwargs))
return PlotDescription(None, text, **kwargs)


def plot():
if not silent:
refresh("plot")
def plot_ipython(plot_cmd, *items, **kwargs):
if Image is not None:
tmp = get_tmp() + ".png"

kwargs.setdefault("term", "pngcairo")
output(tmp, **kwargs)

if not silent:
refresh(plot_cmd, *items)

sleep(1.0)

display(Image(filename=tmp))

return tmp
elif not silent:
refresh(plot_cmd, *items)


def plot(*items, **kwargs):
return plot_ipython("plot", *items, **kwargs)

def splot():
if not silent:
refresh("splot")
def splot(*items, **kwargs):
return plot_ipython("splot", *items, **kwargs)


def _convert_data(data, grid=False, **kwargs):
Expand Down Expand Up @@ -382,18 +440,6 @@ def reset():
call("reset")


def xtics(*args):
call("set xtics %s" % (parse_range(args)))


def ytics(*args):
call("set ytics %s" % (parse_range(args)))


def ztics(*args):
call("set ztics %s" % (parse_range(args)))


def style(stylenum, ltype, **kwargs):
"""
Parameters
Expand Down Expand Up @@ -450,29 +496,6 @@ def label(definition, position, **kwargs):
% (definition, position[0], position[1], font, fontsize))



def ranges(x=None, y=None, z=None):
if x is not None and len(x) == 2:
call("set xrange [%f:%f]" % (x[0], x[1]))

if y is not None and len(y) == 2:
call("set yrange [%f:%f]" % (y[0], y[1]))

if z is not None and len(z) == 2:
call("set zrange [%f:%f]" % (z[0], z[1]))


def xrange(min, max):
call("set xrange [%f:%f]" % (min, max))


def yrange(min, max):
call("set yrange [%f:%f]" % (min, max))

def zrange(min, max):
call("set zrange [%f:%f]" % (min, max))


def replot():
call("replot")

Expand Down Expand Up @@ -547,10 +570,10 @@ def __init__(self, data, command, **kwargs):
self.command = command + parse_plot_arguments(**kwargs)

def __str__(self):
return "\nData:\n{}\nCommand: {}\n".format(self.data, self.command)
return self.command

def __repr__(self):
return "<PlotDescription data: {} command: {}>".format(self.data, self.command)
return "<PlotDescription data: {}, command: {}>".format(self.data, self.command)


# *************************
Expand Down Expand Up @@ -620,8 +643,9 @@ def parse_plot_arguments(**kwargs):
else:
text += " title '%s'" % (title)


if vith is not None:
if vith is None:
pass
elif vith is not None:
text = "%s with %s" % (text, vith)
else:
add = (parse_linedef(key, value) for key, value in kwargs.items())
Expand Down Expand Up @@ -676,7 +700,7 @@ def parse_set(name, value):
}


colors = {
colors = type("Colors", (object,), {
"red": "#8b1a0e",
"green": "#5e9c36",
"lightgreen": "#4d9178",
Expand All @@ -695,7 +719,7 @@ def parse_set(name, value):
"black": "#111111",
"gray": "#AAAAAA",
"silver": "#DDDDDD"
}
})


# **************
Expand Down
1 change: 0 additions & 1 deletion gnuplot/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ def plot_scatter(gp, data, ncols, out=None, title=None, idx=None, titles=None,
def groupby_plot(gp, x, y, data, by, colors, **kwargs):
fields = np.unique(data[by])


indices = (np.where(data[by] == field) for field in fields)
ldefs = (linedef("points", rgb=cols[color], **kwargs) for color in colors)

Expand Down

0 comments on commit 318a71f

Please sign in to comment.