D3.js x-axis error once data reaches 100 value - d3.js

I modified the code from a D3.js example for a multi line series chart so the x values are numbers instead of dates. The graph works fine as long as the x values are under 100, but once they reach 100 the x-axis reverses order and changes scale (ie: 1 2 3 ... 99) to (100 99.9 99.8 99.7)
Here's the script: http://bitpusher.in/graph.html
and data.tsv: http://bitpusher.in/data.tsv
Any suggestions on how to fix, or where I went wrong?
Thank you.

Related

sorting by x-y-coordinaten

I want to plot results in gnuplot that all lie on a circle. For each value I have the corresponding x-y coordinates and a corresponding ID number (so 4 columns in total), but in an unsorted order. The rows are to be sorted in such a way that the direction of rotation is from -x => -y => +x => +y and end again at -x. So the center of the circle is at 0. How to implement this with "sort" (or alternatively with "awk"?) command (using Linux)?
At Theozh's suggestion, I will formulate my problem a little more precisely.
Imagine the dial of a clock with small dots as minute symbols. The position of the minute points can be determined by polar coordinates or by Cartesian coordinates. My file contains the Cartesian coordinates with an associated value (result). The file contains 60 lines with x - y coordinates and the result in the third column. Depending on the quadrant, the signs of x and y change, of course. Unfortunately, the lines are NOT sorted in such a way that they correspond to the sense of circulation. So the line for the point "minute 30" is not in line 30, but e.g. in line 17. The task is to sort the lines by the coordinates so that they appear in the order from 1 to 60. In the diagram, the x-axis would then simply be defined from 1 to 60 and the y-axis would then contain the results (from the 3rd column)
My unsorted file (coordinates for a unit circle, result values simplified for a better overview)
And this is what I want to have (8 rows (every 45°) sorted counterclockwise):
The angle can be calculated directly from the x/y coordinates using the atan2() function.
You do not say exactly what it is that you want to plot. If it is simply the points themselves (one point per line in the file), then this can be done easily inside gnuplot. I show the output from gnuplot 5.5. In earlier versions, and depending on exactly what you want to plot, it might require additional commands to sort the data in a separate step and then plot the sorted data. If you clarify what exactly is supposed to go into the plot, I will modify the example accordingly.
Example using 100 points with random x and y coordinates:
set print $RANDOM
do for [i=1:100] { print rand(0)-0.5, rand(0)-0.5 }
unset print
set xrange [-1:1]
set yrange [-1:1]
set angle degrees
set cbrange [-180:180]; set cblabel "Angle"
set style data linespoints
plot $RANDOM using 1:2:(atan2($2,$1)):(atan2($2,$1)) smooth zsort lc palette
Updated answer
Revised to show a plot of the sample data as given
$DATA << EOD
X Y Result
-0.707 -0.707 222
-0.707 0.707 888
0.707 -0.707 444
-1 0 111
1 0 555
0.707 0.707 666
0 1 777
0 -1 333
EOD
set datafile columnheader # allow for the line of labels
unset key
# atan2() returns a number between -pi and pi; convert this to 0 -> 1
# You could make it run from 0->60 if you know in advance
# there will be 60 evenly spaced points
xcoord(a) = (a + pi) / (2 * pi)
plot $DATA using (xcoord(atan2($2,$1))):3:(atan2($2,$1)) smooth zsort with points
And actually, if you don't care what order the points are drawn in, only where they end up, the command is even simpler because there is no need to sort!
plot $DATA using (xcoord(atan2($2,$1))):3 with points

Seaborn Stripplot Axis Values with Correct Scaling

I'm trying to plot some data in seaborn where the x values are percentages*100 as floating point numbers (ie 90.909). When I make the plot:
fig, ax = plt.subplots(figsize=(10,10))
ax = sns.stripplot(df_12['% ident'], df_12['length'], jitter=True)
The decimals in the floating points make the X axis unreadable:
Initial Plot
I would like to set the x axis to show only whole number multiples of 5 (ie 80, 85, 90, 95, 100).
One method I have tried is the following:
fmt = '{:0.0f}'
xticklabels = []
count = 0
for item in ax.get_xticklabels():
count+= 1
item.set_text(fmt.format(float(item.get_text())));
xticklabels += [item];
ax.set_xticklabels(xticklabels);
This succeeds in changing the axis values to integers, but the axis looks busy. The numbers shown are also inconsistent between similar datasets.
Second Plot
I would like to reduce the total number of values shown on the axis. I have tried to use
ax.xaxis.set_major_locator(plt.MaxNLocator(5))
Or similarly
ax.xaxis.set_major_locator(plt.MaxNLocator(5))
ax.set_xticklabels([80, 85, 90, 95, 100])
Which give outputs similar to this:
Third Plot
If you compare this to the previous plot, you'll notice the x axis labels no longer relate to the points plotted. How do I set the values of the x axis while still keeping them related to the points plotted?
Other things I have tried:
ax.set_xlim(75, 100)
This and any variants result in a blank plot.
ax.set(xticklabels=[75,80,85,90,95,100])
Does the same thing where the axis labels don't match the data.
ax.set(xticks=range(75,101), xticklabels=[75,80,85,90,95,100])
Results in all the data points stuck on the left side of the plot with all the axis labels overlapping on a single tick on the right.
ax.xaxis.set_major_locator(ticker.MaxNLocator(integer=True))
This doesn't change the axis values to integers, and also appears to cause the axis to no longer correlate with the data.

Gnuplot how can I draw matrix every nth line

I have following data
...
10800 42.835282 2.0799322 9.6376456 14.69194 15.74205 16.591997 14.208506 17.036752 16.974312 30.759594 318.69734
10900 59.608134 2.0319971 10.413494 17.136174 18.597465 19.31398 16.78688 19.939459 20.034195 43.809158 470.3118
11000 71.147383 2.3502536 11.098845 19.525944 21.618026 22.255387 19.446565 22.871378 23.265609 60.717349 559.03537
11100 70.844437 2.5290753 11.759208 21.795673 24.63466 25.294785 22.079689 25.788459 26.690083 80.472264 513.94945
...
Data have total 600 lines, 12 columns. I want to plot line-wise data for every 50th line, from 3rd column to 12th column. I used plot data matrix (because [i=3:12] was not working as I intended)
data = "data.dat"
plot data matrix every 1::2 w l
This give me the plot what I want (draw 3rd ~ 12th columns of each lines), but draws the curves for all 600 lines. How can I draw every 50th lines in this matrix every 1::2 command, so only 12 curves are shown?
Thanks
ps) I just solved by myself by using sed command like
plot '<sed -n "0~50p" data.dat' matrix every 1::2 w l
To plot every 50th row, you must make use the block values for every:
plot "data.dat" matrix every :50:2 with lines
That plots every point starting from column 3 in every 50th row.

Generating random data for a scatter plot

I'm testing out different JavaScript graphing frameworks. I'm trying out line graphs and scatter plots with generated data. While it's all going quite okay. I've run into a trouble while trying to generate data for a scatter plot.
So it would be quite easy to do something like this in PHP, or in any other language:
for ($i=0; $i < $x; $i++) {
$data[] = array(
'x' => mt_rand(0, 10000),
'y' => mt_rand(0, 10000)
);
}
The result is distributed pretty much equally around the whole chart. So here I am trying to think of a way to come up with better random data, which would eventually look more like a scatter plot, rather than a equally distributed dots on a page. And I can't come up with anything.
I would like to end up with something more like this random scatter plot from the Web:
So it is more intense in some part of the plot and pretty much nothing in the corners. But I wouldn't like to make it completely impossible for a dot to make it to the corners.
Any algorithmic ideas?
For something like the image you showed, where you have a line around which you want to scatter data, it's pretty easy. For example, imagine a line in which y = x * 0.75. Given that, you select an x value in the range 0..xMax (whatever your maximum X value is), and then generate a value for y with some variance. For example, if 90% of the time the Y value is within 10% of the expected value, then you'd generate a random value between 0.675x and 0.825x.
Say that 5% of the time, the Y value is within 50% of the expected value and 5% of the time the value is unconstrained. For each of those, you generate a Y value the same way: a random value that is equal to the expected Y value, plus or minus 50% (or, in the latter case, plus or minus some very large number).
You can adjust the probabilities and the variance as appropriate.
You can also adjust the distribution of X values. For example, it looks like most of your data points are between about .15 xMax and .6 xMax. So what you want is a higher percentage of X values in that range. Imagine, then that your X values are broken into three different ranges:
0 to .149 * xMax - 20%
.15 to .60 * xMax - 70%
> .60 xMax - 10%
Generate a random number between 0 and 100. Then:
if value < 20, generate an x value between 0 and .15 xmax
if value > 19 & < 60, generate an x value between .15 xMax and .60 xMax
otherwise, generate an x value > .60 xMax and < xMax
Define a function that becomes the center line of the distribution, for example c(x) = sqrt(x).
Define a function that specifies the maximal allowed deviation from the center line, for example d(x) = 0.1 (x - 5)².
For every x value generate one or a few y values y(x) = c(x) + 2 * (random() - 0.5) * d(x) where random() is a (pseudo) random number generator with values in [0;1].
For a more realistic look use a (pseudo) random number generator that has a more interesting distribution, for example a normal distributed with standard deviation d(x).

d3.js using d3.scale.sqrt()

What does the d3.scale.sqrt() scale do? As per the documentation it is similar to d3.scale.pow().exponent(.5), so the returned scale is equivalent to the sqrt function for numbers; for example:
sqrt(0.25) returns 0.5.
so when we apply a domain similar to this:
d3.scale.sqrt().domain([1, 100]).range([10, 39])
does it signify it takes the value between 1-100 and return the sqrt function which ranges between 10-39? Could anybody clarify and provide more details on how this scale works?
The way scales work in D3 is that they map input values (defined by .domain()) to output values (defined by .range()). So
d3.scale.sqrt().domain([1, 100]).range([10, 39])
maps values from 1 to 100 to the 10 to 39 range. That is, 1 corresponds to 10 and 100 to 39. This has nothing to do with the transformation the scale applies, which only affects the distribution of values within the range. For the sqrt function, the growth is sub-linear, which means that more of the input values will fall into the latter part of the output range.

Resources