Creating a 2 line graph on left axis and a bar graph on right axis Octave - octave

I'm having difficulty creating a 2 y axis graph in Octave. Currently I can make the 2 line graph. However, I haven't been able to find a function that will help me with my problem. I have tried using the plotyy function but I am not sure if you can use this function with two left side axis line graphs and one right side graph. Here is code I have written so far in my attempt.
labels = ["Data 1"; "Data 2"; "Data 3"; "Data 4"; "Data 5"]
y1 = [137, 15, 2, 3, 37]
y2 = [43, 1, 67, 97, 41]
x = [1, 2, 3, 4, 5]
y3 = [0, .2, .3, .104, .09]
z1 = plot(x, y1, y2)
plot(x, y1, y2)
hold on
plot(x, y2)
xlabel("Version")
yyaxis left
ylabel("Y axis")
set(gca,'XTickLabel',labels)
yyaxis right
z = bar(x,y3)
z
yyaxis right
ylabel("Data")

While plotyy is the command to plot two normal plots using distinct left and right yaxes, I don't think you can do what you were trying to do with it. (i.e. mix two plots with a bar chart). However, what plotyy does is literally a simple case of overlaying two axes at the same position and making one 'see-through'. So you can use the same approach in general.
Here's your example above re-worked to achieve this (plus some extra bling):
x = [1, 2, 3, 4, 5]; labels = ["Data 1"; "Data 2"; "Data 3"; "Data 4"; "Data 5"];
y1 = [137, 15, 2, 3, 37]; y2 = [43, 1, 67, 97, 41]; y3 = [0, .2, .3, .104, .09];
ax_left = axes('position', [0.15, 0.12, 0.7, 0.82]); % manually positioned
plot (x, y1, 'r-', 'linewidth', 3); hold on
plot (x, y2, 'g:', 'linewidth', 3); hold off
set (ax_left, ...
'fontsize', 16, 'fontweight', 'bold', 'labelfontsizemultiplier', 1.2, ...
'color', 'none', ... % makes 'background' see-through
'box', 'off', ... % prevents left axis ticks in the right axis
'xlim', [0, 6], 'ylim', [0, 150], 'xtick', x, 'xticklabel', labels);
xlabel('Version'); ylabel('Left Y-Axis');
ax_right = axes('position', [0.15, 0.12, 0.7, 0.82]); % same position as above
bar (x, y3, 0.5, 'facecolor', [0, 0.5, 1]); % nice narrow light blue columns
set (ax_right, ...
'fontsize', 16, 'fontweight', 'bold', 'labelfontsizemultiplier', 1.2, ...
'yaxislocation', 'right', ...
'ycolor', [0, 0.5, 1], ... % same nice light blue color as bar chart
'box', 'off', 'xlim', [0, 6], 'ylim', [0, 0.35], 'xtick', []);
ylabel('Data');
% ensure axes are stacked in the order you want them to appear (bottom to top)
axes(ax_right);
axes(ax_left);

Related

Transparency in plotted surfaces

I'm using Octave 7.2.0-1 on linux.
When plotting surfaces which overlap (both with facealpha<1) Octave only shows the axes as a "see-through", not the surface which is "behind":
[ xs, ys, zs ] = sphere( 20 );
surf( xs, ys, zs, 'facealpha', 0.5, 'edgealpha', 0.5, 'facecolor', 'r' );
hold on
surf( xs+1, ys+1, zs , 'facealpha',0.5, 'edgealpha', 0.5, 'facecolor', 'g');
Is this a bug?

plotting multiple graphs on the same figure in Octave

I'm trying to plot multiple graphs on a single figure in Octave. Here is my code: these graphs represents the decrease of the cost function on each iteration of gradient decent:
% Init Theta and Run Gradient Descent
theta = zeros(3, 1);
[theta, J_history] = gradientDescentMulti(X, y, zeros(3, 1), alpha, num_iters);
[theta1,J1]=gradientDescentMulti(X, y, zeros(3, 1), 0.05, num_iters);
[theta3,J3]=gradientDescentMulti(X, y, zeros(3, 1), 0.03, num_iters);
% Plot the convergence graph
figure;
plot(1:numel(J_history), J_history, 'g', 'LineWidth', 2);
hold on;
plot(1:50, J2, 'r');
plot(1:50, J3, 'b');
xlabel('Number of iterations');
ylabel('Cost J');
However, when I run the codes, I got only one graph on the figure without even the labels, The best I was able to d was to put two graph on the same figure:
Is there something wrong with my codes?

Automatic Level Generation from Array

So, I am trying to make the stages for the level in my game automatically generated.
I made an array (note, the amount of "tiles" on the screen is 16x16):
var background:Array=new Array(
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
)
And as you can probably tell, each 1 or 0 corresponds to if the tile is one thing or another (there or not there in this scenario).
I am pretty bad at the next part that I did.
I decided to make this using http://www.flashgametuts.com/tutorials/as3/how-to-create-a-platform-game-in-as3-part-2/'s method (kinda).
var bkgblocks:Sprite=new Sprite();
var bkgblocksw:Number=stage.stageWidth/16
var bkgblocksh:Number=stage.stageHeight/16
//the blocks are 45 pixels wide and tall
var row:int=0;
for(var i:int=0; i<background.length;i++){
if((i+1)/16==int((i+1)/16)){
//if i is divisible by 16
row++
}
if(background[i]==1){
bkgblocks.graphics.beginFill(0x000000)
bkgblocks.graphics.drawRect(I have no idea what to do here ,row*stage.stageHeight/16,bkgblocksw,bkgblocksh);
bkgblocks.graphics.endFill()
addChild(bkgblocks)
}
}
As you can see, I have no idea how or where to place the blocks!
I have where to place their y coordinate, but the x is way too confusing.
I thought I could do something like this
i*(45/(row+1))
but that messed up completely. This is more of a math question, I'm sorry, but if anybody can (or has) figure this out, I would appreciate it.
I usually prefer packing a grid into an array of arrays to make it more human-readable e. g.
var grid:Array = [
[0, 0, 1, 0, 0],
[0, 1, 0, 1, 0],
[1, 0, 0, 0, 1],
[0, 1, 0, 1, 0],
[0, 0, 1, 0, 0]
];
Where the first (outer) array contains rows of cells, each row represented by an array
So you can access a cell by calling grid[y][x] and find the 'real' coordinates by multiplying x and y by const CELL_SIZE
It seems you are tangled with 1D-2D coordinate transformation.
Let's width of your screen (2D coordinates) is Wdt. So element with (x,y) coordinates will be at y * Wdt + x index of 1D array.
A[y * Wdt + x] corresponds to Screen[y][x]
And back tranform:
x = index %% Wdt //integer modulus
y = index \ Wdt //integer division
Screen[index \ Wdt] [index %% Wdt] = A[index]

Python: about [:] and its behavior in a function

def call(nums):
nums[:] = [x for x in nums if x != 4]
numbers = [4, 5]
print(numbers)
call(numbers)
print(numbers)
The output for the above code is:
[4, 5]
[5]
But if you remove the "[:]", the output becomes the following:
[4, 5]
[4, 5]
I know that [:] makes a copy of the full list, but why the function argument is modified in one case and not in the other?
As you suspected the issue is hiding in the slicer in line:
nums[:] = [x for x in nums if x != 4]
Python is "pass by value" which means that you're not passing the pointer numbers into the function, but a copy of it. So re-assigning a value to a copy of the reference will not change the original reference.
But, when you use the slicer, you're accessing the object behind the reference and changing it directly which is why you see the side effect after you exit the function - when using the "slice".
As Python passes objects by reference, when you execute your function with nums[:] = ... line, you change actual list that you've passed from outside, numbers. When you change line to nums = ..., you just overwrite local variable called nums, without affecting numbers array.
In Python, you can not only slice collections to read them, but you can assign to slices, replacing sliced content.
For example:
>>> a = [0, 1, 2, 3, 4, 5]
>>> a[1:4]
[1, 2, 3]
If you assign to slice, it will replace part of original array:
>>> a[1:4] = ['z']
>>> a
[0, 'z', 4, 5]
But when assigning to slices, array remains the same:
>>> a = [0, 1, 2, 3, 4, 5]
>>> b = a
>>> a[:] = ['z']
>>> a
['z']
>>> b
['z']
As you can see, a and b change at the same time, because when assigning to slice, you don't change object's identity, you only change its contents.
>>> a = [0, 1, 2, 3, 4, 5]
>>> b = a
>>> a = ['z']
>>> a
['z']
>>> b
[0, 1, 2, 3, 4, 5]
This is not the case when you just assign to variable, dropping older array out of scope.
def call(nums):
nums = [x for x in nums if x != 4]
Would only change the value of the name nums function parameter which would accomplish nothing.
def call(nums):
nums[:] = [x for x in nums if x != 4]
Changes the actual value of the list passed in as an argument.

Octave Boxplot Axis

I would like to create multiple boxplot in one graph by using octave. I try to set the x-axis that associates each data.
Here is my code
x = [1, 2, 4];
y1 = [6, 2, 3];
y2 = [1, 7, 3];
y3 = [1, 9, 2];
boxplot ({y1,y2,y3});
set(gca,'XTickLabel',x);
refresh;
but the result looks strange. The axis appears three times.
I want to see x-axis 1 for data y1, 2 for data y2 and 4 for data y3
According to Octave Documentation, I could not find how we could set the axis. I found Matlab could do that :(
Please help me to solve this problem.
Before set(gca,'XTickLabel',x); you have to add set(gca, 'xtick', [1:3]);. This makes sure that each (and only each) box in the plot is assigned an x-axis number before these numbers are overridden by manual labels.
Here's the full code:
x = [1, 2, 4];
y1 = [6, 2, 3];
y2 = [1, 7, 3];
y3 = [1, 9, 2];
boxplot ({y1,y2,y3});
set(gca, 'xtick', [1:3]);
set(gca,'XTickLabel',x);
refresh;