{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Updating data in plots\n",
"#### Data used in the following examples"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"x = (1..600).map { |i| i/100.0 }\n",
"y = x.map { |xx| Math.sin(xx ** 2.3) * Math.exp(-xx) }\n",
"nil"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Updating data stored in file\n",
"First lets generate a file"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"1..300"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"File.open('tons_of_data', 'w') { |f| (1..300).each { |i| f.puts \"#{x[i]} #{y[i]}\" } }"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"and plot it"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
"# \"Tons of data\", :with => \"lines\"]>], @cmd=\"plot \">"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"require 'gnuplotrb'\n",
"include GnuplotRB\n",
"\n",
"graph = Plot.new(['tons_of_data', title: 'Tons of data', with: 'lines'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we can just append file and replot out graph"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
"# \"Tons of data\", :with => \"lines\"]>], @cmd=\"plot \">"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"File.open('tons_of_data', 'a') { |f| (301..600).each { |i| f.puts \"#{x[i]} #{y[i]}\" } }\n",
"\n",
"graph"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Updating data given as points array\n",
"##### 1. Data stored in memory and piped to gnuplot in here-doc"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
"#, @options=Hamster::Hash[:with => \"lines\", :title => \"Before update\"]>], @cmd=\"plot \">"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x0 = x[0..200]\n",
"y0 = y[0..200]\n",
"updatable_plot = Plot.new([[x0,y0], with: 'lines', title: 'Before update'])"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
"#, @options=Hamster::Hash[:title => \"After update\"]>], @cmd=\"plot \">"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x1 = x[201..600]\n",
"y1 = y[201..600]\n",
"updatable_plot.update_dataset(data: [x1,y1], title: 'After update')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This way is expensive because data is piped to gnuplot each time you want to replot it, but updating data does not affect original Plot:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
"#, @options=Hamster::Hash[:with => \"lines\", :title => \"Before update\"]>], @cmd=\"plot \">"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"updatable_plot"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### 2. Data stored in temporary file and its name is piped to gnuplot\n",
"Dataset boolean option 'file' corresponds to using temporary file for storage data being plotted."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
"#, @options=Hamster::Hash[:with => \"lines\", :title => \"Before update\"]>], @cmd=\"plot \">"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x0 = x[0..400]\n",
"y0 = y[0..400]\n",
"updatable_file_plot = Plot.new([[x0,y0], with: 'lines', title: 'Before update', file: true])"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
"#, @options=Hamster::Hash[:with => \"lines\", :title => \"After update\"]>], @cmd=\"plot \">"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x1 = x[401..600]\n",
"y1 = y[401..600]\n",
"updatable_file_plot.update_dataset(data: [x1,y1], title: 'After update')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Be careful**: updating data stored in temp file **affects** original Plot:"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
"#, @options=Hamster::Hash[:with => \"lines\", :title => \"Before update\"]>], @cmd=\"plot \">"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"updatable_file_plot"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Destructive update methods\n",
"Almost every update method in GnuplotRB's classes has its destructive twin ending with '!' or '='."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 1. Updating options\n",
"\n",
"Examples relate to Plot, but Splot, Multiplot, Animation and so on options may be changed the same way too."
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
"# \"Old title\"], @datasets=Hamster::Vector[#], @cmd=\"plot \">"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"plot = Plot.new('sin(x)', title: 'Old title')"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
"# [\"New title\"], :yrange => [0..1], :xrange => [-1..1]], @datasets=Hamster::Vector[# [\"Dataset title\"]]>], @cmd=\"plot \">"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"plot.title = 'New title'\n",
"# plot is container of datasets, so plot[0] is Dataset object\n",
"plot[0].title = 'Dataset title'\n",
"plot.xrange!(-1..1)\n",
"plot.yrange = 0..1\n",
"plot"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can update several options at once using ```#options!``` method or use something like ```Plot#update_dataset!```.Please see [GnuplotRB](https://rubygems.org/gems/gnuplotrb) doc for more methods."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 2. Updating containers\n",
"\n",
"Plot and Splot are containers for Dataset, Multiplot and Animation - for Plots and Splots. So sometimes you may want to modify them. GnuplotRB offers methods such as ```#add_dataset```, ```#remove_dataset```, ```#replace_dataset```, ```#update_dataset```, their destructive twins (with '!' at the end) and methods like them for other classes."
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
"# 0..2], @datasets=Hamster::Vector[#, #, #], @cmd=\"plot \">"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"plot = Plot.new('sin(x)', 'cos(x)', 'exp(x)', xrange: 0..2)"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
"# 0..2], @datasets=Hamster::Vector[#, #, #], @cmd=\"plot \">"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"plot.replace_dataset(1, 'x*x') # DOES NOT modify original plot"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
"# 0..2], @datasets=Hamster::Vector[#, #, #], @cmd=\"plot \">"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"plot.replace_dataset!(2, 'x*x') # MODIFYES original plot"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
"# 0..2], @datasets=Hamster::Vector[# \"1-st dataset\"]>, #, #], @cmd=\"plot \">"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"plot.update_dataset!(0, title: '1-st dataset')"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
"# 0..2], @datasets=Hamster::Vector[# \"1-st dataset\"]>, #], @cmd=\"plot \">"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"plot.remove_dataset!(2)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Ruby 2.1.2",
"language": "ruby",
"name": "ruby"
},
"language_info": {
"file_extension": "rb",
"mimetype": "application/x-ruby",
"name": "ruby",
"version": "2.1.2"
}
},
"nbformat": 4,
"nbformat_minor": 0
}