0

I'm trying to install the "Gnuplot-py" package on my Mac using this command "python setup.py install" within the gnuplot-py-1.8 directory but I get this error:

Traceback (most recent call last):

File "/Users/sebydc77/Downloads/gnuplot-py-1.8/PlotItems.py", line 20, in from cStringIO import StringIO ModuleNotFoundError: No module named 'cStringIO'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):

File "setup.py", line 15, in from init import version File "/Users/sebydc77/Downloads/gnuplot-py-1.8/init.py", line 166, in from PlotItems import PlotItem, Func, File, Data, GridData File "/Users/sebydc77/Downloads/gnuplot-py-1.8/PlotItems.py", line 22, in from StringIO import StringIO ModuleNotFoundError: No module named 'StringIO'

I spent at least 3 hours trying to solve this problem. I also tried different alternatives such as "pip install Gnuplot-py", "pip install download link..." etc...

(NOTE: I already have gnuplot installed on my machine)

miken32
  • 42,008
  • 16
  • 111
  • 154
  • looks like you are using Python 3 (judging by the missing `StringIO` module)? Gnuplot-py works only with Python 2.X I believe - http://stackoverflow.com/a/12840346/5351549 – ewcz Feb 25 '17 at 09:32
  • You were partly right. I created a new environment with miniconda for the 2.7 version. At first I got an error, but these commands solved it: 1) brew install Caskroom/cask/aquaterm 2) brew reinstall gnuplot --with-aquaterm THANK YOU SO MUCH FOR YOUR HELP! – Alexander Li Feb 26 '17 at 03:09

1 Answers1

0

As mentioned, the module doesn't work with Python 3.

But it isn't all that hard to write a custom plot function using gnuplot in Python. Below is an example that I wrote to make a graph of the infusion of carbon fiber laminates with epoxy resin. During the infusion, the pail of resin is placed on a scale, so I can write down the remaining weight every couple of minutes.

The main input for the plot function is a numpy array where I have recorded the time and amount of resin still in the bucket. This amount goes down over time, so I use this data to calculate the total amount of injected resin at every point and the speed with which the resin flows. That's where numpy comes in handy!

Basically this function creates a list of lines containing gnuplot commands and inline data, which is then joined into a single string and fed to gnuplot running as a subprocess.

import subprocess
import numpy as np


def plot(rawdata, filename, maxy=None, labels=False, n=2):
    """Plot injection data with gnuplot.

    Arguments:
        data: numpy array of shape (N,2)
            (Time, weight) pairs as written down during the injection. The time
            in minutes increases and the weight in grams decreases.
        filename: string
            Name to write the output figure to.
        maxy: Maximum y coordinate for the left axis (injected weight).
            The right axis (injection speed) is 1/10th of the left axis.
            When set to None, automatic scaling is used.
        labels: Label every n-th data point when true.
        n: Print every n-th value as a label.
    """
    gtype = 'lines'
    if labels:
        gtype = 'linespoints'
    delta = rawdata[1:] - rawdata[:-1]
    totals = np.array([[0, 0]] + [[dt, -dm] for dt, dm in delta])
    som = np.cumsum(totals, axis=0)
    print('harshoeveelheid "{}": {} g'.format(filename, som[-1, 1]))
    if maxy is None:
        maxy = round(som[-1, 1], -2)
    dm = np.array([[0]] + [[-dm/dt] for dt, dm in delta])
    newdata = np.hstack((som, dm))
    newdata[0, 2] = newdata[1, 2]
    l1 = 'set label "{:.0f} g" at {},{} center offset 0,0.5'
    l2 = 'set label "{:.0f} g/min" at {},second {} center offset 0,0.5'
    p1 = 'plot "-" with {gt} ls 1 title "harshoeveelheid", ' \
        '"-" with {gt} axes x1y2 ls 2 title "injectiesnelheid"'
    lp1 = ', "-" using 1:2:2 with labels right offset character 0.4,0.7' \
        'font "Alegreya, 8" tc ls 1 notitle'
    lp2 = ', "-" using 1:2:2 axis x1y2 with labels left offset character ' \
        '0.5,0.7 font "Alegreya, 8" tc ls 2 notitle'
    text = ['set terminal pdfcairo enhanced color dashed font "Alegreya, 11" '
            'rounded size 12.8 cm, 7.0 cm',
            'set xlabel "tijd [min]"',
            'set ylabel "harshoeveelheid [g]"',
            'set y2label "injectiesnelheid [g/min]"',
            'set y2tics',
            'set yrange [0:{:.0f}]'.format(maxy),
            'set y2range [0:{:.0f}]'.format(maxy/10),
            'set key left bottom',
            'set grid']
    if not labels:
        text.append(l1.format(newdata[-1, 1], newdata[-1, 0], newdata[-1, 1]))
        text.append(l2.format(newdata[-1, 2], newdata[-1, 0], newdata[-1, 2]))
    text.append('set output "{}"'.format(filename + '.pdf'))
    text.append(p1.format(gt=gtype))
    if labels:
        text[-1] += lp1 + lp2
    data1 = ['{:2.0f} {:4.0f}'.format(a, b) for a, b, _ in newdata]
    data2 = ['{:2.0f} {:4.0f}'.format(a, b) for a, _, b in newdata]
    text += data1
    text.append('e')
    text += data2
    text.append('e')
    if labels:
        data1 = ['{:2.0f} {:4.0f}'.format(a, b) for a, b, _ in newdata[n-1::n]]
        data2 = ['{:2.0f} {:4.0f}'.format(a, b) for a, _, b in newdata[n-1::n]]
        text += data1
        text.append('e')
        text += data2
        text.append('e')
    p = subprocess.Popen(['gnuplot'], stdin=subprocess.PIPE)
    _, _ = p.communicate(input='\n'.join(text).encode('utf-8'))

The output looks something like this: example infusion picture

Note that the style of the graph is determined by the settings in my gnuplotrc file.

Roland Smith
  • 42,427
  • 3
  • 64
  • 94