Fill a region on a graph with no outline? - octave

I'd like to fill a region on a graph plotted with octave, without any outline:
The fill command accepts a color argument that it respects for the filled area, but it doesn't seem to accept the 'LineColor' property to change the color of the line it draws around the filled area...
e.g.
fill([1 2 3 3 2 1], [1 0.5 1 -1 -1 -1], [0.9,0.9,0.9]); # line is black
fill([1 2 3 3 2 1], [1 0.5 1 -1 -1 -1], [0.9,0.9,0.9], 'LineColor', 'r') # hangs
I'm using octave-3.4.0 on OS X.

The patch command should do the job
verts = [0.2 0.4; ...
0.2 0.8; ...
0.8 0.8; ...
0.8 0.4];
faces = [1 2 3 4];
p = patch('Faces',faces,'Vertices',verts,'FaceColor','b','EdgeColor','none');
Of course you could also place it in one line ... ;-)

Related

ValueError; Quantreg with Intercept

I am working with the following dataframe, called test:
y intercept x
0 -1.6168468132687293 1 NA
1 1.5500031232431757 1 NA
2 1.5952617833602785 1 1.5500031232431757
3 1.1390724309357498 1 1.5952617833602785
4 0.9950311340335872 1 1.1390724309357498
5 0.7095780139613861 1 0.9950311340335872
6 0.5962529862944801 1 0.7095780139613861
7 0.6555353674581792 1 0.5962529862944801
8 1.0008751093886736 1 0.6555353674581792
9 1.2648319050758074 1 1.0008751093886736
I am trying to apply the smf.quantreg() function to the dataframe as follows:
import statsmodels.formula.api as smf
Output_pre = smf.quantreg('y ~ intercept + x', test , missing = 'drop')
Output = Output_pre.fit(q=0.25)
The equivalent standard statsmodels.ols() function works just fine. However, applying the smf.quantreg() function yields the following error:
ValueError: operands could not be broadcast together with shapes (3,) (2,)
Why is that so and how do I solve this issue?
I found out myself. By default, the function gives an intercept. Hence the input matrix is not full rank when including a second intercept (two columns are perfectly colinear).

Grouped bar plot with multiple labels in x-axis

I am trying to replicate something close to the following graph in gnuplot as I need to use it on a latex paper. I have tried a lot but I cannot make the two-line labels at the bottom. Could you please guide me? Also, how is it possible to have the % character as part of a label in the x-axis? Latex complains about it.
The data are in the following format (example). Each different color corresponds to different method. Blue is method 1 (m1), orange is method 2 (m2), and brown is method 3 (m3)
#% system1-m1 system1-m2 system1-m3 system2-m1 ...
0.5% 16 8 15 6
1% 15 17 16 8
2% 12 10 20 15
Thanks
Edit
My code so far is as follows:
set rmargin 0
set key outside tmargin center top horizontal width 3
set border
set grid
set boxwidth 0.8
set style fill solid 1.00
set xtics nomirror rotate by 0
set format y '%1.f'
set yrange [0 to 22]
set ylabel 'Gain (\%)'
set ytics 0, 5
set style data histograms
set label 1 at -0.3, -4 '|---------System 1------------|'
set label 2 at 2.7, -4 '|---------System 2------------|'
plot "./data/metrics.dat" using 2:xtic(1) title 'Method 1' ,\
"" using 3 title 'Method 2', \
"" using 4 title 'Method 3',
And I have modified the .dat file as
0.5 16 8 15
1.0 15 17 16
2.0 12 10 20
0.5 13 6 4
1.0 11 13 13
2.0 14 12 14
because I cannot make it print the % character. The output graph is
As you can see it is not scalable. I have to put labels by hand (trial and error) and also the labels below the x-axis do not contain the % character.
We've been close: set format x '%.1f\%%'. The following works for me with cairolatex terminal (check help cairolatex).
Code:
### percent sign for tic label in TeX
reset session
set term cairolatex
set output 'SO70029830.tex'
set title 'Some \TeX\ or \LaTeX\ title: $a^2 + b^2 = c^2$'
set format x '%.1f\%%'
plot x
set output
### end of code
Result: (screenshot)
Addition:
Sorry, I forgot the second part of your question: the labels.
Furthermore, in your graph you are using xtic(1) as tic labels, i.e. text format, so the command set format x '%.1f\%%' from my answer above will not help here. One possible solution would be to create and use your special TeX label like this:
myTic(col) = sprintf('%.1f\%%',column(col))
plot $Data using 2:xtic(myTic(1))
For the labels, I would use arrows and labels. Each histogram is placed at integer numbers starting from 0. So, the arrows have to go from x-values -0.5 to 2.5 and from 2.5 to 5.5. The labels are placed at x-value 1 and 4. There is certainly room for improvements.
Code:
### tic labels with % for TeX and lines/labels
reset session
set term cairolatex
set output 'SO70029830.tex'
$Data <<EOD
0.5 16 8 15
1.0 15 17 16
2.0 12 10 20
0.5 13 6 4
1.0 11 13 13
2.0 14 12 14
EOD
set rmargin 0
set key outside center top horizontal width 3
set border
set grid
set boxwidth 0.8
set style fill solid 1.00
set xtics nomirror rotate by 0
set format y '%1.f'
set yrange [0 to 22]
set ylabel 'Gain (\%)'
set ytics 0, 5
set style data histograms
set bmargin 4
set arrow 1 from -0.5, screen 0.05 to 2.5, screen 0.05 heads size 0.05,90
set label 1 at 1, screen 0.05 'System 1' center offset 0,-0.7
set arrow 2 from 2.5, screen 0.05 to 5.5, screen 0.05 heads size 0.05,90
set label 2 at 4, screen 0.05 'System 2' center offset 0,-0.7
myTic(col) = sprintf('%.1f\%%',column(col))
plot $Data using 2:xtic(myTic(1)) title 'Method 1' ,\
"" using 3 title 'Method 2', \
"" using 4 title 'Method 3',
set output
### enf of code
Result: (screenshot from LaTeX document)
As an alternative to the answer of #theozh there is already a build-in function called newhistogram that directly allows to place labels below the x-axis.
While working on an an answer that involves newhistogram I discovered a bug with horizontal key layout, which is now fixed thanks to Ethan. So, with the newest development version of gnuplot at hand I am able to offer a solution that allows for more finetuning like the ability to change the inter-group spacing.
set terminal cairolatex standalone colour header '\usepackage{siunitx}' size 25cm, 7cm
# generate some random data in your format
N = 7
set print $MYDATA
do for [i=1:N] {
print sprintf('0.5 %f %f %f', rand(0)*20, rand(0)*20, rand(0)*20)
print sprintf('1.0 %f %f %f', rand(0)*20, rand(0)*20, rand(0)*20)
print sprintf("2.0 %f %f %f", rand(0)*20, rand(0)*20, rand(0)*20)
}
unset print
# define the look
set style data histograms
set style fill solid 1.00
set boxwidth 0.8
set key horizontal outside t c width 1
set xr [-1:27]
set xtics nomirror
set ytics out 5 nomirror
set grid y # I don't think vertical grid lines are needed here
set ylabel 'Gain/\%'
set rmargin 0.01
set bmargin 3
As for the tic marks, I adapted #theozh's answer a bit – since you are using LaTeX already, you might as well parse the numbers through siunitx, which will ensure correct spacing between numbers and the unit:
myTic(col) = sprintf('\SI{%.1f}{\%}',column(col))
The vertical separation marks like in the screenshot you provided can be created iteratively:
do for [i=1:N+1] {set arrow i from first -1+(i-1)*4, graph 0 to first -1+(i-1)*4, screen 0 lw 2 nohead}
Now for the actual plot command:
plot newhistogram "System 1" offset 0,-0.5 lt 1, for [i=1:3] $MYDATA using (column(i+1)):xtic(myTic(1)) every ::0::2 title sprintf('Method %.0f',i), \
newhistogram "System 2" offset 0,-0.5 lt 1 at 4, for [i=1:3] $MYDATA using (column(i+1)):xtic(myTic(1)) every ::3::5 not, \
newhistogram "System 3" offset 0,-0.5 lt 1 at 8, for [i=1:3] $MYDATA using (column(i+1)):xtic(myTic(1)) every ::6::8 not, \
newhistogram "System 4" offset 0,-0.5 lt 1 at 12, for [i=1:3] $MYDATA using (column(i+1)):xtic(myTic(1)) every ::9::11 not, \
newhistogram "System 5" offset 0,-0.5 lt 1 at 16, for [i=1:3] $MYDATA using (column(i+1)):xtic(myTic(1)) every ::12::14 not, \
newhistogram "System 6" offset 0,-0.5 lt 1 at 20, for [i=1:3] $MYDATA using (column(i+1)):xtic(myTic(1)) every ::15::17 not, \
newhistogram "System 7" offset 0,-0.5 lt 1 at 24, for [i=1:3] $MYDATA using (column(i+1)):xtic(myTic(1)) every ::18::20 not
That looks very nasty, what's going on here?
newhistogram creates a new group of histogram boxes, its first argument is a string that is put below the x axis. It is also told to reset the linetype counter to 1.
Then the three columns of the data are plotted iteratively, but not all lines at once, but only the first three lines, with corresponding key entries.
Then another newhistogram is created and it is told to start at the x value 4 (which would be the default anyway). Now the next three lines are plotted, and so.
Now, every time newhistogram is called an empty line is added to key, hence making trouble with the key placement. Therefore the new keyword introduced by Ethan is
set style histogram nokeyseparators
which will disable this behaviour.
As you see, the spaces between the groups are larger than inside. You might want to change the numbers in newhistogram at ... and adjust the calculation of vertical line positions accordingly.
The plot command is of course highly repetitive, and it would be nice to make it an iterative call. Unfortunately, iterations that span multiple objects are not possible within a plot call. However, it is possible to iteratively put the plot command string together (excessively using string concatenation .) and then plot it.
A = 'newhistogram "System '
B = '" offset 0,-0.5 lt 1'
C = 'for [i=1:3] $MYDATA using (column(i+1)):xtic(myTic(1)) every ::'
myplotstring = A.'1'.B.', '.C."0::2 title sprintf('Method %.0f',i),"
do for [i=2:N] {myplotstring = myplotstring.A.i.B.'at '.(4*(i-1)).', '.C.(3*i-3).'::'.(3*i-1).' not, '}
plot #myplotstring

rjson::fromJSON returns only the first item

I have a sqlite database file with several columns. One of the columns has a JSON dictionary (with two keys) embedded in it. I want to extract the JSON column to a data frame in R that shows each key in a separate column.
I tried rjson::fromJSON, but it reads only the first item. Is there a trick that I'm missing?
Here's an example that mimics my problem:
> eg <- as.vector(c("{\"3x\": 20, \"6y\": 23}", "{\"3x\": 60, \"6y\": 50}"))
> fromJSON(eg)
$3x
[1] 20
$6y
[1] 23
The desired output is something like:
# a data frame for both variables
3x 6y
1 20 23
2 60 50
or,
# a data frame for each variable
3x
1 20
2 60
6y
1 23
2 50
What you are looking for is actually a combination of lapply and some application of rbind or related.
I'll extend your data a little, just to have more than 2 elements.
eg <- c("{\"3x\": 20, \"6y\": 23}",
"{\"3x\": 60, \"6y\": 50}",
"{\"3x\": 99, \"6y\": 72}")
library(jsonlite)
Using base R, we can do
do.call(rbind.data.frame, lapply(eg, fromJSON))
# X3x X6y
# 1 20 23
# 2 60 50
# 3 99 72
You might be tempted to do something like Reduce(rbind, lapply(eg, fromJSON)), but the notable difference is that in the Reduce model, rbind is called "N-1" times, where "N" is the number of elements in eg; this results in a LOT of copying of data, and though it might work alright with small "N", it scales horribly. With the do.call option, rbind is called exactly once.
Notice that the column labels have been R-ized, since data.frame column names should not start with numbers. (It is possible, but generally discouraged.)
If you're confident that all substrings will have exactly the same elements, then you may be good here. If there's a chance that there will be a difference at some point, perhaps
eg <- c(eg, "{\"3x\": 99}")
then you'll notice that the base R solution no longer works by default.
do.call(rbind.data.frame, lapply(eg, fromJSON))
# Error in (function (..., deparse.level = 1, make.row.names = TRUE, stringsAsFactors = default.stringsAsFactors()) :
# numbers of columns of arguments do not match
There may be techniques to try to normalize the elements such that you can be assured of matches. However, if you're not averse to a tidyverse package:
library(dplyr)
eg2 <- bind_rows(lapply(eg, fromJSON))
eg2
# # A tibble: 4 × 2
# `3x` `6y`
# <int> <int>
# 1 20 23
# 2 60 50
# 3 99 72
# 4 99 NA
though you cannot call it as directly with the dollar-method, you can still use [[ or backticks.
eg2$3x
# Error: unexpected numeric constant in "eg2$3"
eg2[["3x"]]
# [1] 20 60 99 99
eg2$`3x`
# [1] 20 60 99 99

Converting OBJ data to CSS3D

I found a ton of formulae and what not, but 3D isn't my forte so I'm at a loss of what specifically to use. My goal is to convert the data in an 3D .obj file (vertices, normals, faces) to CSS3D (width, height, rotateX,Y,Z and/or similar transforms).
For example 2 simple planes
g plane1
# simple along along Z axis
v 0.0 0.0 0.0
v 0.0 0.0 1.0
v 0.0 1.0 1.0
v 0.0 1.0 0.0
g plane2
# plane rotated 90 degrees along Y-axis
v 0.0 0.0 0.0
v 0.0 1.0 0.0
v 1.0 1.0 0.0
v 1.0 0.0 0.0
f 1 2 3 4
f 5 6 7 8
Could this data be converted to:
#plane1 {
width: X;
height: Y;
transform: rotateX(Xdeg) rotateY(Ydeg) rotateZ(Zdeg) translateZ(Zpx)
}
#plane2 {
width: X;
height: Y;
transform: rotateX(Xdeg) rotateY(Ydeg) rotateZ(Zdeg) translateZ(Zpx)
}
/* Or something equivalent such as transform: matrix3d() */
The core question is how to get the X/Y/Z-rotation of a 4 point plane from it's matrix of x,y,z coordinates?
UPDATE #1 - 11/12/12
So based on the answers provided, I've come across the unoptimized function from http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToEuler/index.htm below:
/*
-v 0.940148 -0.847439 -1.052535
-v 0.940148 -0.847439 0.947465
-v -1.059852 -0.847439 0.947465
-v -1.059852 -0.847439 -1.052535
-v 0.940148 1.152561 -1.052534
-v 0.940147 1.152561 0.947466
-v -1.059852 1.152561 0.947465
v -1.059852 1.152561 -1.052535
f 1 2 3 4
f 5 8 7 6
f 1 5 6 2
f 2 6 7 3
f 3 7 8 4
f 5 1 4 8
*/
var f = {
'm00' : 0.940148,
'm01' : -0.847439,
'm02' : -1.052535,
'm10' : 0.940148,
'm11' : -0.847439,
'm12' : 0.947465,
'm20' : -1.059852,
'm21' : -0.847439,
'm22' : 0.947465
}
// Assuming the angles are in radians.
if (f.m10 > 0.998) { // singularity at north pole
heading = Math.atan2(f.m02, f.m22);
attitude = Math.PI/2;
bank = 0;
} else if (f.m10 < -0.998) { // singularity at south pole
heading = Math.atan2(f.m02,f.m22);
attitude = -Math.PI/2;
bank = 0;
} else {
heading = Math.atan2(-f.m20, f.m00);
bank = Math.atan2(-f.m12, f.m11);
attitude = Math.asin(f.m10);
}
I'm getting results, but I'm not sure if my calculations are correct and I'm also getting mixed responses on what corresponds to which axis. Is it heading = y, bank = x, and attitude = z? I'm also converting each to degrees if that matters.
Read this http://www.songho.ca/opengl/gl_matrix.html It explains pretty much everything and there is implementation.
Beside that the CSS 3D solution will have lower performance(order of magnitude) mainly because each pice of represented surface is DOM element, it's also highly limited - you can find numerous materials about this issue(Google IO records for example)
If you need declarative 3D framework you might want to look at x3dom
To draw a 3D box you just need to include x3dom js script and embed this declaration in your page:
<body>
<h1>Hello X3DOM World</h1>
<x3d width="400" height="300">
<scene>
<shape>
<box></box>
</shape>
</scene>
</x3d>
</body>
It will parse <x3d> tags on your page and generate proper WebGL or Flash implementation with the good performance.
x3d has way to import assets from Blender, Maya and 3ds Max.
Here is some good reading: x3domIntroTutorial.pdf
IE 11 will support WebGL and IE10 will autoupdate to IE 11 so only non-supporting desktop browser(disabled by default) will be Safari. Apple will be forced to enable it by default. With full desktop support it won't take too long to get full mobile because it's highly competitive market. And we have highly accessible WebGL framework like three.js. So there is no sense in doing it with CSS 3D
UPDATE: iOS 8 Safari will enable WebGL support by default: http://caniuse.com/webgl

problem with igraph degree( ) function

I have an N x 2 table of integers called games[ , ]. The table of nodes/edges is converted to a graph:
net <- graph.data.frame(as.data.frame(games), directed=FALSE)
deg.net <- degree(net, mode='total', loops=FALSE)
(I realize that not all options are necessary.)
The problem I am having is that the degree distribution seems to be for in-degree only. For example, the games file has the lines:
103 86
24 103
103 2
92 103
87 103
103 101
103 44
and yet igraph indicates that the degree for node 103 is '3' when it should be '7'.
Any insight in what I am missing would be appreciated.
One thing that you should keep in mind is that most igraph functions refer to the vertices by their IDs, which are simply integers from 0 to N-1 where N is the number of vertices in the graph. If you have an N x 2 table of integers (containing zero-based vertex indices) and you want igraph to use the integers as the vertex IDs, you can simply use the graph constructor after having flattened the matrix into a vector by rows. When you use graph.data.frame, the first two columns of the data frame are assumed to contain symbolic vertex names (i.e. there is no requirement that they must be integers); these will be assigned to the name vertex attribute, and igraph will simply make up the IDs from 0 to N-1.
So, let's assume that you have an N x 2 matrix, one row per each edge:
> edges <- matrix(c(103, 86, 24, 103, 103, 2, 92, 103, 87, 103, 103, 101, 103, 44), ncol=2, byrow=T)
First we create a graph out of it after flattening the matrix by rows:
> g <- graph(as.vector(t(edges)))
This gives you a directed graph with 7 edges and the out/in-degrees of vertex 103 will be as expected:
> ecount(g)
7
> degree(g, 103, mode="out")
4
> degree(g, 103, mode="in")
3
> degree(g, 103, mode="all")
7
If you use graph.data.frame with the above matrix, igraph will construct a graph where the numbers in the matrix are stored in the name vertex attribute:
> g <- graph.data.frame(as.data.frame(edges))
> V(g)$name
[1] "103" "24" "92" "87" "86" "2" "101" "44"
This shows you that the vertex with the name 103 actually became vertex zero in the graph:
> degree(g, 0, mode="out")
4
> degree(g, 0, mode="in")
3
> degree(g, 0, mode="all")
7
As far as I know, degree is also able to work with the vertex names directly if there is a vertex attribute called name in the graph, so you can also do this:
> degree(g, "103", mode="in")
3
Hope this helps.
You created a undirected graph. There is no in and out degree in such a graph. From the igraph documentation link you can get the general idea. Your deg.net will return a vector with all the degrees(per node) on your graph, similar to this:
[1] 2 1 1 1 1 1 1
If you want to get the degree of a specific node(in our example it's 103) you have to specify the node(appearence_order-1). In your example you are looking for the (1st_node-1), it's node 0. So you must type:
degree(net,0, mode='total', loops=FALSE)
Which will return the degree of node 0, "7".