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.
I want to fill a specific road with a specific color using mapbox-gl js or at least getting the geojson data of that specific road. Is there any specific and efficient way to get that done?
Found a way around it.
At first, I generated geojson data of a specific road (Beverly Glen Blvd, San Fernando, CA, USA) using the http://geojson.io provided by mapbox.
After that, I added three properties to the properties object of that geojson data (id, name, color) and using that property named color to fill the road which I utilized using the mapbox-gl js get expression like this.
line-color": ["string", ["get", "color"]],
Here's the codepen demo.
map.on("load", function() {
map.addLayer({
id: "1",
type: "line",
source: {
type: "geojson",
data: {
type: "FeatureCollection",
features: [
{
type: "Feature",
properties: {
id: "1",
name: "Beverly Glen Blvd",
color: "#000000"
},
geometry: {
type: "LineString",
coordinates: [
[-118.44586461782454, 34.15044515309062],
[-118.44606578350066, 34.14968601019978],
[-118.44618380069733, 34.14921542697057],
[-118.44627767801283, 34.14880699411822],
[-118.4463205933571, 34.14861165596896],
[-118.44635546207427, 34.14842297664594],
[-118.44640910625458, 34.148209879491944],
[-118.44645202159882, 34.148043396966365],
[-118.44650834798811, 34.14780144177757],
[-118.44652980566025, 34.147717090264415],
[-118.44678997993468, 34.1466293921546],
[-118.44680070877074, 34.146573896977564],
[-118.4468087553978, 34.14652950080971],
[-118.44683825969695, 34.14650064328809],
[-118.44687312841414, 34.14647844518782],
[-118.44692945480347, 34.146436268781265],
[-118.44693750143051, 34.14638299329021],
[-118.4469187259674, 34.146307519620414],
[-118.44689458608627, 34.146229826066346],
[-118.44685971736908, 34.14617211080851],
[-118.4468302130699, 34.14610995587136],
[-118.44671756029128, 34.14576588307053],
[-118.44666659832001, 34.14569040884941],
[-118.4465754032135, 34.145561658551856],
[-118.44654053449631, 34.14537075257705],
[-118.44656199216844, 34.14531525657322],
[-118.44660490751268, 34.14522202320469],
[-118.44666928052901, 34.14508883249976],
[-118.4467738866806, 34.14492900337667],
[-118.44714134931564, 34.144345180538075],
[-118.44724595546721, 34.144167591041665],
[-118.44746589660645, 34.14389676634091],
[-118.44773143529893, 34.143637040197646],
[-118.44793260097505, 34.14342393097094],
[-118.44798624515533, 34.143344014872326],
[-118.44802916049957, 34.143264098698126],
[-118.44805866479874, 34.14320860131048],
[-118.44806134700775, 34.14311092581964],
[-118.44804793596266, 34.14301325021589],
[-118.44807475805283, 34.1428889356478],
[-118.44817131757735, 34.142729102362914],
[-118.44827055931091, 34.14261366702467],
[-118.44845294952391, 34.14240721496879],
[-118.44851195812225, 34.1422962190313],
[-118.4486970305443, 34.14189441251827],
[-118.4489169716835, 34.141448205256296],
[-118.44912618398665, 34.14101087545433],
[-118.44926834106445, 34.14073782067377],
[-118.44944804906845, 34.14037596623108],
[-118.44964385032654, 34.13998081052974],
[-118.4498342871666, 34.139616732854655],
[-118.44989329576491, 34.13949463328309],
[-118.4500166773796, 34.139245993610096],
[-118.45008373260498, 34.13912611350636],
[-118.45019906759262, 34.13890411286514],
[-118.45033317804337, 34.13872651193225],
[-118.4505772590637, 34.13841792942364],
[-118.45063894987106, 34.13832690846846],
[-118.45148384571075, 34.13721910898561],
[-118.45174133777618, 34.13687722004035],
[-118.45193445682526, 34.136628572665956],
[-118.45214903354643, 34.136368824181034],
[-118.45228046178816, 34.13627114078354],
[-118.45256745815279, 34.136073553566185],
[-118.45295637845992, 34.13591592747724],
[-118.45308512449263, 34.13582712391739],
[-118.45317900180817, 34.135698358589856],
[-118.45320314168929, 34.135449707746986],
[-118.45313072204591, 34.135205496385616],
[-118.45292419195174, 34.135010126788465],
[-118.45279544591902, 34.1349612843186],
[-118.45267742872237, 34.134919102162826],
[-118.45248430967332, 34.13490578147768],
[-118.45228046178816, 34.134932422845864],
[-118.45213294029236, 34.134919102162826],
[-118.45198541879654, 34.13490134124881],
[-118.45173329114914, 34.134819196973034],
[-118.45158040523529, 34.13473039226078],
[-118.45145970582962, 34.134619386239216],
[-118.45134437084197, 34.13446619769004],
[-118.45125585794449, 34.13432188938248],
[-118.45111370086669, 34.13414649895386],
[-118.45094203948973, 34.13403327202814],
[-118.4507355093956, 34.133933365791236],
[-118.45047533512115, 34.133895623404335],
[-118.45026612281798, 34.13390228382677],
[-118.45004886388779, 34.13394890676917],
[-118.44987988471985, 34.13402439147855],
[-118.44961971044539, 34.13421976335437],
[-118.4494024515152, 34.13435297119262],
[-118.44921737909316, 34.13439959388638],
[-118.44906449317932, 34.134415134778614],
[-118.44894379377365, 34.13439959388638],
[-118.44874262809753, 34.13434853093473],
[-118.44855487346649, 34.13422642375129],
[-118.44837516546251, 34.13379127671756],
[-118.44833225011824, 34.13368026946253],
[-118.44804257154463, 34.1329720397431],
[-118.4478548169136, 34.132505803773135],
[-118.4477823972702, 34.13242809752812],
[-118.44766169786453, 34.13231042793535],
[-118.44752490520476, 34.13224604261713],
[-118.44723254442214, 34.13208174882427],
[-118.4469884634018, 34.13191079413322],
[-118.4468087553978, 34.13174871988604],
[-118.44654858112334, 34.13159774633511],
[-118.4459102153778, 34.131324661138855],
[-118.44558298587798, 34.13124029317626],
[-118.44531476497652, 34.13119366873973],
[-118.44509482383728, 34.13114260385121],
[-118.44451010227205, 34.13101161116996],
[-118.4443598985672, 34.13095388551715],
[-118.44417750835417, 34.13088727894572],
[-118.4440889954567, 34.1308206723218],
[-118.44387710094452, 34.13070522071602],
[-118.44370543956757, 34.13064305440144],
[-118.44350159168245, 34.13060309031791],
[-118.44332456588745, 34.130583108269064],
[-118.44320386648177, 34.13058532849696],
[-118.44304293394087, 34.13062529258886],
[-118.44287663698196, 34.130665256661906],
[-118.4427237510681, 34.130762946538646],
[-118.4425950050354, 34.13085397564034],
[-118.4422704577446, 34.131053795275896],
[-118.4420558810234, 34.1311359432113],
[-118.44191908836363, 34.13113372299788],
[-118.44180643558501, 34.13113816342467],
[-118.44159185886383, 34.13111596128842],
[-118.44143897294997, 34.131095979360815],
[-118.44125390052795, 34.13109375914633],
[-118.44108492136003, 34.131095979360815]
]
}
}
]
}
},
layout: {
"line-join": "round",
"line-cap": "round"
},
paint: {
"line-color": ["string", ["get", "color"]],
"line-width": 3,
"line-opacity": 0.6
}
});
});
I'm working with this simple chart:
https://jsfiddle.net/w7uyghqn/2/
My dates are in the format: Date(1447793679000), which translates correctly to Thu Aug 11 2016 10:26:59 GMT-0400 (EDT).
var seriesOptions = [
{
"data":[
[Date(1447793679000), 7.8494623656],
[Date(1450913358000), 5.4140127389],
[Date(1460475392000), 6.015037594],
[Date(1460648544000), 3.75],
[Date(1460753244000), 2.1015761821],
[Date(1460985174000), 3.0141843972],
[Date(1460988174000), 5.2264808362],
[Date(1461874589000), 1.5100671141]
],
"name":"Product 1"
},
{
"data":[
[Date(1450729647000), 2.9850746269],
[Date(1452184898000), 4.1666666667],
[Date(1454616863000), 4.1749502982],
[Date(1455206741000), 2.6717557252],
[Date(1458062356000), 2.4],
[Date(1459868909000), 3.8461538462],
[Date(1459882015000), 3.3955857385],
[Date(1459968893000), 4.1832669323],
[Date(1460574864000), 4.973357016],
[Date(1460665314000), 5.2032520325]
],
"name":"Product 2"
}
]
However, as you can see on the x-axis, this is all Jan 1st 1970. Can anyone spot what's wrong?
I've tried so many different formats and I'm totally tearing my hair out.
As jlbriggs said in the comments, you can simply remove the Date() function and use the actual number which will automatically be interpreted by HighCharts as the number of milliseconds since January 1, 1970 because you told it that the xAxis.type is datetime.
I modified your JSFiddle and fixed the problem so you can see it: Working JSFiddle
var seriesOptions = [
{
"data":[
[1447793679000, 7.8494623656],
[1450913358000, 5.4140127389],
[1460475392000, 6.015037594],
[1460648544000, 3.75],
[1460753244000, 2.1015761821],
[1460985174000, 3.0141843972],
[1460988174000, 5.2264808362],
[1461874589000, 1.5100671141]
],
"name":"Product 1"
},{
"data":[
[1450729647000, 2.9850746269],
[1452184898000, 4.1666666667],
[1454616863000, 4.1749502982],
[1455206741000, 2.6717557252],
[1458062356000, 2.4],
[1459868909000, 3.8461538462],
[1459882015000, 3.3955857385],
[1459968893000, 4.1832669323],
[1460574864000, 4.973357016],
[1460665314000, 5.2032520325]
],
"name":"Product 2"
}
]
Highmap metadata has an option 'hc-transform',can someone explain how to use it?
I used the default China map geodata in highmaps,but now I want to add a new point,for example [lat,lon] [121,23],I want to know how can I transform it to a coordinate.
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:EPSG:3415"
}
},
"hc-transform": {
"cn-all": {
"xpan": 350,
"ypan": 25,
"hitZone": {
"type": "Polygon",
"coordinates": [
[
[7902,3046],
[7929,3041],
[7947,3014],
[7915,2972]
]
]
},
"crs": "+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +ellps=airy +toWGS84=446.448,-125.157,542.06,0.15,0.247,0.842,-20.489 +units=m +vunits=m +no_defs",
"scale": 0.000129831107685,
"jsonres": 15.5,
"jsonmarginX": -999,
"jsonmarginY": 9851.0,
"xoffset": -3139937.49309,
"yoffset": 4358972.7486
}
}
Here is what I do.
var transform = Highcharts.maps['countries/cn/cn-all']['hc-transform']['default'];
var position = $(".chart").highcharts().transformFromLatLon({ lat: 121, lon: 23 }, transform);
console.log(position); // {x:NaN ,y:NaN}
Am I wrong in 'hc-transform' setting? How should I make the case.
The 'hc-transform' setting is right.
please try switch lat and lon, like this:
$(".chart").highcharts().transformFromLatLon({ lat: 121, lon: 23 }, transform);
then x and y come out.
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.