Skip to content

Commit 24ec10f

Browse files
committed
Update plot.rb
1 parent 8d6961d commit 24ec10f

File tree

1 file changed

+125
-45
lines changed

1 file changed

+125
-45
lines changed

lib/gr/plot.rb

Lines changed: 125 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@ class Plot
3434
PLOT_KIND = %i[
3535
line
3636
step
37+
stairs
3738
scatter
3839
stem
40+
bar
3941
hist
4042
contour
4143
contourf
@@ -90,6 +92,7 @@ class Plot
9092
location
9193
markersize
9294
nbins
95+
panzoom
9396
ratio
9497
rotation
9598
scale
@@ -173,9 +176,26 @@ class Plot
173176
'S' => 1.5 * Math::PI
174177
}.freeze
175178

179+
COLORS = [
180+
[0xffffff, 0x000000, 0xff0000, 0x00ff00, 0x0000ff, 0x00ffff, 0xffff00, 0xff00ff],
181+
[0x282c34, 0xd7dae0, 0xcb4e42, 0x99c27c, 0x85a9fc, 0x5ab6c1, 0xd09a6a, 0xc57bdb],
182+
[0xfdf6e3, 0x657b83, 0xdc322f, 0x859900, 0x268bd2, 0x2aa198, 0xb58900, 0xd33682],
183+
[0x002b36, 0x839496, 0xdc322f, 0x859900, 0x268bd2, 0x2aa198, 0xb58900, 0xd33682]
184+
].freeze
185+
186+
DISTINCT_CMAP = [0, 1, 984, 987, 989, 983, 994, 988].freeze
187+
176188
@last_plot = nil
189+
@scheme = 0
190+
177191
class << self
178-
attr_accessor :last_plot
192+
attr_accessor :last_plot, :scheme
193+
194+
def usecolorscheme(index)
195+
raise 'Invalid color scheme' unless index >= 1 && index <= 4
196+
197+
@scheme = index
198+
end
179199
end
180200

181201
attr_accessor :args, :kvs, :scheme
@@ -198,7 +218,7 @@ def initialize(*raw_args)
198218
kvs[:clear] = true unless kvs.has_key? :clear
199219
kvs[:update] = true unless kvs.has_key? :update
200220

201-
@scheme = 0
221+
@scheme = self.class.scheme
202222
@background = 0xffffff
203223
# @handle = nil # This variable will be used in gr_meta
204224

@@ -763,7 +783,7 @@ def colorbar(off = 0, colors = 256)
763783
GR.inqscale
764784
end
765785
GR.setscale(options & mask)
766-
h = 0.5 * (zmax - zmin) / (colors - 1)
786+
h = 0 # 0.5 * (zmax - zmin) / (colors - 1)
767787
GR.setwindow(0, 1, zmin, zmax)
768788
GR.setclipregion(GR::REGION_RECTANGLE)
769789
GR.setviewport(viewport[1] + 0.02 + off, viewport[1] + 0.05 + off,
@@ -786,6 +806,14 @@ def colorbar(off = 0, colors = 256)
786806
GR.restorestate
787807
end
788808

809+
def rgb(color)
810+
[
811+
((color >> 16) & 0xff) / 255.0,
812+
((color >> 8) & 0xff) / 255.0,
813+
(color & 0xff) / 255.0
814+
]
815+
end
816+
789817
def plot_data(_figure = true)
790818
# GR.init
791819

@@ -803,7 +831,23 @@ def plot_data(_figure = true)
803831
GR.clearws if kvs[:clear]
804832

805833
if scheme != 0
806-
# Not yet.
834+
8.times do |colorind|
835+
color = COLORS[scheme - 1][colorind]
836+
r, g, b = rgb(color)
837+
GR.setcolorrep(colorind, r, g, b)
838+
GR.setcolorrep(DISTINCT_CMAP[colorind], r, g, b) if scheme != 1
839+
end
840+
841+
r, g, b = rgb(COLORS[scheme - 1][0])
842+
r2, g2, b2 = rgb(COLORS[scheme - 1][1])
843+
rdiff = r2 - r
844+
gdiff = g2 - g
845+
bdiff = b2 - b
846+
847+
12.times do |colorind|
848+
f = colorind / 11.0
849+
GR.setcolorrep(91 - colorind, r + f * rdiff, g + f * gdiff, b + f * bdiff)
850+
end
807851
end
808852

809853
if kvs.has_key?(:font)
@@ -854,14 +898,26 @@ def plot_data(_figure = true)
854898

855899
when :line
856900
mask = GR.uselinespec(spec)
857-
linewidth = kvs[:linewidth]
858-
# Slightly different from Julia,
859-
# Because the implementation of polyline and polymarker is different.
860-
z ||= linewidth # FIXME
861-
GR.polyline(x, y, z, c) if hasline(mask)
862-
GR.polymarker(x, y, z, c) if hasmarker(mask)
863-
864-
when :step
901+
if c
902+
linewidth = kvs[:linewidth] || 1
903+
z = Array.new(x.length, linewidth)
904+
GR.polyline(x, y, z, c)
905+
else
906+
if hasline(mask)
907+
linewidth = kvs[:linewidth] || 1
908+
GR.setlinewidth(linewidth)
909+
GR.polyline(x, y)
910+
end
911+
if hasmarker(mask)
912+
markersize = kvs[:markersize] || 1
913+
GR.setmarkersize(markersize)
914+
borderwidth = kvs[:borderwidth] || 1
915+
GR.setborderwidth(borderwidth)
916+
GR.polymarker(x, y)
917+
end
918+
end
919+
920+
when :step, :stairs
865921
mask = GR.uselinespec(spec)
866922
if hasline(mask)
867923
where = kvs[:where] || 'mid'
@@ -895,43 +951,48 @@ def plot_data(_figure = true)
895951

896952
when :scatter
897953
GR.setmarkertype(GR::MARKERTYPE_SOLID_CIRCLE)
898-
z = z&.map { |i| i * 0.01 }
899-
c = c&.map { |i| normalize_color(i, *kvs[:crange]) }
900-
GR.polymarker(x, y, z, c)
954+
if z || c
955+
if c
956+
cmin, cmax = kvs[:crange]
957+
c = c.map { |i| normalize_color(i, cmin, cmax) }
958+
c = c.map { |i| (1000 + i * 255).round }
959+
end
960+
GR.polymarker(x, y, z, c)
961+
else
962+
GR.polymarker(x, y)
963+
end
901964

902965
when :stem
903-
GR.setlinecolorind(1)
904-
GR.polyline(kvs[:window][0..1], [0, 0])
905966
GR.setmarkertype(GR::MARKERTYPE_SOLID_CIRCLE)
906967
GR.uselinespec(spec)
907968
x = x.to_a if narray?(x)
908969
y = y.to_a if narray?(y)
909970
x.zip(y).each do |xi, yi|
910971
GR.polyline([xi, xi], [0, yi])
972+
GR.polymarker([xi], [yi])
973+
end
974+
GR.setlinecolorind(1)
975+
GR.polyline(kvs[:window][0..1], [0, 0])
976+
977+
when :bar
978+
(0...x.length).step(2) do |i|
979+
GR.setfillcolorind(989)
980+
GR.setfillintstyle(GR::INTSTYLE_SOLID)
981+
GR.fillrect(x[i], x[i + 1], y[i], y[i + 1])
982+
GR.setfillcolorind(1)
983+
GR.setfillintstyle(GR::INTSTYLE_HOLLOW)
984+
GR.fillrect(x[i], x[i + 1], y[i], y[i + 1])
911985
end
912-
GR.polymarker(x, y)
913986

914987
when :hist
915-
if kvs[:horizontal]
916-
xmin = kvs[:window][0]
917-
x.length.times do |i|
918-
GR.setfillcolorind(989)
919-
GR.setfillintstyle(GR::INTSTYLE_SOLID)
920-
GR.fillrect(xmin, x[i], y[i], y[i + 1])
921-
GR.setfillcolorind(1)
922-
GR.setfillintstyle(GR::INTSTYLE_HOLLOW)
923-
GR.fillrect(xmin, x[i], y[i], y[i + 1])
924-
end
925-
else
926-
ymin = kvs[:window][2]
927-
y.length.times do |i|
928-
GR.setfillcolorind(989)
929-
GR.setfillintstyle(GR::INTSTYLE_SOLID)
930-
GR.fillrect(x[i], x[i + 1], ymin, y[i])
931-
GR.setfillcolorind(1)
932-
GR.setfillintstyle(GR::INTSTYLE_HOLLOW)
933-
GR.fillrect(x[i], x[i + 1], ymin, y[i])
934-
end
988+
ymin = kvs[:window][2]
989+
y.length.times do |i|
990+
GR.setfillcolorind(989)
991+
GR.setfillintstyle(GR::INTSTYLE_SOLID)
992+
GR.fillrect(x[i], x[i + 1], ymin, y[i])
993+
GR.setfillcolorind(1)
994+
GR.setfillintstyle(GR::INTSTYLE_HOLLOW)
995+
GR.fillrect(x[i], x[i + 1], ymin, y[i])
935996
end
936997

937998
when :polarhist
@@ -1485,6 +1546,11 @@ def step(*args)
14851546
create_plot(:step, *args)
14861547
end
14871548

1549+
# (Plot) Draw one or more step or staircase plots.
1550+
def stairs(*args)
1551+
create_plot(:stairs, *args)
1552+
end
1553+
14881554
# (Plot) Draw one or more scatter plots.
14891555
def scatter(*args)
14901556
create_plot(:scatter, *args)
@@ -1616,11 +1682,22 @@ def volume(v, kv = {})
16161682
end
16171683

16181684
# (Plot) Draw a bar plot.
1619-
def barplot(labels, heights, kv = {})
1685+
def barplot(*args)
1686+
kv = args.last.is_a?(Hash) ? args.pop : {}
1687+
if args.length == 2
1688+
labels, heights = args
1689+
elsif args.length == 1
1690+
heights = args[0]
1691+
labels = (1..heights.length).map(&:to_s)
1692+
else
1693+
raise ArgumentError
1694+
end
1695+
16201696
labels = labels.map(&:to_s)
1621-
wc, hc = barcoordinates(heights)
1697+
wc, hc = barcoordinates(heights, kv)
1698+
horizontal = kv.delete(:horizontal)
16221699
create_plot(:bar, labels, heights, kv) do |plt|
1623-
if kv[:horizontal]
1700+
if horizontal
16241701
plt.args = [[hc, wc, nil, nil, '']]
16251702
plt.kvs[:yticks] = [1, 1]
16261703
plt.kvs[:yticklabels] = labels
@@ -1634,10 +1711,11 @@ def barplot(labels, heights, kv = {})
16341711

16351712
# (Plot) Draw a histogram.
16361713
def histogram(series, kv = {})
1714+
horizontal = kv.delete(:horizontal)
16371715
create_plot(:hist, series, kv) do |plt|
16381716
nbins = plt.kvs[:nbins] || 0
16391717
x, y = hist(series, nbins)
1640-
plt.args = if kv[:horizontal]
1718+
plt.args = if horizontal
16411719
[[y, x, nil, nil, '']]
16421720
else
16431721
[[x, y, nil, nil, '']]
@@ -1751,13 +1829,15 @@ def hist(x, nbins = 0)
17511829
[x, y]
17521830
end
17531831

1754-
def barcoordinates(heights, barwidth = 0.8, baseline = 0.0)
1832+
def barcoordinates(heights, kv = {})
1833+
barwidth = kv[:barwidth] || 0.8
1834+
baseline = kv[:baseline] || 0.0
17551835
halfw = barwidth / 2.0
17561836
wc = []
17571837
hc = []
17581838
heights.each_with_index do |value, i|
1759-
wc << i - halfw
1760-
wc << i + halfw
1839+
wc << (i + 1) - halfw
1840+
wc << (i + 1) + halfw
17611841
hc << baseline
17621842
hc << value
17631843
end

0 commit comments

Comments
 (0)