An algorithm to generate fake but realistic graph data that trends

Discussion in 'Ruby' started by librarising, Nov 21, 2013.

  1. librarising

    librarising Guest

    I needed to create some sample data for a project that resembled realistic usage, so I wrote a quick algorithm that follows a sinusoidal(periodic - upand down) pattern but still has a bit of randomness to it. As well, the algorithm has the ability trend upwards, downwards, or none.

    If anyone cares to, I'd love some feedback on the algorithm: ways to optimize, ways to make a bit more jittery/random.

    The output of the below code can be pasted into Google charts playground for visualization:

    https://code.google.com/apis/ajax/playground/?type=visualization#line_chart

    Also, the code with better syntax highlighting can be viewed here: http://pastie.org/8494591

    # In order to generate a semi-realistic looking graph behavior
    # we use a sine function to generate periodic behavior(ups and downs). In order to avoid
    # a graph that is too regular, we introduce randomness at two levels:
    # The delta between steps across the x-axis is random, but within a range(deltavariance)
    # The wavelength of the sine function is varied by randomly incrementing the index we pass
    # to the sine function(sine_index)

    # CONFIGURATION VARIABLES
    yvalue = 1 # start value
    range = 100 # y-range
    deltavariance = 10 # allowable variance between changes
    sine_index, wavelength = 0, 0.33 #index into our sine function that determines whether we change direction or not
    i, maxi = 0, 100 # our counter and its maximum
    data = {sine_index => yvalue} # seed our data structure with its first value
    trend = :positive # :negative, :none # do we want the graph to trend upwards, downwards or neither
    periodmin, periodmax = 0, 0 # vars to enforce trending
    direction = 1 # start in a positive direction, -1 for negative

    # DO NOT EDIT BELOW THIS LINE
    while(i < maxi)

    olddirection = direction
    direction = Math.sin(sine_index).to_f
    direction = direction < 0 ? direction.floor : direction.ceil

    delta = rand(deltavariance)
    yvalue += delta * direction

    if trend == :positive
    yvalue = periodmin if yvalue < periodmin
    periodmin = yvalue if olddirection < direction
    elsif trend == :negative
    yvalue = periodmax if yvalue > periodmax
    periodmax = yvalue if olddirection > direction

    end

    data[sine_index] = yvalue
    sine_index += Math.sin(rand) # Math.sin(rand) will give random numbers from -1..1
    i += 1
    end

    code = <<-CODE
    function drawVisualization() {
    // Create and populate the data table.
    var data = google.visualization.arrayToDataTable([
    ['x', 'Cats'],
    DATASTR
    ]);

    // Create and draw the visualization.
    new google.visualization.LineChart(document.getElementById('visualization')).
    draw(data, {curveType: "function",
    width: 500, height: 400,
    vAxis: {maxValue: 10}}
    );
    }
    CODE

    datastr = data.collect{|k,v| "[#{k},#{v}]"}.join(",")
    code = code.gsub('DATASTR', datastr)
    puts code
     
    librarising, Nov 21, 2013
    #1
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.