Obsah
1. Tvorba jednoduchých grafů v systému Incanter
3. Přidání legendy a nadpisu do sloupcového grafu
4. Sloupcový graf s více kategoriemi
7. Pod kapotu Incanteru – přímé použití objektů z knihovny JFreeChart
8. Vykreslení grafu s průběhem funkce
9. Vykreslení funkce i její derivace
10. Numerický výpočet derivace
11. Vliv hodnoty dx na numerický výpočet derivace
14. Repositář s demonstračními příklady
15. Předchozí články o programovacím jazyku Clojure a jeho knihovnách
1. Tvorba jednoduchých grafů v systému Incanter
V systému Incanter je samozřejmě možné vykreslovat různé typy grafů. Podobně, jako je tomu například v Matplotlibu nebo v systému R, existuje i v Incanteru možnost tvořit sloupcové grafy, spojnicové grafy, koláčové grafy, parametrické grafy atd. Incanter přitom interně využívá knihovnu JFreeChart. V praxi je tedy možné (a někdy i nutné) modifikovat vykreslované grafy přímo manipulací s objekty JFreeChartu – a to díky podpoře tzv. Java interop v programovacím jazyku Clojure. V dnešním článku si popíšeme tvorbu těch nejjednodušších (ale pravděpodobně nejčastěji používaných) grafů – sloupcového grafu, liniového grafu, grafu s průběhem funkce či funkcí a konečně grafu parametrického.
Na začátku si připomeňme, že grafy je možné zobrazit funkcí view. Ovšem kromě této funkce, která graf vykreslí do samostatného okna, ho můžeme uložit do rastrového souboru funkcí save. Alternativně lze použít funkci pojmenovanou save-svg, která graf vyexportuje do vektorového formátu SVG (což je mnohdy výhodnější, jak z hlediska velikosti souboru, tak i možnosti jeho tisku a dalšího zpracování beze ztráty kvality).
2. Sloupcový graf
Jedním z nejjednodušších typů grafů podporovaných systémem Incanter je sloupcový graf, který může být podle konkrétních požadavků orientován jak horizontálně, tak i vertikálně. Tento typ grafu se vytváří zavoláním makra pojmenovaného bar-chart, kterému je nutné předat minimálně dvě informace – sekvenci s popiskami hodnot na x-ové ose a sekvenci se samotnými hodnotami, které se mají do grafu vynést. Obě sekvence by přitom měly mít shodnou délku, což je systémem Incanter kontrolováno při konstrukci grafu. Podívejme se nyní na jednoduchý příklad. Spustíme interaktivní smyčku REPL, přepneme se do nového jmenného prostoru a nejprve provedeme všechny potřebné importy:
(ns simple-plot (:use (incanter core stats charts)))
Následně již můžeme nějakým způsobem vypočítat či načíst hodnoty, které se mají do grafu vynést. Pro jednoduchost se bude jednat o výsledky hodů kostkou, konkrétně o deset celočíselných hodnot od 1 do 6:
(def hody-kostkou (take 10 (repeatedly #(inc (rand-int 6)))))
Samotný sloupcový graf se následně vytvoří makrem bar-chart a vykreslí funkcí view, s níž jsme se již seznámili v úvodním článku o projektu Incanter. Prvním parametrem do makra bar-chart předáváme sekvenci hodnot 1..10, která se vypíše na x-ovou osu, druhým parametrem jsou vynášené hodnoty:
(view (bar-chart (range 1 (inc (count hody-kostkou))) hody-kostkou))
Obrázek 1: Sloupcový graf s výchozími popisy os.
Při pohledu na předchozí screenshot jste si pravděpodobně všimli, že popisky os jsou automaticky získány z parametrů předaných makru bar-chart (ostatně právě proto se jedná o makro, aby nedošlo k vyhodnocení parametrů). Můžeme se ostatně jednoduše přesvědčit, co se stane ve chvíli, kdy změníme první parametr (který se ovšem vyhodnotí na tu samou sekvenci 1..10, jako tomu bylo v předchozím příkladu):
(view (bar-chart (range 1 11) hody-kostkou))
Obrázek 2: Kvůli způsobu vyhodnocování maker se automaticky mění i popisy os.
Ve skutečnosti se ovšem prakticky nikdy nespokojíme s výchozím automaticky generovaným popisem os a budeme muset vytvořit popisky vlastní. To se provede jednoduše – předáním nepovinných parametrů se jmény :x-label a y:label makru bar-chart:
(view (bar-chart (range 1 (inc (count hody-kostkou))) hody-kostkou :x-label "Pokusy" :y-label "Výsledek hodu"))
Obrázek 3: Změna popisu os ve sloupcovém grafu.
3. Přidání legendy a nadpisu do sloupcového grafu
Sloupcový graf je možné, ostatně podobně jako všechny další typy grafů, různým způsobem upravovat, i když je nutno poznamenat, že například Matplotlib nabízí jednodušší možnosti modifikací. Kromě popisků os je možné povolit a nakonfigurovat i zobrazení legendy, která se ve výchozím nastavení umisťuje pod vlastním grafem. Zobrazení legendy se povoluje nepovinným parametrem se jménem :legend:
(view (bar-chart (range 1 (inc (count hody-kostkou))) hody-kostkou :x-label "Pokusy" :y-label "Výsledek hodu" :legend true))
Obrázek 4: Legenda, která byla vytvořena automaticky.
Text legendy se opět automaticky získává z parametrů předaných makru bar-chart, takže je možné provést jednoduchou úpravu a získat odlišnou legendu:
(def indexy (range 1 (inc (count hody-kostkou)))) (view (bar-chart indexy hody-kostkou :x-label "Pokusy" :y-label "Výsledek hodu" :legend true))
Obrázek 5: Explicitně zapsaná legenda.
Poslední jednoduchou úpravou je přidání titulku do grafu. K tomuto účelu se opět používá nepovinný keyword parametr, který se tentokrát jmenuje :title:
(def indexy (range 1 (inc (count hody-kostkou)))) (view (bar-chart indexy hody-kostkou :x-label "Pokusy" :y-label "Výsledek hodu" :legend true :title "Hody kostkou"))
Obrázek 6: Přidání nadpisu do grafu.
4. Sloupcový graf s více kategoriemi
Sloupcové grafy popsané v předchozích dvou kapitolách byly ve skutečnosti velmi jednoduché, protože sloužily pro zobrazení hodnot z jediné kategorie (v našem případě se jednalo o výsledky hodu kostkou). V praxi se ovšem velmi často setkáme s požadavkem, aby se do sloupcového grafu vykreslily hodnoty z několika kategorií. Pěkným příkladem z praxe může být například tento graf s výsledky benchmarků. Pokud budete chtít vytvořit podobný typ grafu, je nutné makru bar-chart předat i parametr pojmenovaný :group-by s definicí jednotlivých kategorií. Opět se podívejme na demonstrační příklad, který tentokrát vznikl úpravou příkladu převzatého přímo z dokumentace k projektu Incanter. Budeme požadovat tento výsledek:
Obrázek 7: Sloupcový graf se čtyřmi kategoriemi.
Nejprve si vytvoříme sekvenci obsahující kategorie, které se ovšem budou opakovat, aby byl počet prvků v sekvenci totožný s počtem všech vykreslovaných hodnot. K tomuto účelu použijeme funkci repeat, která bude třikrát opakovat předaný seznam (nebo jinou sekvenci):
(def seasons (mapcat identity (repeat 3 ["jaro" "léto" "podzim" "zima"])))
Výsledkem bude sekvence s dvanácti prvky:
seasons ("jaro" "léto" "podzim" "zima" "jaro" "léto" "podzim" "zima" "jaro" "léto" "podzim" "zima")
Dále vytvoříme druhou sekvenci, tentokrát obsahující roky, pro které se má graf vykreslit. Opět získáme sekvenci s dvanácti hodnotami, tentokrát se ovšem v sekvenci opakuje každá hodnota čtyřikrát (stále opakujeme jen tři roky):
(def years (mapcat identity (repeat 4 [2016 2017 2018]))) years (2016 2017 2018 2016 2017 2018 2016 2017 2018 2016 2017 2018)
A konečně následuje sekvence s vlastními hodnotami, které se mají vykreslit do grafu. Pro jednoduchost zde použijeme generátor náhodných hodnot s rovnoměrným rozdělením:
(def values (sample-uniform 12 :integers true :max 100)) values (75 81 45 95 98 52 73 59 9 3 98 34)
Samotné vykreslení grafu je již poměrně snadné, ovšem nesmíme přitom zapomenout na předání již výše zmíněného parametru :group-by, aby se dosáhlo korektního seskupení hodnot podle kategorií (ostatně schválně si vyzkoušejte, jak bude graf vypadat, pokud tento parametr makru bar-chart nepředáte):
(view (bar-chart years values :group-by seasons :legend true :x-label "Rok" :y-label "Úroda"))
5. Speciální forma doto
V následujících kapitolách se poměrně často setkáme se speciální formou nazvanou doto, která se v programovacím jazyku Clojure používá pro zjednodušení volání funkcí (či metod), které mají shodný první parametr. Nejprve se ovšem podívejme na jednoduchý příklad, v němž se tato speciální forma naopak nevyužívá:
(defn -main "Vstupni bod do aplikace." [& args] (let [object (create-object args)] (do-something object) (do-something-else object 1) (do-something-else object 2) (do-something-else object 3) (do-something-else object 4) (do-something-else object 5)))
Programátora by zde mělo zaujmout především to, že hodnota, která je navázaná na lokální symbol object, je použita při volání dalších šesti funkcí (nebo metod, pokud by před nimi byla zapsána tečka) a to příhodně jako první parametr (což není náhoda, takto jsem si ony volané funkce schválně upravil). Jedná se tedy o opakující se kód, který není příliš přehledný a navíc opět oplývá zbytečně velkým množstvím kulatých závorek, kvůli nimž jsou LISPovské jazyky nechvalně známé :-) V tomto případě je ovšem náprava velmi snadná, protože stačí použít již v nadpisu kapitoly zmíněnou speciální formu doto a přepsat funkci -main následujícím způsobem:
(defn -main "Vstupni bod do aplikace." [& args] (doto (create-object args) (do-something) (do-something-else 1) (do-something-else 2) (do-something-else 3) (do-something-else 4) (do-something-else 5)))
Tato forma nejprve zavolá první funkci create-object a její výsledek postupně předá dalším čtyřem funkcím (jako první parametr). Navíc jsme se elegantně zbavili lokálního symbolu object a tím pádem i formy let.
6. Spojnicový graf
Druhým typem grafu, s nímž se v dnešním článku seznámíme, je takzvaný spojnicový či liniový graf. Ten se poměrně často využívá například ve finančnictví. Na druhou stranu ovšem uvidíme, že se tento graf příliš nehodí pro zobrazení průběhu nějaké funkce – pro tento účel totiž existuje specifický typ grafu, který bude popsán později. Nejdříve se ovšem podívejme na klasický spojnicový graf. Ten se vytváří funkcí nazvanou line-chart, které se opět předají hodnoty na x-ové ose a hodnoty na ose y-ové:
(ns simple-line-chart (:use (incanter core stats charts))) (def x (range 0 100 0.5)) (def y (map #(/ (sin %) (inc %)) x)) (view (line-chart x y))
Povšimněte si, že hodnoty vynesené na x-ovou osu nejsou čitelné – je jich příliš mnoho:
Obrázek 8: Jednoduchý spojnicový graf s výchozím popisem os.
V případě potřeby můžeme změnit rozsah hodnot na y-ové ose, a to zavoláním funkce set-y-range. Vzhledem k tomu, že prvním parametrem této funkce je objekt s grafem, můžeme využít speciální formu doto:
(view (doto (line-chart x y) (set-y-range -1/2 1/2)))
Nebo ještě jednodušeji:
(doto (line-chart x y) (set-y-range -1/2 1/2) view)
Obrázek 9: Změna minimální a maximální hodnoty na vertikální ose.
Dále si můžeme změnit popisky os, a to s využitím funkcí pojmenovaných set-x-label a set-y-label. Tyto funkce je opět vhodné volat přes speciální formu doto:
(view (doto (line-chart x y :title "sinc") (set-y-range -1/2 1/2) (set-x-label "t") (set-y-label "sinc")))
Obrázek 10: Popisky os a titulek grafu.
7. Pod kapotu Incanteru – přímé použití objektů z knihovny JFreeChart
Kromě již zmíněných funkcí set-x-label, set-y-label či set-y-range nám systém Incanter nenabízí mnoho možností, jak ovlivnit způsob vykreslení grafu. Pokud je například nutné změnit frekvenci značek na osách atd., musíme se uchýlit k přímému použití objektů z knihovny JFreeChart. V této kapitole budou ukázány jen některé možnosti, protože knihovna JFreeChart je poměrně rozsáhlá a zasloužila by si vlastní článek.
Nový příklad začneme podobně, jako příklad předchozí, tj. importem potřebných modulů a následně vytvořením sekvencí představujících hodnoty na x-ové ose a vynášené hodnoty:
(ns jfree-chart-interface (:use (incanter core stats charts))) (def x (range 0 100 0.5)) (def y (map #(/ (sin %) (inc %)) x))
Následně vytvoříme objekt s grafem, u kterého ovšem změníme frekvenci numerických popisů na y-ové ose:
(def plot (doto (line-chart x y :title "sinc") (set-y-range -1/2 1/2) (set-x-label "t") (set-y-label "sinc")))
Nastavení popisků na y-ové ose zavoláním metody setTickUnit() pro objekt představující y-ovou osu (range axis) a zobrazení grafu:
(.setTickUnit (.getRangeAxis (.getPlot plot)) (org.jfree.chart.axis.NumberTickUnit. 0.05)) (view plot)
Obrázek 11: Změna popisků na vertikální ose.
Mnohem jednodušší je další operace, která zakáže vykreslování popisků a značek na x-ové ose:
(.setVisible (.getDomainAxis (.getPlot plot)) false) (view plot)
Obrázek 12: Odstranění popisků na horizontální ose.
8. Vykreslení grafu s průběhem funkce
Pro vykreslení grafu s průběhem nějaké funkce je vhodnější namísto výše popsaného liniového grafu použít graf vytvořený funkcí function-plot. Jedním z důvodů vedoucích k použití tohoto typu grafu je snadnější manipulace s popisky os. Opět se podívejme na jednoduchý příklad, v němž se tento typ grafu použije. Začneme specifikací jmenného prostoru a importem potřebných modulů:
(ns simple-function-plot (:use (incanter core stats charts symbolic)))
Vykreslovat budeme známou funkci sinc, takže si ji nejdříve nadefinujeme, stejně jako jakoukoli jinou funkci:
(defn sinc [t] (/ (sin t) t))
Vykreslení této funkce je až triviálně jednoduché. Konstanty –20 a 20 představují rozsah hodnot na x-ové ose:
(view (function-plot sinc -10 10))
Obrázek 13: Vykreslení průběhu funkce sinc.
Pro zajímavost se můžeme pokusit vykreslit derivaci funkce sinc. Již dopředu si řekněme, že použití deriv-fn nepovede k žádoucímu výsledku, i když derivace sinc lze vypočítat snadno:
(view (function-plot (deriv-fn [t] (/ (sin t) t) t) -20 20))
Obrázek 14: Snaha o výpočet a vykreslení derivace funkce sinc.
S využitím funkce add-function můžeme do grafu přidat průběh další funkce. Například si můžeme současně vykreslit jak původní funkci sinc, tak i její symbolicky vyjádřenou derivaci:
(doto (function-plot sinc -10 10) (add-function (deriv-fn [t] (/ (sin t) t) t) -10 10) view)
Obrázek 15: Současné vykreslení funkce i její derivace (nekorektní výsledek).
9. Vykreslení funkce i její derivace
U vykreslení derivace funkce se na chvíli zastavme. Pokusme se například vykreslit derivaci funkce sinus, a to v rozsahu 0 až π. Vykreslení samotné funkce sinus je až triviálně jednoduché:
(def pi java.lang.Math/PI) (view (function-plot sin 0 pi))
Obrázek 16: Průběh funkce sin.
Derivací funkce sinus by měl být kosinus, o čemž se můžeme přesvědčit velmi snadno:
(view (function-plot (deriv-fn [t] (sin t) t) 0 pi))
Obrázek 17: Derivace funkce sin.
Nyní můžeme oba průběhy vykreslit v jediném grafu:
(doto (function-plot sin 0 pi) (add-function (deriv-fn [t] (sin t) t) 0 pi) view)
Obrázek 18: Průběh funkce sin i její derivace v jediném grafu.
Můžeme vidět, že tentokrát je výsledek korektní.
10. Numerický výpočet derivace
Pro vykreslení derivace funkce sinc bude lepší využít numerický výpočet derivace prováděný s využitím funkce nazvané derivative. Podívejme se na jednoduchý příklad, v němž opět nadefinujeme sinc a následně průběh této funkce zobrazíme současně s její derivací:
(defn sinc [t] (/ (sin t) t)) (doto (function-plot sinc -10 10) (add-function (derivative sinc) -10 10) view)
Obrázek 19: Funkce sinc a její derivace. Původní průběh funkce je vykreslen červeně, derivace modře.
Pro větší přehlednost je možné nadefinovat popisky os grafu:
(doto (function-plot sinc -10 10 :x-label "t" :y-label "sinc + deriv sinc") (add-function (derivative sinc) -10 10) view)
Obrázek 20: Změna popisků os grafu.
11. Vliv hodnoty dx na numerický výpočet derivace
Funkci derivative, s níž jsme se seznámili v předchozí kapitole, je možné předat nepovinný parametr pojmenovaný :dx. Tímto parametrem se specifikuje (zjednodušeně řečeno) x-ová vzdálenost mezi dvěma body na funkci v místě, kde se počítá sklon (směrnice tečny) funkce, tj. její hodnota derivace. Výchozí hodnota :dx je nastavena na 0.0001, ale můžete si snadno vyzkoušet, co se stane ve chvíli, kdy bude hodnota příliš velká a kdy se tedy sklon bude počítat na příliš vzdálených bodech (s ohledem na to, s jakou frekvencí funkce kmitá):
(doto (function-plot sinc -10 10 :x-label "t" :y-label "sinc + deriv sinc") (add-function (derivative sinc :dx 5) -10 10) view)
Obrázek 21: Příliš velká hodnota dx znehodnotí výpočet derivace (modrý průběh).
Pro ještě lepší přehled o vlivu :dx na přesnost výpočtů si ukažme graf obsahující mj. i čtyři vypočtené průběhy derivace funkce sinc. První tři průběhy s :dx postupně nastavenou na 0.0001, 1/2 a 1 lze ještě považovat za prakticky dostatečně přesné výpočty derivace, ovšem poslední průběh (fialový) již v žádném případě skutečné derivaci neodpovídá:
(doto (function-plot sinc -10 10 :x-label "t" :y-label "sinc + deriv sinc") (add-function (derivative sinc) -10 10) (add-function (derivative sinc :dx 1/2) -10 10) (add-function (derivative sinc :dx 1) -10 10) (add-function (derivative sinc :dx 5) -10 10) view)
Obrázek 22: Vliv postupné změny hodnoty dx při numerickém výpočtu derivace.
12. Přidání popisků do grafu
Podívejme se ještě na další zajímavou vlastnost Incanteru (kterou opět nalezneme i v Matplotlibu i dalších podobných knihovnách). Do grafu je totiž možné přidat popisky, dokonce s ukazateli (šipkami) na přesné místo, ke kterému se popisek vztahuje. V následujícím grafu jsem například vyznačil ty body na průběhu funkce sinc, v nichž by měla být derivace nulová (tečna v těchto bodech má stejný sklon, jako osa x):
Obrázek 23: Graf s přidanými popisky.
Popisky se do grafu přidají funkcí add-pointer, které je nutné předat souřadnice bodu, na který bude šipka ukazovat, a taktéž text, který se má v grafu zobrazit. V následujícím příkladu jsem nejprve provedl pomocný výpočet x-ové souřadnice bodů ±5π/2 a následně je již vynesení bodů s ukazateli do grafu snadné:
(ns add-pointer-to-plot (:use (incanter core stats charts optimize))) (def pi java.lang.Math/PI) (defn sinc [t] (/ (sin t) t)) (def d0 (/ (* pi 5) 2)) (doto (function-plot sinc -10 10 :x-label "t" :y-label "sinc + deriv sinc") (set-y-range -1/2 3/2) (add-function (derivative sinc) -10 10) (add-pointer 0 1 :text "deriv=0") (add-pointer d0 (sinc d0) :text "deriv=0") (add-pointer (- d0) (sinc (- d0)) :text "deriv=0") view)
13. Parametrický graf
Posledním typem grafu, s nímž se dnes seznámíme, je parametrický graf. Ten dokáže vykreslit průběh funkce typu x,y=f(t). Jak se však taková taková funkce vytvoří? V Clojure sice každá funkce vrací jedinou hodnotu (na rozdíl od jazyka Lua), ovšem nic nám nebrání v tom vrátit vektor obsahující dvojici návratových hodnot x a y. A právě tento způsob je využit v parametrickém grafu. Podívejme se na vykreslení jednoduché spirály:
(ns parametric-graph (:use (incanter core stats charts svg))) (defn spiral [t] [(* t (cos t)) (* t (sin t))]) (view (parametric-plot spiral 0 (* 6 Math/PI) :x-label "x" :y-label "y"))
Obrázek 24: Spirála vykreslená předchozím příkladem.
Podobným způsobem můžeme vykreslit například Lissajousův obrazec:
(defn lis [t] [(cos (* t 3)) (sin (* t 4))]) (view (parametric-plot lis 0 (* 6 Math/PI) :x-label "x" :y-label "y"))
Obrázek 25: Lissajousův obrazec vykreslený předchozím příkladem.
14. Repositář s demonstračními příklady
Zdrojové kódy všech dnes popsaných demonstračních příkladů byly uloženy do Git repositáře dostupného na adrese https://github.com/tisnik/incanter-examples (stále na GitHubu :-). V případě, že nebudete chtít klonovat celý repositář (ten je ovšem stále velmi malý, dnes má doslova několik kilobajtů), můžete namísto toho použít odkazy na jednotlivé příklady, které naleznete v následující tabulce:
15. Předchozí články o programovacím jazyku Clojure a jeho knihovnách
- Clojure 1: Úvod
http://www.root.cz/clanky/clojure-aneb-jazyk-umoznujici-tvorbu-bezpecnych-vicevlaknovych-aplikaci-pro-jvm/ - Clojure 2: Symboly, kolekce atd.
http://www.root.cz/clanky/clojure-aneb-jazyk-umoznujici-tvorbu-bezpecnych-vicevlaknovych-aplikaci-pro-jvm-2-cast/ - Clojure 3: Funkcionální programování
http://www.root.cz/clanky/clojure-aneb-jazyk-umoznujici-tvorbu-bezpecnych-vicevlaknovych-aplikaci-pro-jvm-3-cast-funkcionalni-programovani/ - Clojure 4: Kolekce, sekvence a lazy sekvence
http://www.root.cz/clanky/clojure-aneb-jazyk-umoznujici-tvorbu-bezpecnych-vicevlaknovych-aplikaci-pro-jvm-4-cast-kolekce-sekvence-a-lazy-sekvence/ - Clojure 5: Sekvence, lazy sekvence a paralelní programy
http://www.root.cz/clanky/clojure-a-bezpecne-aplikace-pro-jvm-sekvence-lazy-sekvence-a-paralelni-programy/ - Clojure 6: Podpora pro paralelní programování
http://www.root.cz/clanky/programovaci-jazyk-clojure-6-futures-nejsou-jen-financni-derivaty/ - Clojure 7: Další funkce pro paralelní programování
http://www.root.cz/clanky/programovaci-jazyk-clojure-7-dalsi-podpurne-prostredky-pro-paralelni-programovani/ - Clojure 8: Identity, stavy, neměnné hodnoty a reference
http://www.root.cz/clanky/programovaci-jazyk-clojure-8-identity-stavy-nemenne-hodnoty-a-referencni-typy/ - Clojure 9: Validátory, pozorovatelé a kooperace s Javou
http://www.root.cz/clanky/programovaci-jazyk-clojure-9-validatory-pozorovatele-a-kooperace-mezi-clojure-a-javou/ - Clojure 10: Kooperace mezi Clojure a Javou
http://www.root.cz/clanky/programovaci-jazyk-clojure-10-kooperace-mezi-clojure-a-javou-pokracovani/ - Clojure 11: Generátorová notace seznamu/list comprehension
http://www.root.cz/clanky/programovaci-jazyk-clojure-11-generatorova-notace-seznamu-list-comprehension/ - Clojure 12: Překlad programů z Clojure do bajtkódu JVM I:
http://www.root.cz/clanky/programovaci-jazyk-clojure-12-preklad-programu-z-clojure-do-bajtkodu-jvm/ - Clojure 13: Překlad programů z Clojure do bajtkódu JVM II:
http://www.root.cz/clanky/programovaci-jazyk-clojure-13-preklad-programu-z-clojure-do-bajtkodu-jvm-pokracovani/ - Clojure 14: Základy práce se systémem maker
http://www.root.cz/clanky/programovaci-jazyk-clojure-14-zaklady-prace-se-systemem-maker/ - Clojure 15: Tvorba uživatelských maker
http://www.root.cz/clanky/programovaci-jazyk-clojure-15-tvorba-uzivatelskych-maker/ - Programovací jazyk Clojure – triky při práci s řetězci
http://www.root.cz/clanky/programovaci-jazyk-clojure-triky-pri-praci-s-retezci/ - Programovací jazyk Clojure – triky při práci s kolekcemi
http://www.root.cz/clanky/programovaci-jazyk-clojure-triky-pri-praci-s-kolekcemi/ - Programovací jazyk Clojure – práce s mapami a množinami
http://www.root.cz/clanky/programovaci-jazyk-clojure-prace-s-mapami-a-mnozinami/ - Programovací jazyk Clojure – základy zpracování XML
http://www.root.cz/clanky/programovaci-jazyk-clojure-zaklady-zpracovani-xml/ - Programovací jazyk Clojure – testování s využitím knihovny Expectations
http://www.root.cz/clanky/programovaci-jazyk-clojure-testovani-s-vyuzitim-knihovny-expectations/ - Programovací jazyk Clojure – některé užitečné triky použitelné (nejenom) v testech
http://www.root.cz/clanky/programovaci-jazyk-clojure-nektere-uzitecne-triky-pouzitelne-nejenom-v-testech/ - Enlive – výkonný šablonovací systém pro jazyk Clojure
http://www.root.cz/clanky/enlive-vykonny-sablonovaci-system-pro-jazyk-clojure/ - Nástroj Leiningen a programovací jazyk Clojure: tvorba vlastních knihoven pro veřejný repositář Clojars
http://www.root.cz/clanky/nastroj-leiningen-a-programovaci-jazyk-clojure-tvorba-vlastnich-knihoven-pro-verejny-repositar-clojars/ - Novinky v Clojure verze 1.8.0
http://www.root.cz/clanky/novinky-v-clojure-verze-1–8–0/ - Asynchronní programování v Clojure s využitím knihovny core.async
http://www.root.cz/clanky/asynchronni-programovani-v-clojure-s-vyuzitim-knihovny-core-async/ - Asynchronní programování v Clojure s využitím knihovny core.async (pokračování)
http://www.root.cz/clanky/asynchronni-programovani-v-clojure-s-vyuzitim-knihovny-core-async-pokracovani/ - Asynchronní programování v Clojure s využitím knihovny core.async (dokončení)
http://www.root.cz/clanky/asynchronni-programovani-v-clojure-s-vyuzitim-knihovny-core-async-dokonceni/ - Vytváříme IRC bota v programovacím jazyce Clojure
http://www.root.cz/clanky/vytvarime-irc-bota-v-programovacim-jazyce-clojure/ - Gorilla REPL: interaktivní prostředí pro programovací jazyk Clojure
https://www.root.cz/clanky/gorilla-repl-interaktivni-prostredi-pro-programovaci-jazyk-clojure/ - Multimetody v Clojure aneb polymorfismus bez použití OOP
https://www.root.cz/clanky/multimetody-v-clojure-aneb-polymorfismus-bez-pouziti-oop/ - Práce s externími Java archivy v programovacím jazyku Clojure
https://www.root.cz/clanky/prace-s-externimi-java-archivy-v-programovacim-jazyku-clojure/ - Clojure 16: Složitější uživatelská makra
http://www.root.cz/clanky/programovaci-jazyk-clojure-16-slozitejsi-uzivatelska-makra/ - Clojure 17: Využití standardních maker v praxi
http://www.root.cz/clanky/programovaci-jazyk-clojure-17-vyuziti-standardnich-maker-v-praxi/ - Clojure 18: Základní techniky optimalizace aplikací
http://www.root.cz/clanky/programovaci-jazyk-clojure-18-zakladni-techniky-optimalizace-aplikaci/ - Clojure 19: Vývojová prostředí pro Clojure
http://www.root.cz/clanky/programovaci-jazyk-clojure-19-vyvojova-prostredi-pro-clojure/ - Clojure 20: Vývojová prostředí pro Clojure (Vimu s REPL)
http://www.root.cz/clanky/programovaci-jazyk-clojure-20-vyvojova-prostredi-pro-clojure-integrace-vimu-s-repl/ - Clojure 21: ClojureScript aneb překlad Clojure do JS
http://www.root.cz/clanky/programovaci-jazyk-clojure-21-clojurescript-aneb-preklad-clojure-do-javascriptu/ - Leiningen: nástroj pro správu projektů napsaných v Clojure
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure/ - Leiningen: nástroj pro správu projektů napsaných v Clojure (2)
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-2/ - Leiningen: nástroj pro správu projektů napsaných v Clojure (3)
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-3/ - Leiningen: nástroj pro správu projektů napsaných v Clojure (4)
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-4/ - Leiningen: nástroj pro správu projektů napsaných v Clojure (5)
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-5/ - Leiningen: nástroj pro správu projektů napsaných v Clojure (6)
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-6/ - Programovací jazyk Clojure a databáze (1.část)
http://www.root.cz/clanky/programovaci-jazyk-clojure-a-databaze-1-cast/ - Pluginy pro Leiningen
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-pluginy-pro-leiningen/ - Programovací jazyk Clojure a knihovny pro práci s vektory a maticemi
http://www.root.cz/clanky/programovaci-jazyk-clojure-a-knihovny-pro-praci-s-vektory-a-maticemi/ - Programovací jazyk Clojure a knihovny pro práci s vektory a maticemi (2)
http://www.root.cz/clanky/programovaci-jazyk-clojure-a-knihovny-pro-praci-s-vektory-a-maticemi-2/ - Programovací jazyk Clojure: syntéza procedurálních textur s využitím knihovny Clisk
http://www.root.cz/clanky/programovaci-jazyk-clojure-synteza-proceduralnich-textur-s-vyuzitim-knihovny-clisk/ - Programovací jazyk Clojure: syntéza procedurálních textur s využitím knihovny Clisk (2)
http://www.root.cz/clanky/programovaci-jazyk-clojure-synteza-proceduralnich-textur-s-vyuzitim-knihovny-clisk-2/ - Seesaw: knihovna pro snadnou tvorbu GUI v jazyce Clojure
http://www.root.cz/clanky/seesaw-knihovna-pro-snadnou-tvorbu-gui-v-jazyce-clojure/ - Seesaw: knihovna pro snadnou tvorbu GUI v jazyce Clojure (2)
http://www.root.cz/clanky/seesaw-knihovna-pro-snadnou-tvorbu-gui-v-jazyce-clojure-2/ - Seesaw: knihovna pro snadnou tvorbu GUI v jazyce Clojure (3)
http://www.root.cz/clanky/seesaw-knihovna-pro-snadnou-tvorbu-gui-v-jazyce-clojure-3/ - Programovací jazyk Clojure a práce s Gitem
http://www.root.cz/clanky/programovaci-jazyk-clojure-a-prace-s-gitem/ - Programovací jazyk Clojure a práce s Gitem (2)
http://www.root.cz/clanky/programovaci-jazyk-clojure-a-prace-s-gitem-2/ - Programovací jazyk Clojure: syntéza procedurálních textur s využitím knihovny Clisk (dokončení)
http://www.root.cz/clanky/programovaci-jazyk-clojure-synteza-proceduralnich-textur-s-vyuzitim-knihovny-clisk-dokonceni/ - Pixie: lehký skriptovací jazyk s „kouzelnými“ schopnostmi
https://www.root.cz/clanky/pixie-lehky-skriptovaci-jazyk-s-kouzelnymi-schopnostmi/ - Programovací jazyk Pixie: funkce ze základní knihovny a použití FFI
https://www.root.cz/clanky/programovaci-jazyk-pixie-funkce-ze-zakladni-knihovny-a-pouziti-ffi/ - Novinky v Clojure verze 1.9.0
https://www.root.cz/clanky/novinky-v-clojure-verze-1–9–0/ - Validace dat s využitím knihovny spec v Clojure 1.9.0
https://www.root.cz/clanky/validace-dat-s-vyuzitim-knihovny-spec-v-clojure-1–9–0/ - Použití jazyka Gherkin při tvorbě testovacích scénářů pro aplikace psané v Clojure
https://www.root.cz/clanky/pouziti-jazyka-gherkin-pri-tvorbe-testovacich-scenaru-pro-aplikace-psane-v-nbsp-clojure/ - Použití jazyka Gherkin při tvorbě testovacích scénářů pro aplikace psané v Clojure (2)
https://www.root.cz/clanky/pouziti-jazyka-gherkin-pri-tvorbe-testovacich-scenaru-pro-aplikace-psane-v-nbsp-clojure-2/ - Incanter: prostředí pro statistické výpočty s grafickým výstupem založené na Clojure
https://www.root.cz/clanky/incanter-prostredi-pro-statisticke-vypocty-s-grafickym-vystupem-zalozene-na-clojure/ - Incanter: operace s maticemi
https://www.root.cz/clanky/incanter-operace-s-maticemi/
16. Odkazy na Internetu
- Stopa (algebra)
https://cs.wikipedia.org/wiki/Stopa_(algebra) - Matrix calculator
https://matrixcalc.org/en/ - Incanter is a Clojure-based, R-like platform for statistical computing and graphics.
http://incanter.org/ - Evolution of incanter (Gource Visualization)
https://www.youtube.com/watch?v=TVfL5nPELr4 - Questions tagged [incanter] (na Stack Overflow)
https://stackoverflow.com/questions/tagged/incanter?sort=active - Data Sorcery with Clojure
https://data-sorcery.org/contents/ - Back to the Future: Lisp as a Base for a Statistical Computing System
https://rd.springer.com/chapter/10.1007/978–3–7908–2084–3_2 - Incanter Cheat Sheet
http://incanter.org/docs/incanter-cheat-sheet.pdf - Back to the Future: Lisp as a Base for a Statistical Computing System (celá verze článku)
https://www.researchgate.net/publication/227019917_Back_to_the_Future_Lisp_as_a_Base_for_a_Statistical_Computing_System - Lisp-Stat Information
http://homepage.cs.uiowa.edu/~luke/xls/xlsinfo/ - Sample Plots in Incanter
https://github.com/incanter/incanter/wiki/Sample-Plots-in-Incanter#line - vectorz-clj
https://github.com/mikera/vectorz-clj - vectorz – Examples
https://github.com/mikera/vectorz-clj/wiki/Examples - Array Programming
https://en.wikipedia.org/wiki/Array_programming - Discovering Array Languages
http://archive.vector.org.uk/art10008110 - no stinking loops – Kalothi
http://www.nsl.com/ - Vector (obsahuje odkazy na články, knihy a blogy o programovacích jazycích APL, J a K)
http://www.vector.org.uk/ - Colt
http://dst.lbl.gov/ACSSoftware/colt/ - Parallel Colt: Open Source Libraries for High Performance Scientific and Technical Computing in Java
http://incanter.org/docs/parallelcolt/api/ - Processing
https://www.processing.org/ - The R Project for Statistical Computing
https://www.r-project.org/ - Humane test output for clojure.test
https://github.com/pjstadig/humane-test-output - iota
https://github.com/juxt/iota - 5 Differences between clojure.spec and Schema
https://lispcast.com/clojure.spec-vs-schema/ - Schema: Clojure(Script) library for declarative data description and validation
https://github.com/plumatic/schema - Zip archiv s Clojure 1.9.0
http://repo1.maven.org/maven2/org/clojure/clojure/1.9.0/clojure-1.9.0.zip - Clojure 1.9 is now available
https://clojure.org/news/2017/12/08/clojure19 - Deps and CLI Guide
https://clojure.org/guides/deps_and_cli - Changes to Clojure in Version 1.9
https://github.com/clojure/clojure/blob/master/changes.md - clojure.spec – Rationale and Overview
https://clojure.org/about/spec - Zip archiv s Clojure 1.8.0
http://repo1.maven.org/maven2/org/clojure/clojure/1.8.0/clojure-1.8.0.zip - Clojure 1.8 is now available
http://clojure.org/news/2016/01/19/clojure18 - Socket Server REPL
http://dev.clojure.org/display/design/Socket+Server+REPL - CLJ-1671: Clojure socket server
http://dev.clojure.org/jira/browse/CLJ-1671 - CLJ-1449: Add clojure.string functions for portability to ClojureScript
http://dev.clojure.org/jira/browse/CLJ-1449 - Launching a Socket Server
http://clojure.org/reference/repl_and_main#_launching_a_socket_server - API for clojure.string
http://clojure.github.io/clojure/branch-master/clojure.string-api.html - Clojars:
https://clojars.org/ - Seznam knihoven na Clojars:
https://clojars.org/projects - Clojure Cookbook: Templating HTML with Enlive
https://github.com/clojure-cookbook/clojure-cookbook/blob/master/07_webapps/7–11_enlive.asciidoc - An Introduction to Enlive
https://github.com/swannodette/enlive-tutorial/ - Enlive na GitHubu
https://github.com/cgrand/enlive - Expectations: příklady atd.
http://jayfields.com/expectations/ - Expectations na GitHubu
https://github.com/jaycfields/expectations - Lein-expectations na GitHubu
https://github.com/gar3thjon3s/lein-expectations - Testing Clojure With Expectations
https://semaphoreci.com/blog/2014/09/23/testing-clojure-with-expectations.html - Clojure testing TDD/BDD libraries: clojure.test vs Midje vs Expectations vs Speclj
https://www.reddit.com/r/Clojure/comments/1viilt/clojure_testing_tddbdd_libraries_clojuretest_vs/ - Testing: One assertion per test
http://blog.jayfields.com/2007/06/testing-one-assertion-per-test.html - Rewriting Your Test Suite in Clojure in 24 hours
http://blog.circleci.com/rewriting-your-test-suite-in-clojure-in-24-hours/ - Clojure doc: zipper
http://clojuredocs.org/clojure.zip/zipper - Clojure doc: parse
http://clojuredocs.org/clojure.xml/parse - Clojure doc: xml-zip
http://clojuredocs.org/clojure.zip/xml-zip - Clojure doc: xml-seq
http://clojuredocs.org/clojure.core/xml-seq - Parsing XML in Clojure
https://github.com/clojuredocs/guides - Clojure Zipper Over Nested Vector
https://vitalyper.wordpress.com/2010/11/23/clojure-zipper-over-nested-vector/ - Understanding Clojure's PersistentVector implementation
http://blog.higher-order.net/2009/02/01/understanding-clojures-persistentvector-implementation - Understanding Clojure's PersistentHashMap (deftwice…)
http://blog.higher-order.net/2009/09/08/understanding-clojures-persistenthashmap-deftwice.html - Assoc and Clojure's PersistentHashMap: part ii
http://blog.higher-order.net/2010/08/16/assoc-and-clojures-persistenthashmap-part-ii.html - Ideal Hashtrees (paper)
http://lampwww.epfl.ch/papers/idealhashtrees.pdf - Clojure home page
http://clojure.org/ - Clojure (downloads)
http://clojure.org/downloads - Clojure Sequences
http://clojure.org/sequences - Clojure Data Structures
http://clojure.org/data_structures - The Structure and Interpretation of Computer Programs: 2.2.1 Representing Sequences
http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-15.html#%_sec2.2.1 - The Structure and Interpretation of Computer Programs: 3.3.1 Mutable List Structure
http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-22.html#%_sec3.3.1 - Clojure – Functional Programming for the JVM
http://java.ociweb.com/mark/clojure/article.html - Clojure quick reference
http://faustus.webatu.com/clj-quick-ref.html - 4Clojure
http://www.4clojure.com/ - ClojureDoc (rozcestník s dokumentací jazyka Clojure)
http://clojuredocs.org/ - Clojure (na Wikipedia EN)
http://en.wikipedia.org/wiki/Clojure - Clojure (na Wikipedia CS)
http://cs.wikipedia.org/wiki/Clojure - SICP (The Structure and Interpretation of Computer Programs)
http://mitpress.mit.edu/sicp/ - Pure function
http://en.wikipedia.org/wiki/Pure_function - Funkcionální programování
http://cs.wikipedia.org/wiki/Funkcionální_programování - Čistě funkcionální (datové struktury, jazyky, programování)
http://cs.wikipedia.org/wiki/Čistě_funkcionální - Clojure Macro Tutorial (Part I, Getting the Compiler to Write Your Code For You)
http://www.learningclojure.com/2010/09/clojure-macro-tutorial-part-i-getting.html - Clojure Macro Tutorial (Part II: The Compiler Strikes Back)
http://www.learningclojure.com/2010/09/clojure-macro-tutorial-part-ii-compiler.html - Clojure Macro Tutorial (Part III: Syntax Quote)
http://www.learningclojure.com/2010/09/clojure-macro-tutorial-part-ii-syntax.html - Tech behind Tech: Clojure Macros Simplified
http://techbehindtech.com/2010/09/28/clojure-macros-simplified/ - Fatvat – Exploring functional programming: Clojure Macros
http://www.fatvat.co.uk/2009/02/clojure-macros.html - Eulerovo číslo
http://cs.wikipedia.org/wiki/Eulerovo_číslo - List comprehension
http://en.wikipedia.org/wiki/List_comprehension - List Comprehensions in Clojure
http://asymmetrical-view.com/2008/11/18/list-comprehensions-in-clojure.html - Clojure Programming Concepts: List Comprehension
http://en.wikibooks.org/wiki/Clojure_Programming/Concepts#List_Comprehension - Clojure core API: for macro
http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/for - cirrus machina – The Clojure for macro
http://www.cirrusmachina.com/blog/comment/the-clojure-for-macro/ - Riastradh's Lisp Style Rules
http://mumble.net/~campbell/scheme/style.txt - Dynamic Languages Strike Back
http://steve-yegge.blogspot.cz/2008/05/dynamic-languages-strike-back.html - Scripting: Higher Level Programming for the 21st Century
http://www.tcl.tk/doc/scripting.html - Java Virtual Machine Support for Non-Java Languages
http://docs.oracle.com/javase/7/docs/technotes/guides/vm/multiple-language-support.html - Třída java.lang.String
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html - Třída java.lang.StringBuffer
http://docs.oracle.com/javase/7/docs/api/java/lang/StringBuffer.html - Třída java.lang.StringBuilder
http://docs.oracle.com/javase/7/docs/api/java/lang/StringBuilder.html - StringBuffer versus String
http://www.javaworld.com/article/2076072/build-ci-sdlc/stringbuffer-versus-string.html - Threading macro (dokumentace k jazyku Clojure)
https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/-> - Understanding the Clojure → macro
http://blog.fogus.me/2009/09/04/understanding-the-clojure-macro/ - clojure.inspector
http://clojure.github.io/clojure/clojure.inspector-api.html - The Clojure Toolbox
http://www.clojure-toolbox.com/ - Unit Testing in Clojure
http://nakkaya.com/2009/11/18/unit-testing-in-clojure/ - Testing in Clojure (Part-1: Unit testing)
http://blog.knoldus.com/2014/03/22/testing-in-clojure-part-1-unit-testing/ - API for clojure.test – Clojure v1.6 (stable)
https://clojure.github.io/clojure/clojure.test-api.html - Leiningen: úvodní stránka
http://leiningen.org/ - Leiningen: Git repository
https://github.com/technomancy/leiningen - leiningen-win-installer
http://leiningen-win-installer.djpowell.net/ - Clojure.org: Vars and the Global Environment
http://clojure.org/Vars - Clojure.org: Refs and Transactions
http://clojure.org/Refs - Clojure.org: Atoms
http://clojure.org/Atoms - Clojure.org: Agents as Asynchronous Actions
http://clojure.org/agents - Transient Data Structures
http://clojure.org/transients