-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New features #35
New features #35
Changes from all commits
6272855
f5cfae2
f725c88
2863903
9718e2a
20e5db9
80a5a30
f483c66
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#!/bin/env ruby | ||
require_relative "../lib/unicode_plot" | ||
|
||
# example of line plots using different renderers | ||
UnicodePlot.lineplot([1, 2, 7], [9, -6, 8], title: "Default Lineplot").render | ||
UnicodePlot.lineplot([1, 2, 7], [9, -6, 8], title: "Ascii Lineplot", canvas: :ascii).render | ||
UnicodePlot.lineplot([1, 2, 7], [9, -6, 8], title: "Dot Lineplot", canvas: :dot).render | ||
UnicodePlot.lineplot([1, 2, 7], [9, -6, 8], title: "Block Lineplot", canvas: :block).render |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
#!/bin/env ruby | ||
require_relative "../lib/unicode_plot" | ||
|
||
# single plot at a time | ||
UnicodePlot.stairs([1, 2, 4, 7, 8], [1, 3, 4, 2, 7], style: :post).render | ||
|
||
# pre: style | ||
UnicodePlot.stairs([1, 2, 4, 7, 8], [1, 3, 4, 2, 7], style: :pre).render | ||
|
||
# Another single plot with title | ||
UnicodePlot.stairs([2, 3, 5, 6, 9], [2, 5, 3, 4, 2], title: "My Staircase Plot").render | ||
|
||
# Two plots at a time. | ||
# Using an explicit limit because data for the 2nd plot is outside the bounds from the 1st plot | ||
plot = UnicodePlot.stairs([1, 2, 4, 7, 8], [1, 3, 4, 2, 7], title: "Two Staircases", xlim: [1,10] ) | ||
UnicodePlot.stairs!(plot, [0, 3, 5, 6, 9], [2, 5, 3, 4, 0]) | ||
plot.render | ||
|
||
plot = UnicodePlot.stairs([1, 2, 4, 7, 8], [1, 3, 4, 2, 7], title: "Two Staircases", xlim: [1,10] , canvas: :block) | ||
UnicodePlot.stairs!(plot, [0, 3, 5, 6, 9], [2, 5, 3, 4, 0]) | ||
plot.render | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#!/bin/env ruby | ||
require_relative "../lib/unicode_plot" | ||
|
||
ys = [261, 272, 277, 283, 289, 294, 298, 305, 309, 314, 319, 320, 322, 323, 324] | ||
#ys = [283, 289, 294, 298, 305] | ||
xs = ys.size.times.to_a | ||
|
||
UnicodePlot.lineplot( xs, ys, height: 26, ylim: [0, 700]).render | ||
UnicodePlot.lineplot( xs, ys, height: 26, ylim: [0, 700], canvas: :block).render |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
#!/bin/env ruby | ||
require_relative "../lib/unicode_plot" | ||
|
||
# example of using the 256 color pallette | ||
cmax = 255 | ||
# dummy | ||
|
||
plt = UnicodePlot.lineplot([0,0],[0,0], title: "Bar", color: 0, xlim: [0,31], ylim: [0,31], width: 33, height: 33) | ||
(0..cmax).each do |colornum| | ||
x1 = (colornum / 32).floor * 4 | ||
x2 = x1 + 3 | ||
y = colornum % 32 | ||
UnicodePlot.lineplot!(plt, [x1, x2],[y, y], color: colornum) | ||
end | ||
plt.render | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,30 @@ | ||
require 'stringio' | ||
|
||
require 'unicode_plot/version' | ||
require_relative './unicode_plot/version' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. converted to relative requires because it makes development easier for me, but can revert if you prefer normal require. |
||
|
||
require 'unicode_plot/utils' | ||
require 'unicode_plot/styled_printer' | ||
require 'unicode_plot/value_transformer' | ||
require 'unicode_plot/renderer' | ||
require_relative './unicode_plot/utils' | ||
require_relative './unicode_plot/styled_printer' | ||
require_relative './unicode_plot/value_transformer' | ||
require_relative './unicode_plot/renderer' | ||
|
||
require 'unicode_plot/canvas' | ||
require 'unicode_plot/braille_canvas' | ||
require 'unicode_plot/density_canvas' | ||
require 'unicode_plot/lookup_canvas' | ||
require 'unicode_plot/ascii_canvas' | ||
require 'unicode_plot/dot_canvas' | ||
require_relative './unicode_plot/canvas' | ||
require_relative './unicode_plot/braille_canvas' | ||
require_relative './unicode_plot/density_canvas' | ||
require_relative './unicode_plot/lookup_canvas' | ||
require_relative './unicode_plot/ascii_canvas' | ||
require_relative './unicode_plot/dot_canvas' | ||
require_relative './unicode_plot/block_canvas' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. new block canvas |
||
|
||
require 'unicode_plot/plot' | ||
require 'unicode_plot/grid_plot' | ||
require_relative './unicode_plot/plot' | ||
require_relative './unicode_plot/grid_plot' | ||
|
||
require_relative './unicode_plot/barplot' | ||
require_relative './unicode_plot/boxplot' | ||
require_relative './unicode_plot/densityplot' | ||
require_relative './unicode_plot/lineplot' | ||
require_relative './unicode_plot/histogram' | ||
require_relative './unicode_plot/scatterplot' | ||
|
||
# new! | ||
require_relative './unicode_plot/stairs' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. new stair plot |
||
|
||
require 'unicode_plot/barplot' | ||
require 'unicode_plot/boxplot' | ||
require 'unicode_plot/densityplot' | ||
require 'unicode_plot/lineplot' | ||
require 'unicode_plot/histogram' | ||
require 'unicode_plot/scatterplot' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# coding: utf-8 | ||
|
||
=begin | ||
The `BlockCanvas` is also Unicode-based. | ||
It has half the resolution of the `BrailleCanvas`. | ||
In contrast to BrailleCanvas, the pixels don't | ||
have visible spacing between them. | ||
This canvas effectively turns every character | ||
into 4 pixels that can individually be manipulated | ||
using binary operations. | ||
=end | ||
|
||
module UnicodePlot | ||
class BlockCanvas < LookupCanvas | ||
X_PIXEL_PER_CHAR = 2 | ||
Y_PIXEL_PER_CHAR = 2 | ||
|
||
def initialize(width, height, fill_char=0, **kw) | ||
super(width, height, | ||
X_PIXEL_PER_CHAR, | ||
Y_PIXEL_PER_CHAR, | ||
fill_char, | ||
**kw) | ||
end | ||
|
||
BLOCK_SIGNS = [ [0b1000, 0b0010].freeze, | ||
[0b0100, 0b0001].freeze | ||
].freeze | ||
|
||
BLOCK_DECODE = [' ', '▗', '▖', '▄', | ||
'▝', '▐', '▞', '▟', | ||
'▘', '▚', '▌', '▙', | ||
'▀', '▜', '▛', '█' ].freeze | ||
|
||
def lookup_encode(x,y) ; BLOCK_SIGNS[x][y] ; end | ||
def lookup_decode(x) ; BLOCK_DECODE[x] ; end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,17 +36,21 @@ def pixel!(pixel_x, pixel_y, color) | |
pixel_x -= 1 unless pixel_x < pixel_width | ||
pixel_y -= 1 unless pixel_y < pixel_height | ||
tx = pixel_x.fdiv(pixel_width) * width | ||
char_x = tx.floor + 1 | ||
char_x_off = pixel_x % X_PIXEL_PER_CHAR + 1 | ||
char_x += 1 if char_x < tx.round + 1 && char_x_off == 1 | ||
|
||
char_y = (pixel_y.fdiv(pixel_height) * height).floor + 1 | ||
char_y_off = pixel_y % Y_PIXEL_PER_CHAR + 1 | ||
char_x = tx.floor | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This code is both a fix for interpolation issue #32 but also removes several of the +1 / -1 manipulations needed which were there because the original UnicodePlots.jl (Julia) uses 1-based array indexing. |
||
char_x_off = pixel_x % X_PIXEL_PER_CHAR | ||
char_x += 1 if char_x < tx.round && char_x_off == 0 | ||
|
||
index = index_at(char_x - 1, char_y - 1) | ||
char_y_off = pixel_y % Y_PIXEL_PER_CHAR | ||
char_y = (pixel_y - char_y_off) / Y_PIXEL_PER_CHAR | ||
|
||
index = index_at(char_x, char_y) | ||
if index | ||
@grid[index] = (@grid[index].ord | BRAILLE_SIGNS[char_x_off - 1][char_y_off - 1]).chr(Encoding::UTF_8) | ||
@colors[index] |= COLOR_ENCODE[color] | ||
@grid[index] = (@grid[index].ord | BRAILLE_SIGNS[char_x_off][char_y_off]).chr(Encoding::UTF_8) | ||
# If we can fetch color from color-encode then or with the existing color. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Color handling done using fetch where the numeric color is used if the symbol lookup is unsuccessful. |
||
# this works for cases where color is 0..7 and we implement a 'mixer' | ||
# if color is beyond 7, then use it directly. | ||
@colors[index] |= COLOR_ENCODE.fetch(color, color) | ||
end | ||
color | ||
end | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
# coding: utf-8 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oops, did not mean to check this file in yet, heatmap support is not finished. |
||
require 'paint' | ||
|
||
# The `HeatmapCanvas` is also Unicode-based. | ||
# It has a half the resolution of the `BlockCanvas`. | ||
# This canvas effectively turns every character | ||
# into two pixels (top and bottom). | ||
module UnicodePlot | ||
class HeatmapCanvas < LookupCanvas | ||
# grid::Array{UInt8,2} | ||
# colors::Array{UInt8,2} | ||
# pixel_width::Int | ||
# pixel_height::Int | ||
# origin_x::Float64 | ||
# origin_y::Float64 | ||
# width::Float64 | ||
# height::Float64 | ||
X_PIXEL_PER_CHAR = 1 | ||
Y_PIXEL_PER_CHAR = 2 | ||
|
||
HALF_BLOCK = '▄' | ||
HEATMAP_ENCODE = [[0, 0], [1, 1]].freeze | ||
HEATMAP_DECODE = [HALF_BLOCK, HALF_BLOCK].freeze | ||
|
||
# @inline nrows(c::HeatmapCanvas) = div(size(grid(c), 2) + 1, 2) | ||
def initialize(width, height, **kw) | ||
super(width, height, | ||
width * X_PIXEL_PER_CHAR, | ||
height * Y_PIXEL_PER_CHAR, | ||
"\u{2800}", | ||
x_pixel_per_char: X_PIXEL_PER_CHAR, | ||
y_pixel_per_char: Y_PIXEL_PER_CHAR, | ||
**kw) | ||
end | ||
|
||
def print_row(out, row_index) | ||
unless 0 <= row_index && row_index < height | ||
raise ArgumentError, "row_index out of bounds" | ||
end | ||
y = 2 * row_index | ||
# extend the plot upwards by half a row | ||
y -= 1 if height.odd? | ||
|
||
is_color = out.isatty | ||
(0 ... width).each do |x| | ||
if is_color | ||
fgcol = color_at(x,y) | ||
if (y - 1) > 0 | ||
bgcol = color_at(x, y - 1) | ||
out.print Paint[BorderMaps::BORDER_SOLID[:l], :light_black] | ||
out.print Paint[HALF_BLOCK, fgcol, bgcol] | ||
# for odd numbers of rows, only print the foreground for the top row | ||
else | ||
out.print Paint[HALF_BLOCK, fgcol] | ||
end | ||
else | ||
out.print HALF_BLOCK | ||
end | ||
end | ||
if is_color | ||
out.print Paint[:reset] | ||
end | ||
end | ||
|
||
def print_color_barrow(out, row_index, colormap, border, lim, plot_padding, zlabel) | ||
b = BorderMaps::BORDER_MAP[border] | ||
min_z, max_z = lim[0..1] | ||
if row_index == 1 | ||
# print top border and maximum z value | ||
out.print Paint[ b[:tl], :light_black] | ||
out.print Paint[ b[:t], :light_black] | ||
out.print Paint[ b[:t], :light_black] | ||
out.print Paint[ b[:tr], :light_black] | ||
max_z_str = max_z.is_a?(Integer) ? max_z : float_round_log10(max_z) | ||
out.print plot_padding | ||
out.print Paint[io, max_z_str, :light_black] | ||
elsif row_index == height | ||
# print bottom border and minimum z value | ||
out.print Paint[ b[:bl], :light_black] | ||
out.print Paint[ b[:b], :light_black] | ||
out.print Paint[ b[:b], :light_black] | ||
out.print Paint[ b[:br], :light_black] | ||
min_z_str = min_z.is_a?(Integer) ? min_z : float_round_log10(min_z) | ||
out.print plot_padding | ||
out.print Paint[min_z_str, :light_black] | ||
else | ||
# print gradient | ||
out.print Paint[ b[:l], :light_black] | ||
# if min and max are the same, single color | ||
if min_z == max_z | ||
bgcol = colormap(1, 1, 1) | ||
fgcol = bgcol | ||
# otherwise, blend from min to max | ||
else | ||
n = 2*(nrows(c) - 2) | ||
r = row_index - 2 | ||
bgcol = colormap(n - (2*r), 1, n) | ||
fgcol = colormap(n - (2*r + 1), 1, n) | ||
end | ||
out.print Paint[HALF_BLOCK, fgcol, bgcol] | ||
out.print HALF_BLOCK | ||
out.print Paint[:reset] | ||
out.print Paint[ b[:r], :light_black] | ||
|
||
# print z label | ||
if row_index == div(nrows(c), 2) + 1 | ||
out.print(plot_padding) | ||
out.print(zlabel) | ||
end | ||
end | ||
end | ||
end | ||
end | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,17 +19,17 @@ def pixel!(pixel_x, pixel_y, color) | |
pixel_y -= 1 unless pixel_y < pixel_height | ||
|
||
tx = pixel_x.fdiv(pixel_width) * width | ||
char_x = tx.floor + 1 | ||
char_x_off = pixel_x % x_pixel_per_char + 1 | ||
char_x += 1 if char_x < tx.round + 1 && char_x_off == 1 | ||
char_x = tx.floor | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. simlar to canvas.rb, we have
|
||
char_x_off = pixel_x % x_pixel_per_char | ||
char_x += 1 if char_x < tx.round && char_x_off == 0 | ||
|
||
char_y = (pixel_y.fdiv(pixel_height) * height).floor + 1 | ||
char_y_off = pixel_y % y_pixel_per_char + 1 | ||
char_y_off = pixel_y % y_pixel_per_char | ||
char_y = (pixel_y - char_y_off) / y_pixel_per_char | ||
|
||
index = index_at(char_x - 1, char_y - 1) | ||
index = index_at(char_x, char_y) | ||
if index | ||
@grid[index] |= lookup_encode(char_x_off - 1, char_y_off - 1) | ||
@colors[index] |= COLOR_ENCODE[color] | ||
@grid[index] |= lookup_encode(char_x_off, char_y_off) | ||
@colors[index] |= COLOR_ENCODE.fetch(color, color) | ||
end | ||
end | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New example for lineplot with different canvases including :block