Skip to content

Commit 17bdcdc

Browse files
committed
Merge branch 'master' into debian
2 parents 69b3cfc + 0523e00 commit 17bdcdc

4 files changed

Lines changed: 361 additions & 170 deletions

File tree

README.org

Lines changed: 73 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ gnuplotlib: a gnuplot-based plotting backend for numpy
44
#+BEGIN_SRC python
55
import numpy as np
66
import gnuplotlib as gp
7-
from scipy.constants import pi
87

98
x = np.arange(101) - 50
109
gp.plot(x**2)
@@ -29,12 +28,13 @@ gnuplotlib: a gnuplot-based plotting backend for numpy
2928
[ Heat map pops up where first parabola used to be ]
3029

3130

32-
theta = np.linspace(0, 6*pi, 200)
33-
z = np.linspace(0, 5, 200)
31+
theta = np.linspace(0, 6*np.pi, 200)
32+
z = np.linspace(0, 5, 200)
3433
g2 = gp.gnuplotlib(_3d = True)
35-
g2.plot( (np.cos(theta), np.sin(theta), z),
36-
(np.cos(theta), -np.sin(theta), z))
37-
[ Two 3D curves together in a new window: spirals ]
34+
g2.plot( np.cos(theta),
35+
np.vstack((np.sin(theta), -np.sin(theta))),
36+
z )
37+
[ Two 3D spirals together in a new window ]
3838
#+END_SRC
3939

4040

@@ -115,18 +115,56 @@ Plot generation is controlled by two sets of options:
115115

116116
** Data arguments
117117

118-
The 'curves' arguments in the plot(...) argument list represent the actual data
119-
being plotted. Each output data point is a tuple whose size varies depending on
120-
what is being plotted. For example if we're making a simple 2D x-y plot, each
121-
tuple has 2 values; if we're making a 3d plot with each point having variable
122-
size and color, each tuple has 5 values (x,y,z,size,color). In the plot(...)
123-
argument list each tuple element must be passed separately. If we're making
124-
anything fancier than a simple 2D or 3D plot (2- and 3- tuples respectively)
125-
then the 'tuplesize' curve option MUST be passed in.
118+
The 'curve' arguments in the plot(...) argument list represent the actual data
119+
being plotted. Each output data point is a tuple (set of values, not a python
120+
"tuple") whose size varies depending on what is being plotted. For example if
121+
we're making a simple 2D x-y plot, each tuple has 2 values; if we're making a 3d
122+
plot with each point having variable size and color, each tuple has 5 values
123+
(x,y,z,size,color). In the plot(...) argument list each tuple element must be
124+
passed separately. If we're making anything fancier than a simple 2D or 3D plot
125+
(2- and 3- tuples respectively) then the 'tuplesize' curve option MUST be passed
126+
in.
126127

127-
Currently each array is assumed to be 1D for normal plots and 2D for matrix
128-
plots. At some point I'll implement broadcasting to allow packed arrays, but not
129-
yet (numpy is missing thread_define from PDL)
128+
Furthermore, broadcasting is fully supported, so multiple curves can be plotted
129+
by stacking data inside the passed-in arrays. Broadcasting works across curve
130+
options also, so things like curve labels and styles can also be stacked inside
131+
arrays. An example:
132+
133+
#+BEGIN_SRC python
134+
th = np.linspace(0, 6*np.pi, 200)
135+
z = np.linspace(0, 5, 200)
136+
size = 0.5 + np.abs(np.cos(th))
137+
color = np.sin(2*th)
138+
139+
140+
# without broadcasting:
141+
plot3d( ( np.cos(th), np.sin(th)
142+
z, size, color,
143+
{ 'legend': 'spiral 1'}),
144+
145+
( -np.cos(th), -np.sin(th)
146+
z, size, color,
147+
{ 'legend': 'spiral 2'})
148+
149+
title = 'double helix', tuplesize = 5,
150+
_with = 'points pointsize variable pointtype 7 palette' )
151+
152+
153+
# identical plot using broadcasting:
154+
plot3d( ( np.cos(th) * np.array([[1,-1]]).T,
155+
np.sin(th) * np.array([[1,-1]]).T,
156+
z, size, color, { 'legend': np.array(('spiral 1', 'spiral 2'))})
157+
158+
title = 'double helix', tuplesize = 5,
159+
_with = 'points pointsize variable pointtype 7 palette' )
160+
#+END_SRC
161+
162+
This is a 3d plot with variable size and color. There are 5 values in the tuple,
163+
which we specify. The first 2 arrays have dimensions (2,N); all the other arrays
164+
have a single dimension. Thus the broadcasting rules generate 2 distinct curves,
165+
with varying values for x,y and identical values for z, size and color. We label
166+
the curves differently by passing an array for the 'legend' curve option. This
167+
array contains strings, and is broadcast like everything else.
130168

131169
*** Implicit domains
132170

@@ -441,8 +479,7 @@ Generates an image plot. Shorthand for 'plot(..., _with='image', tuplesize=3)'
441479

442480
* RECIPES
443481

444-
Most of these come directly from Gnuplot commands. See the Gnuplot docs for
445-
details.
482+
Some different plots appear here. A longer set of demos is given in demos.py.
446483

447484
** 2D plotting
448485

@@ -472,6 +509,9 @@ To change point size and point type:
472509
gp.plot(x,y, _with='points pointtype 4 pointsize 8')
473510
#+END_SRC
474511

512+
Everything (like _with) feeds directly into Gnuplot, so look at the Gnuplot docs
513+
to know how to change thicknesses, styles and such.
514+
475515
*** Errorbars
476516

477517
To plot errorbars that show y +- 1, plotted with an implicit domain
@@ -551,20 +591,24 @@ If xy is a 2D array, we can plot it as a height map on an implicit domain
551591
plot3d(xy)
552592
#+END_SRC
553593

554-
Complicated 3D plot with fancy styling:
594+
Ellipse and sphere plotted together, using broadcasting:
555595

556596
#+BEGIN_SRC python
557-
th = np.linspace(0, 6*pi, 200)
558-
z = np.linspace(0, 5, 200)
559-
size = 0.5 + np.abs(np.cos(th))
560-
color = np.sin(2*th)
597+
th = np.linspace(0, np.pi*2, 30)
598+
ph = np.linspace(-np.pi/2, np.pi*2, 30)[:,np.newaxis]
561599

562-
plot3d( ( np.cos(th), np.sin(th), z, size, color, {'legend': "spiral 1"}),
563-
(-np.cos(th), -np.sin(th), z, size, color, {'legend': "spiral 2"}),
600+
x_3d = (np.cos(ph) * np.cos(th)) .ravel()
601+
y_3d = (np.cos(ph) * np.sin(th)) .ravel()
602+
z_3d = (np.sin(ph) * np.ones( th.shape )) .ravel()
564603

565-
title = 'double helix',
566-
tuplesize = 5,
567-
_with = 'points pointsize variable pointtype 7 palette' )
604+
gp.plot3d( (x_3d * np.array([[1,2]]).T,
605+
y_3d * np.array([[1,2]]).T,
606+
z_3d,
607+
{ 'legend': np.array(('sphere', 'ellipse'))}),
608+
609+
title = 'sphere, ellipse',
610+
square = True,
611+
_with = 'points')
568612
#+END_SRC
569613

570614
Image arrays plots can be plotted as a heat map:

demo.py

Lines changed: 45 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#!/usr/bin/python
22

33
import numpy as np
4-
from scipy.constants import pi
54
import time
65
import sys
76

@@ -11,8 +10,8 @@
1110
x = np.arange(21) - 10
1211

1312
# data I use for 3D testing
14-
th = np.linspace(0, pi*2, 30)
15-
ph = np.linspace(-pi/2, pi*2, 30)[:,np.newaxis]
13+
th = np.linspace(0, np.pi*2, 30)
14+
ph = np.linspace(-np.pi/2, np.pi*2, 30)[:,np.newaxis]
1615

1716
x_3d = (np.cos(ph) * np.cos(th)) .ravel()
1817
y_3d = (np.cos(ph) * np.sin(th)) .ravel()
@@ -38,27 +37,31 @@
3837
time.sleep(sleep_interval)
3938
gp.plot((-x, x**3, {'with': 'lines'}), (x**2,))
4039
time.sleep(sleep_interval)
40+
gp.plot( x, np.vstack((x**3, x**2)) )
41+
time.sleep(sleep_interval)
42+
gp.plot( np.vstack((-x**3, x**2)), _with='lines' )
43+
time.sleep(sleep_interval)
44+
gp.plot( (np.vstack((x**3, -x**2)), {'with': 'points'} ))
45+
time.sleep(sleep_interval)
4146

4247
#################################
4348
# some more varied plotting, using the object-oriented interface
4449
plot1 = gp.gnuplotlib(_with = 'linespoints',
4550
xmin = -10,
4651
title = 'Error bars and other things')
4752

48-
# this had PDL threading in it. Put it back when packed broadcastable plotting
49-
# is implemented
50-
plot1.plot( ( x, x**2 - 300,
53+
plot1.plot( ( np.vstack((x, x*2, x*3)), x**2 - 300,
5154
{'with': 'lines lw 4',
5255
'y2': True,
53-
'legend': 'a parabola'}),
56+
'legend': 'parabolas'}),
5457

5558
(x**2 * 10, x**2/40, x**2/2, # implicit domain
5659
{'with': 'xyerrorbars',
5760
'tuplesize': 4}),
5861

59-
(x, x**3 - 100,
62+
(x, np.vstack((x**3, x**3 - 100)),
6063
{"with": 'lines',
61-
'legend': 'shifted cubic',
64+
'legend': 'shifted cubics',
6265
'tuplesize': 2}))
6366
time.sleep(sleep_interval)
6467

@@ -89,11 +92,10 @@
8992
time.sleep(sleep_interval)
9093

9194
# sphere, ellipse together
92-
# put broadcasting here
93-
gp.plot3d( (x_3d, y_3d, z_3d,
94-
{ 'legend': 'sphere'}),
95-
(2*x_3d, 2*y_3d, z_3d,
96-
{ 'legend': 'ellipse'}),
95+
gp.plot3d( (x_3d * np.array([[1,2]]).T,
96+
y_3d * np.array([[1,2]]).T,
97+
z_3d,
98+
{ 'legend': np.array(('sphere', 'ellipse'))}),
9799

98100
title = 'sphere, ellipse',
99101
square = True,
@@ -102,11 +104,10 @@
102104

103105

104106
# similar, written to a png
105-
# put broadcasting here
106-
gp.plot3d( (x_3d, y_3d, z_3d,
107-
{ 'legend': 'sphere'}),
108-
(2*x_3d, 2*y_3d, z_3d,
109-
{ 'legend': 'ellipse'}),
107+
gp.plot3d( (x_3d * np.array([[1,2]]).T,
108+
y_3d * np.array([[1,2]]).T,
109+
z_3d,
110+
{ 'legend': np.array(('sphere', 'ellipse'))}),
110111

111112
title = 'sphere, ellipse',
112113
square = True,
@@ -128,13 +129,14 @@
128129
time.sleep(sleep_interval)
129130

130131
# 3d, variable color, variable pointsize
131-
th = np.linspace(0, 6*pi, 200)
132-
z = np.linspace(0, 5, 200)
132+
th = np.linspace(0, 6*np.pi, 200)
133+
z = np.linspace(0, 5, 200)
133134
size = 0.5 + np.abs(np.cos(th))
134135
color = np.sin(2*th)
135136

136-
gp.plot3d( ( np.cos(th), np.sin(th), z, size, color, {'legend': "spiral 1"}),
137-
(-np.cos(th), -np.sin(th), z, size, color, {'legend': "spiral 2"}),
137+
gp.plot3d( ( np.cos(th) * np.array([[1,-1]]).T,
138+
np.sin(th) * np.array([[1,-1]]).T,
139+
z, size, color, { 'legend': np.array(('spiral 1', 'spiral 2'))}),
138140

139141
title = 'double helix',
140142
tuplesize = 5,
@@ -157,7 +159,7 @@
157159
x = np.linspace(0,20,100)
158160
gp.plot( ( z, {'tuplesize': 3,
159161
'with': 'image'}),
160-
(x, 20*np.cos(x/20 * pi/2),
162+
(x, 20*np.cos(x/20 * np.pi/2),
161163

162164
{'tuplesize': 2,
163165
'with': 'lines'}),
@@ -198,11 +200,10 @@
198200
ascii = False)
199201
time.sleep(sleep_interval)
200202

201-
# 2 3d matrix curves
202-
gp.plot((x, {'tuplesize': 3,
203-
'with': 'points palette pt 7'}),
204-
(z, {'tuplesize': 3,
205-
'with': 'points ps variable pt 6'}),
203+
# Using broadcasting to plot each slice with aa different style
204+
gp.plot((np.rollaxis( np.dstack((x,z)), 2,0),
205+
{'tuplesize': 3,
206+
'with': np.array(('points palette pt 7','points ps variable pt 6'))}),
206207

207208
title = '2 3D matrix plots. Binary.',
208209
square = 1,
@@ -219,10 +220,9 @@
219220
# time.sleep(sleep_interval)
220221

221222
# 2 3d matrix curves
222-
gp.plot((x, {'tuplesize': 3,
223-
'with': 'points palette pt 7'}),
224-
(z, {'tuplesize': 3,
225-
'with': 'points ps variable pt 6'}),
223+
gp.plot((np.rollaxis( np.dstack((x,z)), 2,0),
224+
{'tuplesize': 3,
225+
'with': np.array(('points palette pt 7','points ps variable pt 6'))}),
226226

227227
title = '2 3D matrix plots. Binary.',
228228
square = 1,
@@ -237,17 +237,17 @@
237237
y -= 30.0
238238
z = np.sin(x / 4.0) * y
239239

240-
# single 3d matrix curve
241-
gp.plot3d( (z, {'tuplesize': 3, 'with': 'image'}),
242-
(z, {'tuplesize': 3, 'with': 'lines'}),
243-
244-
title = 'matrix plot with contours',
245-
cmds = [ 'set contours base',
246-
'set cntrparam bspline',
247-
'set cntrparam levels 15',
248-
'unset grid',
249-
'unset surface',
250-
'set view 0,0'],
240+
# single 3d matrix curve. Two plots: the image and the contours together.
241+
# Broadcasting the styles
242+
gp.plot3d( (z, {'tuplesize': 3, 'with': np.array(('image','lines'))}),
243+
244+
title = 'matrix plot with contours',
245+
cmds = [ 'set contours base',
246+
'set cntrparam bspline',
247+
'set cntrparam levels 15',
248+
'unset grid',
249+
'unset surface',
250+
'set view 0,0'],
251251
square = 1 )
252252
time.sleep(sleep_interval)
253253

@@ -261,7 +261,7 @@
261261
sys.stderr.write('I should complain about an invalid "with":\n')
262262
sys.stderr.write("=================================\n")
263263
try:
264-
gp.plot(x, _with = 'bogusstyle')
264+
gp.plot(np.arange(5), _with = 'bogusstyle')
265265
except gp.GnuplotlibError as e:
266266
print("OK! Got err I was supposed to get:\n[[[[[[[\n{}\n]]]]]]]\n".format(e))
267267
except:

0 commit comments

Comments
 (0)