Warping Maps

Polish railway network
In this warped map of Poland, straight line distance (emphatically not distance measured along the segments) between points in the network is approximately proportional to their rail distance. I do not have a good name for this kind of map. All I know is: if it showed the travel time, we would call it a time-space map. By the way, here is the unwarped version.

Interestingly, the map is the best possible in the sense of minimizing the squared error of the approximation. The rest of this article explains how to produce it.

  1. Scrape the data about Polish railway lines from http://semaforek.kolej.org.pl and put it into an SQLite database. Here is a sample:
    SELECT line, name, kind, metrage, another_line
    FROM Lines JOIN Names USING(name_id) JOIN Kinds USING(kind_id)
    WHERE line = 137 ORDER BY metrage LIMIT 21;
    
    137 | Katowice              | stacja węzłowa     |   381 |   1
    137 | Katowice              | stacja węzłowa     |   381 | 138
    137 | Katowice              | stacja węzłowa     |   381 | 139
    137 | Katowice              | stacja węzłowa     |   381 | 656
    137 | Katowice              | stacja węzłowa     |   381 | 713
    137 | Katowice Załęże       | przystanek osobowy |  2528 |
    137 | Katowice Towarowa KTC | stacja węzłowa     |  2913 | 713
    137 | Chorzów Batory        | stacja węzłowa     |  6166 | 131
    137 | Chorzów Batory        | stacja węzłowa     |  6166 | 164
    137 | Chorzów Batory        | stacja węzłowa     |  6166 | 713
    137 | Świętochłowice        | przystanek osobowy |  8413 |
    137 | Ruda Chebzie          | stacja węzłowa     | 11740 | 187
    137 | Ruda Chebzie          | stacja węzłowa     | 11740 | 189
    137 | Ruda Śląska           | przystanek osobowy | 14068 |
    137 | Zabrze                | stacja             | 18926 |
    137 | Gliwice               | stacja węzłowa     | 27100 | 141
    137 | Gliwice               | stacja węzłowa     | 27100 | 147
    137 | Gliwice               | stacja węzłowa     | 27100 | 168
    137 | Gliwice               | stacja węzłowa     | 27100 | 200
    137 | Gliwice               | stacja węzłowa     | 27100 | 671
    137 | Gliwice               | stacja węzłowa     | 27100 | 711
    
  2. Construct a list of 1838 edges between all terminal and junction nodes of the network, labelled with their length in metres:
    edges = [
        (u’Katowice’, u’Katowice Towarowa KTC’, 2532),
        (u’Katowice Towarowa KTC’, u’Chorzów Batory’, 3253),
        (u’Chorzów Batory’, u’Ruda Chebzie’, 5574),
        (u’Ruda Chebzie’, u’Gliwice’, 15360), ... ]
    
  3. Convert the list of edges into an adjacency matrix, putting infinite distance between nonadjacent vertices. The matrix has 1258 rows and columns.
  4. Compute the shortest distances between all pairs of vertices with the Floyd–Warshall algorithm, obtaining the so-called proximity matrix D.
  5. Perform multidimensional scaling (MDS) of the proximity matrix D, in its classical version invented by Torgerson in 1952:
    coords = sklearn.manifold.MDS(
        dissimilarity=’precomputed’).fit_transform(D)
    

    Under the hood, it would perform four steps:

    1. set up the matrix of squared proximities D(2)
      [if the ith point has coordinates xiyizi,…, then dij(2) = (xixj)2 + (yiyj)2 + (zizj)2 +⋯],
    2. perform the “double centring”: subtract the row mean and the column mean from the elements of D(2), add the total mean, and multiply by −1/2, obtaining matrix B
      [bij = xixj + yiyj + zizj +⋯],
    3. find the singular value decomposition of B into the product of three matrices USUT,
    4. take the initial two singular vectors U2 and two corresponding singular values S2 — the rows of matrix X = U2S21/2 give the coordinates of the points
      [the initial two coordinates computed by SVD follow the principal axes of B, the remaining coordinates are less important, so bijxixj + yiyj or in matrix form BXXT = U2S2U2T],

    were it not using another algorithm, called SMACOF (Scaling by Majorizing a Complicated Function).

  6. The obtained map is randomly oriented. Rotate it to move Gdańsk Główny (G) straight north of Katowice (KO).
  7. If Lublin (Lb) happens to lie west of the Katowice–Gdańsk Główny meridian, flip the X axis.

On my machine, steps 2–7 take about 20 seconds. The code is available on Bitbucket.

Advertisements
Warping Maps

O sol é grande…

Słońce jest wielkie: ptactwo cicho zniża loty
w okresie, który zwykle w zimnej trwa pogodzie.
Zbudziłbym się przy z góry spadającej wodzie,
lecz nie ze snu bynajmniej — z poważnej zgryzoty.

O rzeczy, ciągle próżne — ciągłe wasze zwroty,
jakie serce was przyjmie w ufności i zgodzie?
Czas mija, dni za dniami ciągną się w pochodzie,
bardziej chwiejne niż żagli na wietrze trzepoty.

Widziałem tu już cienie, widziałem kwitnienie,
widziałem tyle wody, zieleń tak bogatą,
słyszałem wszystkich ptaków o miłości pienie.

Wszystko jest suche, nieme, z barwą popielatą;
ja też, zmieszany, inne przyjmuję odcienie.
Odżywa wszystko inne: nie ma rady na to!

Coat of arms of Portugal
Coat of arms of Portugal. Source: Wikipedia

This is the Polish translation… not of the first Portuguese sonnet but of the most popular one among the earliest Portuguese sonnets. The original, shown below, was written by Francisco de Sá de Miranda between 1530 and 1558. And today, June 10, is the Portugal Day.

O sol é grande: caem coa calma as aves,
Do tempo em tal sazão, que sói ser fria.
Esta água que de alto cai acordar-me-ia,
Do sono não, mas de cuidados graves.

Ó cousas, todas vãs, todas mudaves,
Qual é tal coração que em vós confia?
Passam os tempos, vai dia trás dia,
Incertos muito mais que ao vento as naves.

Eu vira já aqui sombras, vira flores,
Vi tantas águas, vi tanta verdura,
As aves todas cantavam de amores.

Tudo é seco e mudo; e, de mistura,
Também mudando-me eu fiz doutras cores.
E tudo o mais renova: isto é sem cura!

O sol é grande…

Kling-dikt över författarens sinnebild, en silkesmask

Sonet o godle autora, jedwabniku

Ucisz się, myśli! Z wolna spekulujesz,
czym być to może. Spójrz: ta kreatura,
żałosny, nagi robak, to figura,
co nie ma kształtu — nic w niej nie wyczujesz

wzrokiem. Lecz zobacz, przecież więcej tu jest
niż sądzisz: zdatna, czysta, cna natura,
dziwna, przez Boga utworzona, która
gryząc rośliny, kornie włókno snuje,

wyplata nici, tka płótno jedwabne.
Tworzy skarb z liści, aż pusta, zmarniała,
owita przędzą, żywota dokona.

Lecz wstanie nowe stworzenie powabne
o pięknych skrzydłach: świeża i wspaniała
dusza, przez żywe słońce przebudzona.

Coat of arms of Sweden
Coat of arms of Sweden. Source: Wikipedia

I published this translation of the first Swedish sonnet to celebrate June 6, the National Day of Sweden. Below is the original, written in 1644 by Georg Stiernhielm, and a literal re-translation from Polish into English for those who want to criticize my version. For another sonnet with a silkworm in it, read my translation of Farie së ndeerme….

Kling-dikt över författarens sinnebild, en silkesmask

Håll stilla mitt förnuft, dig saktelig besinna,
vad detta vara må. Du sir här en figur,
en usel, naken kropp, en mask, ett kreatur,
som ingen skapnad har, där intet är till finna,

som ögat lyster se. Men märk: här ligger inna
mer än en tänka kan, en nyttig, ädel, pur,
en sällsam, underlig av Gud beredd natur:
en mask, dess spis är blad, dess id är artigt spinna,

dess spunna silkes-tråd, dess verk och väv är siden.
Av blad gör han en skatt, till dess han, tom och mager,
invecklat in-dör i sin väv och livet stäcker.

Men si, en ny figur, med vingar prydd, med tiden
här kommer fram igen, uppkvickter, fin och fager,
en livlig sol hans själ med kraft en gång uppväcker.


Sonnet about the author’s crest, silkworm

Calm down, [my] thought! You slowly speculate
what this can be. Look: this creature,
pathetic, naked worm, is a figure
that has no shape — you will sense nothing in it

with sight. But see: still, there is more here
than you suppose: an apt, pure, noble nature,
strange, formed by God, which,
chewing plants, humbly spins fibre,

plaits threads, weaves silk linen.
It is creating a treasure from leaves until, empty, wasted,
wrapped in yarn, it will end [its] life.

But a new graceful being will rise,
with beautiful wings: a fresh and splendid
soul, awakened by the vivid sun.

Kling-dikt över författarens sinnebild, en silkesmask