Class: Rubyplot::Scatter

Inherits:
Artist
  • Object
show all
Defined in:
lib/rubyplot/scripting/scatter/scatter.rb,
lib/rubyplot/scripting/scatter/data.rb,
lib/rubyplot/scripting/scatter/init.rb,
lib/rubyplot/scripting/scatter/constant.rb

Overview

Here's how to set up an XY Scatter Chart

g = Rubyplot::Scatter.new(800) g.data(:apples, [1,2,3,4], [4,3,2,1]) g.data('oranges', [5,7,8], [4,1,7]) g.write('scatter.png')

Direct Known Subclasses

Bubble

Constant Summary

Constants inherited from Artist

Artist::DATA_COLOR_INDEX, Artist::DATA_LABEL_INDEX, Artist::DATA_VALUES_INDEX, Artist::DATA_VALUES_X_INDEX, Artist::DEFAULT_MARGIN, Artist::DEFAULT_TARGET_WIDTH, Artist::LABEL_MARGIN, Artist::LEGEND_MARGIN, Artist::THOUSAND_SEPARATOR

Instance Attribute Summary collapse

Attributes inherited from Artist

#base_image, #font, #font_color, #has_left_labels, #hide_legend, #hide_line_numbers, #labels, #legend_font_size, #legend_margin, #marker_color, #marker_count, #marker_shadow_color, #maximum_value, #minimum_value, #title, #title_margin, #x_axis_label, #y_axis_label

Instance Method Summary collapse

Methods inherited from Artist

#artist_draw, #calculate_caps_height, #calculate_width, #center, #clip_value_if_greater_than, #construct_colors_array, #draw_axis_labels, #draw_label, #draw_legend, #draw_title, #get_colors_array, #initialize_variables, #render_gradiated_background, #reset_themes, #scale, #scale_fontsize, #set_colors_array, #setup_graph_measurements, #significant, #sort_norm_data, #sum, #theme=, #write

Constructor Details

#initializeScatter

Rubyplot::Scatter takes the same parameters as the Rubyplot::Line graph

Example

g = Rubyplot::Scatter.new


8
9
10
11
# File 'lib/rubyplot/scripting/scatter/init.rb', line 8

def initialize(*)
  super
  @geometry = Rubyplot::ScatterGeometry.new
end

Instance Attribute Details

#circle_radiusObject

Attributes to allow customising the size of the points


27
28
29
# File 'lib/rubyplot/scripting/scatter/constant.rb', line 27

def circle_radius
  @circle_radius
end

#disable_significant_rounding_x_axisObject

Allow disabling the significant rounding when labeling the X axis This is useful when working with a small range of high values (for example, a date range of months, while seconds as units)


32
33
34
# File 'lib/rubyplot/scripting/scatter/constant.rb', line 32

def disable_significant_rounding_x_axis
  @disable_significant_rounding_x_axis
end

#enable_vertical_line_markersObject

Allow enabling vertical lines. When you have a lot of data, they can work great


35
36
37
# File 'lib/rubyplot/scripting/scatter/constant.rb', line 35

def enable_vertical_line_markers
  @enable_vertical_line_markers
end

#marker_x_countObject

The number of vertical lines shown for reference


11
12
13
# File 'lib/rubyplot/scripting/scatter/constant.rb', line 11

def marker_x_count
  @marker_x_count
end

#maximum_x_valueObject

Maximum X Value. The value will get overwritten by the max in the datasets.


4
5
6
# File 'lib/rubyplot/scripting/scatter/constant.rb', line 4

def maximum_x_value
  @maximum_x_value
end

#minimum_x_valueObject

Minimum X Value. The value will get overwritten by the min in the datasets.


8
9
10
# File 'lib/rubyplot/scripting/scatter/constant.rb', line 8

def minimum_x_value
  @minimum_x_value
end

#stroke_widthObject

Returns the value of attribute stroke_width


28
29
30
# File 'lib/rubyplot/scripting/scatter/constant.rb', line 28

def stroke_width
  @stroke_width
end

#use_vertical_x_labelsObject

Returns the value of attribute use_vertical_x_labels


39
40
41
# File 'lib/rubyplot/scripting/scatter/constant.rb', line 39

def use_vertical_x_labels
  @use_vertical_x_labels
end

#x_axis_label_formatObject

Returns the value of attribute x_axis_label_format


43
44
45
# File 'lib/rubyplot/scripting/scatter/constant.rb', line 43

def x_axis_label_format
  @x_axis_label_format
end

#x_label_marginObject

Allow using vertical labels in the X axis (and setting the label margin)


38
39
40
# File 'lib/rubyplot/scripting/scatter/constant.rb', line 38

def x_label_margin
  @x_label_margin
end

#y_axis_label_formatObject

Allow passing lambdas to format labels


42
43
44
# File 'lib/rubyplot/scripting/scatter/constant.rb', line 42

def y_axis_label_format
  @y_axis_label_format
end

Instance Method Details

#calculate_spreadObject

:nodoc:


54
55
56
57
58
# File 'lib/rubyplot/scripting/scatter/data.rb', line 54

def calculate_spread #:nodoc:
  super
  @x_spread = @geometry.maximum_x_value.to_f - @geometry.minimum_x_value.to_f
  @x_spread = @x_spread > 0 ? @x_spread : 1
end

#data(name, x_data_points = [], y_data_points = [], _color = nil) ⇒ Object

The first parameter is the name of the dataset. The next two are the x and y axis data points contain in their own array in that respective order. The final parameter is the color.

Can be called multiple times with different datasets for a multi-valued graph.

If the color argument is nil, the next color from the default theme will be used.

Parameters

name

String or Symbol containing the name of the dataset.

x_data_points

An Array of of x-axis data points.

y_data_points

An Array of of y-axis data points.

color

The hex string for the color of the dataset. Defaults to nil.

Exceptions

Data points contain nil values

This error will get raised if either the x or y axis data points array contains a nil value. The graph will not make an assumption as how to graph nil

x_data_points is empty

This error is raised when the array for the x-axis points are empty

y_data_points is empty

This error is raised when the array for the y-axis points are empty

x_data_points.length != y_data_points.length

Error means that the x and y axis point arrays do not match in length

Examples

g = Rubyplot::Scatter.new g.data(:apples, [1,2,3], [3,2,1]) g.data('oranges', [1,1,1], [2,3,4]) g.data('bitter_melon', [3,5,6], [6,7,8], '#000000')


36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/rubyplot/scripting/scatter/data.rb', line 36

def data(name, x_data_points = [], y_data_points = [], _color = nil)
  # Call the existing data routine for the y axis data
  super(name, y_data_points)

  # append the x data to the last entry that was just added in the @data member
  last_elem = @data.length - 1
  @data[last_elem] << x_data_points

  if @geometry.maximum_x_value.nil? && @geometry.minimum_x_value.nil?
    @geometry.maximum_x_value = @geometry.minimum_x_value = x_data_points.first
  end

  @geometry.maximum_x_value = x_data_points.max > @geometry.maximum_x_value ?
                      x_data_points.max : @geometry.maximum_x_value
  @geometry.minimum_x_value = x_data_points.min < @geometry.minimum_x_value ?
                      x_data_points.min : @geometry.minimum_x_value
end

#drawObject


9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/rubyplot/scripting/scatter/scatter.rb', line 9

def draw
  super
  return unless @geometry.has_data

  # Check to see if more than one datapoint was given. NaN can result otherwise.
  @x_increment = @geometry.column_count > 1 ? (@graph_width / (@geometry.column_count - 1).to_f) : @graph_width

  @geometry.norm_data.each_with_index do |data_row, row_num|
    data_row[DATA_VALUES_INDEX].each_with_index do |data_point, index|
      @d = @d.fill @plot_colors[row_num]
      x_value = data_row[DATA_VALUES_X_INDEX][index]
      next if data_point.nil? || x_value.nil?

      new_x = get_x_coord(x_value, @graph_width, @graph_left)
      new_y = @graph_top + (@graph_height - data_point * @graph_height)

      # Reset each time to avoid thin-line errors
      @d = @d.stroke_opacity 1.0
      @d = @d.stroke_width @geometry.stroke_width || clip_value_if_greater_than(@columns / (@geometry.norm_data.first[1].size * 4), 5.0)

      circle_radius = @geometry.circle_radius || clip_value_if_greater_than(@columns / (@geometry.norm_data.first[1].size * 2.5), 5.0)
      @d = @d.circle(new_x, new_y, new_x - circle_radius, new_y)
    end
  end

  @d.draw(@base_image)
end

#normalize(force = nil) ⇒ Object


60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/rubyplot/scripting/scatter/data.rb', line 60

def normalize(force = nil)
  if @geometry.norm_data.nil? || force
    @geometry.norm_data = []
    return unless @geometry.has_data

    @data.each do |data_row|
      norm_data_points = [data_row[DATA_LABEL_INDEX]]
      norm_data_points << data_row[DATA_VALUES_INDEX].map do |r|
        (r.to_f - @geometry.minimum_value.to_f) / @spread
      end

      norm_data_points << data_row[DATA_COLOR_INDEX]
      norm_data_points << data_row[DATA_VALUES_X_INDEX].map do |r|
        (r.to_f - @geometry.minimum_x_value.to_f) / @x_spread
      end
      @geometry.norm_data << norm_data_points
    end
  end
  # ~ @norm_y_baseline = (@geometry.baseline_y_value.to_f / @geometry.maximum_value.to_f) if @geometry.baseline_y_value
  # ~ @norm_x_baseline = (@geometry.baseline_x_value.to_f / @geometry.maximum_x_value.to_f) if @geometry.baseline_x_value
end

#setup_drawingObject


13
14
15
16
17
18
19
20
21
# File 'lib/rubyplot/scripting/scatter/init.rb', line 13

def setup_drawing
  @labels = {}

  super

  # Translate our values so that we can use the base methods for drawing
  # the standard chart stuff
  @geometry.column_count = @x_spread
end