@@ -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