I have a collection of points in tiling 2D space (I believe its called toroidal geometry/space), and I want to find their mean:
The basic approach would be to just take their mean 'locally' where you would just treat the space as non-tiling. Looking at the example, I'd guess that that would be somewhere in about the middle. However, looking at the extended example, I'd say that the middle is probably one of the worst representations of the data.
I'd say the objective is to find a location where the total variation from the mean is at a minimum
One potential method would be to try all combinations of points in each of the 9 neighbours, and then see which one has the lowest variance, but that becomes extremely inefficient very quickly:
Big O = O(8^n)
I believe it could probably be made more efficient by doing something like treating the x and y independently, but that would only reduce it to O(5^n), so still not manageable.
Perhaps hill-climbing might work? Where I have a random point, and then calculate the lowest possible variance for each point, then make some random adjustments and test again reverting if the variance decreases, I then repeat this until I reach a seemingly optimal value.
Is there a better method? Or maybe some sort of heuristic 'good enough' method?
as of my understanding, you are trying to find the center of mass.
to do so (for each tile) you have to find the sum of each positions multiplied by its weight (assume it is 1 because they are just identical points positioned differently) then divide this by the sum of the weights (which is the number of points in this example as weight = 1). The formula
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS_HTML-full"></script> <script type="text/x-mathjax-config"> MathJax.Hub.Config({"HTML-CSS": { preferredFont: "TeX", availableFonts:["STIX","TeX"], linebreaks: { automatic:true }, EqnChunk:(MathJax.Hub.Browser.isMobile ? 10 : 50) }, tex2jax: { inlineMath: [ ["$", "$"], ["\\\\(","\\\\)"] ], displayMath: [ ["$$","$$"], ["\\[", "\\]"] ], processEscapes: true, ignoreClass: "tex2jax_ignore|dno" }, TeX: { noUndefined: { attributes: { mathcolor: "red", mathbackground: "#FFEEEE", mathsize: "90%" } }, Macros: { href: "{}" } }, messageStyle: "none" }); </script>
$$G\left( x,y \right) =\frac{\sum_{i=1}^n{m_i\cdot p_i\left( x_i\,\,,y_i \right)}}{\sum_{i=1}^n{m_i}}$$
in our example:
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS_HTML-full"></script> <script type="text/x-mathjax-config"> MathJax.Hub.Config({"HTML-CSS": { preferredFont: "TeX", availableFonts:["STIX","TeX"], linebreaks: { automatic:true }, EqnChunk:(MathJax.Hub.Browser.isMobile ? 10 : 50) }, tex2jax: { inlineMath: [ ["$", "$"], ["\\\\(","\\\\)"] ], displayMath: [ ["$$","$$"], ["\\[", "\\]"] ], processEscapes: true, ignoreClass: "tex2jax_ignore|dno" }, TeX: { noUndefined: { attributes: { mathcolor: "red", mathbackground: "#FFEEEE", mathsize: "90%" } }, Macros: { href: "{}" } }, messageStyle: "none" }); </script>
$$G\left( x,y \right) =\frac{\sum_{i=1}^n{p_i\left( x_i\,\,,y_i \right)}}{n}$$
here is a python implementation :
#assuming l is a list of 2D tuples as follow: [(x1,y1),(x2,y2),...]
def findCenter(l):
cx,cy = 0,0
for p in l:
cx += p[0]
cy += p[1]
return (cx / len(l), cy / len(l))
# the result is a tuple of non-integer, if you need
# an integer result use: return (cx // len(l),cy // len(l))
# remove the outer parenthesis to take result as 2 separate values
as for multiple tiles you can calculate the center for each tile then the center for the centers, or treat all points from multiple tiles as points from one big tile and calculate the center of all of them.
Related
I want to optimize size of vertex buffer. Currently my layout for VBO is:
x y | r g b a
It's consumed by shader like this:
struct VertexInput {
#location(0) position: vec2<f32>,
#location(1) color: vec4<f32>,
}
And I'm storing mesh in buffer like this: |Mesh1|Mesh2|LargeMesh3|, because my meshes are dynamic. It's being rendered in one drawCall (seems like it's called Draw Call Batching).
I want to reduce sent data to GPU by setting different color for every mesh, not every vertex. And every mesh is different. How can I achive it?
I'm drawing strokes:
I achieved it with #trojanfoe's help with multiple drawCalls.
I created second buffer with stepMode: 'instance' and passed colors to it.
Layout:
vertex: {
module: this.shaderModule,
entryPoint: 'vertex',
buffers: [
{
arrayStride: 2 * VBO_ARRAY.BYTES_PER_ELEMENT,
stepMode: 'vertex',
attributes: [
{
format: 'float32x2',
offset: 0,
shaderLocation: 0,
},
],
},
{
arrayStride: 4 * VBO_ARRAY.BYTES_PER_ELEMENT,
stepMode: 'instance',
attributes: [
{
format: 'float32x4',
offset: 0,
shaderLocation: 1,
},
],
},
],
}
Added to renderPass:
pass.setVertexBuffer(0, this.vbo.buffer)
pass.setVertexBuffer(1, this.clrbo.buffer)
And used in shader as is:
struct VertexInput {
#location(0) position: vec2<f32>,
#location(1) color: vec4<f32>,
}
struct VSOutput {
#builtin(position) position: vec4<f32>,
#location(0) color: vec4<f32>,
}
#vertex
fn vertex(vert: VertexInput) -> VSOutput {
var out: VSOutput;
out.color = vert.color;
....
return out;
}
#fragment
fn fragment(in: VSOutput) -> #location(0) vec4<f32> {
return in.color;
}
However, I'm not sure it will work with multiple meshes merged in one buffer and rendered with one draw call.
suppose if i am doing hyper parameter tuning to one of my model, lets say, i am using AdaBoostClassifier() and want to pass different base_estimator, so i pass SVC & DecisionTreeClassifier as estimator
_parameters=[
{
'mdl':[AdaBoostClassifier(random_state=23)],
'mdl__learning_rate':np.linspace(0,1,20),
'mdl__base_estimator':[SVC(),DecisionTreeClassifier()]
}
]
now, i want to pass different values to ccp_alpha of DecisionTreeClassifier, something like this
'mdl__base_estimator':[LinearRegression(),DecisionTreeClassifier(ccp_alpha=[0.1,0.2,0.3,0.4])]
how can i do that, i tried passing it like this, but it is not working, here is my entire code
pipeline=Pipeline(
[
('scal',StandardScaler()),
('mdl','passthrough')
]
)
_parameters=[
{
'mdl':[DecisionTreeClassifier(random_state=42)] ,
'mdl__max_depth':np.linspace(2,30,2),
'mdl__min_samples_split':np.linspace(1,10,1),
'mdl__max_features':np.linspace(1,100,1),
'mdl__ccp_alpha':np.linspace(0,1,10)
}
,{
'mdl':[AdaBoostClassifier(random_state=23)],
'mdl__learning_rate':np.linspace(0,1,20),
'mdl__base_estimator':[SVC(),DecisionTreeClassifier(ccp_alpha=[0.3,0.4,0.5,0.7])]
}
]
grid_search=GridSearchCV(_pipeline,_parameters,cv=3,n_jobs=-1,scoring='f1')
grid_search.fit(x,y
)
This kind of splitting is why param_grid can be a list of dicts, as in your outer split; but it cannot easily handle the nested disjunction you have. Two approaches come to mind.
More disjoint grids:
_parameters=[
{
'mdl': [DecisionTreeClassifier(random_state=42)],
'mdl__max_depth': np.linspace(2,30,2),
'mdl__min_samples_split': np.linspace(1,10,1),
'mdl__max_features': np.linspace(1,100,1),
'mdl__ccp_alpha': np.linspace(0,1,10),
},
{
'mdl': [AdaBoostClassifier(random_state=23)],
'mdl__learning_rate': np.linspace(0,1,20),
'mdl__base_estimator': [SVC()],
},
{
'mdl': [AdaBoostClassifier(random_state=23)],
'mdl__learning_rate': np.linspace(0,1,20),
'mdl__base_estimator': [DecisionTreeClassifier()],
'mdl__base_estimator__ccp_alpha': [0.3,0.4,0.5,0.7],
},
]
Or list comprehension:
_parameters=[
{
'mdl': [DecisionTreeClassifier(random_state=42)],
'mdl__max_depth': np.linspace(2,30,2),
'mdl__min_samples_split': np.linspace(1,10,1),
'mdl__max_features': np.linspace(1,100,1),
'mdl__ccp_alpha': np.linspace(0,1,10),
},
{
'mdl': [AdaBoostClassifier(random_state=23)],
'mdl__learning_rate': np.linspace(0,1,20),
'mdl__base_estimator': [SVC()] + [DecisionTreeClassifier(ccp_alpha=a) for a in [0.3,0.4,0.5,0.7]],
},
]
When exporting scatter plot / bubble chart data as CSV or XLS, it is missing key information, see for example: http://jsfiddle.net/11fum86u/
This is the data (extract):
series: [{
data: [
{ x: 95, y: 95, z: 13.8, name: 'BE', country: 'Belgium' },
And the axis titles are in the tooltip (but perhaps needs to be defined elsewhere):
tooltip: {
pointFormat: '<tr><th colspan="2"><h3>{point.country}</h3></th></tr>' +
'<tr><th>Fat intake:</th><td>{point.x}g</td></tr>' +
'<tr><th>Sugar intake:</th><td>{point.y}g</td></tr>' +
'<tr><th>Obesity (adults):</th><td>{point.z}%</td></tr>',
What is missing in the default export is (i) labels for y and z axis, and (ii) the names of the bubbles (in this example, country codes/names)
I was wondering how I might be able to add this information to the export.
Actually there's no z axis in bubble charts. It's quite confusing, because all points have z property. This property serves to compute the bubble size so no additional axis is needed, because everything is in 2d. zAxis is used in 3d charts.
Please refer to this live working example: http://jsfiddle.net/kkulig/udtr0emL/
You can handle first row labels via columnHeaderFormatter (http://api.highcharts.com/highcharts/exporting.csv.columnHeaderFormatter):
exporting: {
csv: {
columnHeaderFormatter: function(item, key, keyLength) {
if (item.axisTitle) {
return item.axisTitle.textStr; // x axis label
} else if (key === 'y') {
return item.yAxis.axisTitle.textStr; // y axis label
} else if (key === 'z') {
return 'Obesity (adults)'; // z axis label
}
}
}
}
To add another column (countries) added following pieces of code in these three core functions:
1. Highcharts.Chart.prototype.getDataRows
// add original point reference
rows[key].point = point;
2. Highcharts.Chart.prototype.getCSV
// Add point name and header
csv += itemDelimiter;
var point = row['point'];
if (point) {
csv += point.name
} else {
csv += "Country"
}
3. Highcharts.Chart.prototype.getTable (for XLS)
var point = row['point'],
val;
if (point) {
val = point.name;
} else {
val = "Country";
}
html += '<' + tag + ' class="text">' +
(val === undefined ? '' : val) + '</' + tag + '>';
All functions are available in export-data.src.js in this directory: https://github.com/highcharts/highcharts/tree/b4b4221b19a3a50d9ed613b6f50b12f0afcc7d06/js/modules
I want to make stacked bar chart where each portion has a width that encodes one value (say "Change" in the data below) and a height that encodes another value ("Share")
In some ways this is like a histogram with different bin sizes. There are a few "histogram" questions but none seem to address this. Plot Histograms in Highcharts
So given data like this:
Category Share Price Change
Apples 14.35 0.1314192423
Horseradish 46.168 0.1761474117
Figs 2.871 0.018874249
Tomatoes 13.954 0.0106121298
Mangoes 7.264 0.1217297011
Raisins 5.738 0.0206787136
Eggplant 6.31 0.0110160732
Other produce 3.344 0.0945377722
I can make a stacked bar that captures the "share" column in widths:
And another that captures the "change" column in heights:
And I can use an image editor to combine those into this histogram-like beast:
Which really captures that horseradish is a huge deal. So my question is, can I do that within Highcharts?
You can realise that by using snippet.
(function (H) {
var seriesTypes = H.seriesTypes,
each = H.each,
extendClass = H.extendClass,
defaultPlotOptions = H.getOptions().plotOptions,
merge = H.merge;
defaultPlotOptions.marimekko = merge(defaultPlotOptions.column, {
pointPadding: 0,
groupPadding: 0
});
seriesTypes.marimekko = extendClass(seriesTypes.column, {
type: 'marimekko',
pointArrayMap: ['y', 'z'],
parallelArrays: ['x', 'y', 'z'],
processData: function () {
var series = this;
this.totalZ = 0;
this.relZ = [];
seriesTypes.column.prototype.processData.call(this);
each(this.zData, function (z, i) {
series.relZ[i] = series.totalZ;
series.totalZ += z;
});
},
translate: function () {
var series = this,
totalZ = series.totalZ,
xAxis = series.xAxis;
seriesTypes.column.prototype.translate.call(this);
// Distort the points to reflect z dimension
each(this.points, function (point, i) {
var shapeArgs = point.shapeArgs,
relZ = series.relZ[i];
shapeArgs.x *= (relZ / totalZ) / (shapeArgs.x / xAxis.len);
shapeArgs.width *= (point.z / totalZ) / (series.pointRange / series.xAxis.max);
});
}
});
}(Highcharts));
Example: http://jsfiddle.net/highcharts/75oucp3b/
I have a flask app in which I am using Highcharts to plot data, and if the user enters a lot of inputs for which he needs a graph, I plot multiple plot lines on the graph with different colors. But after 8-10 plot lines the color repeat and hence its not useful coz its not distinguishable.
<script type="text/javascript">
$('document').ready(function(){
window.seriesOptions = [];
window.yAxisOptions = [],
window.seriesCounter = 0,
window.colors = Highcharts.getOptions().colors;
generate_graph( {{ coordinates| safe }} , {{ graph_name | safe }} );
});
</script>
/*
Generate graph function takes two input parameters i.e. Coordinates - which is an array of [x, y] points AND graph_name which is an array of the (service_name,server_name) pair and generates
seriesOptions and calls createChart function.
*/
function generate_graph(coordinates, graph_name){
$.each(graph_name, function(i, name) {
window.seriesOptions[i]= {
name : graph_name[i],
data : coordinates[i],
type : 'line'
};
seriesCounter++;
if (seriesCounter == graph_name.length) {
createChart();
}
});
$('#add-to-dashboard-button').show();
}
/*
createChart function generates the actual graphs and sets the different properties of the graph.
*/
function createChart(){
$('#chart').highcharts('StockChart', {
chart: {
zoomType: 'x'
},
rangeSelector: {
selected: 4
},
xAxis: {
type: 'datetime',
labels: {
formatter: function() {
return Highcharts.dateFormat('%a %d %b', this.value);
}
}
},
title : {
text : 'Graph'
},
legend: {
enabled: true,
layout: 'vertical',
labelFormat: '<span style="color:{color}">{name}</span> - <b> x : ({point.x:.2f}) , </b> y : ({point.y:.2f}) <br/>',
maxHeight: 100
},
series : seriesOptions
});
}
</script>
How to make sure that every time a plot is generated its in a different unique color and hence distinguishable.
Also The tooltip doesn`t appear even though the data for x axis is sorted?
If you don't specify any colours when creating a chart or adding a series, highcharts will pick one from it's default colours. There are a limited number of defaults.
However, you can tell highcharts about a new set of default colours, so you could give it more to chose from, up to the maxumum you want to support. This code sets 9 defaults, but you can add as many as you want, you just need to come up with some unique colours:
Highcharts.setOptions({
colors:[
'#058DC7', '#50B432', '#ED561B', '#DDDF00', '#24CBE5', '#64E572', '#FF9655', '#FFF263', '#6AF9C4']
});
Make this the first thing you call.