Gnuplot vykresluje data ze souborů, bodů zadaných uživatelem, funkcí zadaných předpisem nebo gnuplotem spočtených proložených dat funkcí (fit). Gnuplot je konzolová aplikace ovládána textovými příkazy. Mezi nejfrekventovanější elementy jazyka gnuplotu patří:
-
Nejzákladnější klíčové slovo
plot
provádí vykreslení grafu. -
Matematické formule se zadávají podobně jako v programovacím jazyku C/C++. Například zápis
x**2
vyjadřuje čtverec proměnné x. -
Řetězce se deklarují uvozovkami.
-
Klíčové slovo
set
zajišťuje nejrůznější nastavení. -
Při zadání výrazu
save
se uloží do spustitelného skriptu poslední kreslicí příkaz a nastavení prostředí. Spuštěním skriptu se provede plotovací příkaz s uloženými nastaveními. -
Znak otazník (nebo synonymní klíčové slovo
help
) s uvedeným výrazem zobrazí příslušnou nápovědu. -
Znak vykřičník vynutí interpretaci zbytku řádky jako příkazu Bashe. Uživatel je tak s to pracovat v terminálu přímo z gnuplotu.
Chtějme pro osvětlení způsobu práce v gnuplotu připravit třeba graf funkce sin(1/x)
. V řádkovém rozhraní gnuplotu stačí zadat pouze příkaz plot sin(1/x)
. Graf se otevře ve vlastním okně, které vidíte na předcházejícím obrázku.
Týž graf se zjemněným vzorkováním
Zjevně v důsledku přílišné hrubosti graf nerespektuje průběh funkce v oblasti druhého překmitu. Počet interpolačních bodů zvýším na 5000 příkazem set sample 5000
. Překreslení příkazem plot sin(1/x)
očividně zlepšilo graf.
Nyní popíši graf, přikreslím funkci druhé mocniny a omezím definiční obor na jednotkové okolí nuly. Nadpis grafu zajistí příkaz set title "Dvě funkce"
. Graf vytvořím příkazem plot [-1:1] sin(1/x) title "první funkce", x*x title "druhá funkce"
.
Podobným aditivním postupem by šlo graf dále vylepšovat. O přístupné funkcionalitě poskytne představu oficiální galerie a v ní zveřejněné skripty korespondujícími s grafy. Nad to existuje množství volně dostupných tutoriálů a dokumentace ke gnuplotu.
Další nasazení gnuplotu
Výše uvedené „přímé deklarace“ neodráží nejběžnější způsob práce v gnuplotu. Gnuplot totiž není obvykle využíváván přímo, ale tvoří součást jiných řešení. Gnuplot se nasazuje jako vykreslovací engine u mnoha prominentních projektů. Textově orientované rozhraní gnuplotu totiž představuje z hlediska programátora jasnou konkurenční výhodu oproti převážně grafickým systémům (např. QtiPlot). S jistou nadsázkou by šlo třeba Octave označit za frontend ke gnuplotu. Máte-li nainstalované některé matematické aplikace, pravděpodobně budete mít nainstalovaný i gnuplot.
Navzdory svému názvu gnuplot nesouvisí s aktivitami hnutí GNU. První tři písmena se proto v názvu gnuplot záměrně píší malými písmeny, aby se naznačila odlišnost od produktů GNU. Licence gnuplotu se shoduje, až na jedno podstatné omezení, s běžnými svobodnými licencemi. Smluvní ustanovení totiž vylučuje prosté šíření děl odvozených od gnuplotu. Rozšíření gnuplotu musí být šířena výhradně izolovaně od samotného gnuplotu ve formě rozdílových patchů zdrojového kódu. Gnuplot nerespektuje právo spotřebitele šířit odvozená díla, a proto patří do nepříliš početné kategorie nesvobodného open source. Svobodné náhrady gnuplotu (např. PLPlot a Grace) se těší znatelně nižší popularitě.
Při vývoji softwaru lze gnuplot využít různými způsoby. Například gnuplot může pro webovou aplikaci dynamicky generovat grafy. Stačí jej jen doinstalovat do LAMP serveru. Zbytek článku studuje návrh možného programátorského využití gnuplotu. Pro další výklad si zvolme následující úlohu:
-
Implementujme skript pro řešení číselné křížovky Sudoku metodou genetického algoritmu.
-
Pravděpodobnostní charakter algoritmu vyžaduje mnohonásobné provádění simulace. Statistická chyba totiž v asymptotě klesá jen se čtvercem počtu měření.
-
V gnuplotu vykreslíme rychlost konvergence při různých parametrech algoritmu. Vzhledem k výpočetní intenzivnosti úlohy (řádově hodiny) chceme tento krok provést bez interakce s uživatelem.
-
Grafy se rovněž automaticky uloží. Případně výsledky rozešlete svým přátelům utilitou mailutils.
Popis ukázkového skriptu v Pythonu
Díky extrémně efektivním syntaktickým konstrukcím jazyka Python se celý řešitel vešel do méně než třiceti řádků zdrojového kódu. Krom toho jsem Python vybral, protože se jedná o skriptovací jazyk hojně používaný v matematice. Ačkoli v Pythonu existují řešení s přímou podporou gnuplotu, zvolil jsem v dalším výkladu univerzálně platný postup využívající prostředků samotného operačního systému.
Pravidla Sudoku kladou podmínky na vyplnění sloupců, řádků a čtverečků. Například jednou z podmínek je, že třetí řádek musí obsahovat sedmičku. Tuto vazbu program ukládá jako řetězec „radek37“ do proměnné constrains. Pravidla se testují v řádcích číslo 8, 9 a 10. Poslední řádek funkce fitness vrátí počet splněných podmínek. Nejvyšší teoreticky možná hodnota 243 funkce fitness odpovídá splnění všech podmínek, což je pochopitelně ekvivalentní korektnímu vyplnění křížovky Sudoku. Genetický algoritmus řeší úlohu jako optimalizační úlohu maximalizace funkce fitness.
Z populace se nevyřazují nejlepší vygenerované prvky, a proto se průměrné zdraví populace v okamžiku po selekci monotónně zvyšuje. Po dostatečně dlouhém čase budou populaci tvořit prvky s maximálním zdravím, které řeší úlohu. Naopak vyřazování nejlepších prvků by řešilo úlohu nalezení nejhoršího možného vyplnění, což by představovalo analogii například šachové výzvě samomatu.
Vlastní logika programu funguje následovně: Algoritmus provede vytvoření mutace zcela náhodným doplněním nezadaných polí (řádek 21). Následně generuje nové prvky křížením prvků v populaci (řádek 24). Při dosažení limitní velikosti populace se nejhorší prvky zahodí (řádek 18). Iterace popsané v tomto odstavci se mnohokrát opakuje.
K vytvoření zadání (řádek 21 zdrojového kódu) posloužil program kSudoku, který se dostal mezi základní hry prostředí KDE.
Přístup ke gnuplotu skrze Bash
Operační systém Linux připouští několik způsobů spuštění programu:
-
Forkování rozdělí proces na dva nezávislé stejné procesy. Bohužel fork nespouští libovolný kód, takže z vašeho programu nespustí gnuplot.
-
Eval nahradí kód původního procesu jiným kódem, takže místo zbytku programu začne vykonávat jiný program.
-
Volání system vykoná zadaný příkaz v Bashi. Toto volání budu dále rozebírat.
Skript importuje požadované prostředky operačního systému jednoduše jako import os
. Příkaz Bashe spouštějící gnuplot se nyní provede jednoduše řádkem os.system("gnuplot")
. Často se vyskytuje velmi naivní blud, že Bash je primitivní jako DOS. Mezi vymoženosti Bashe patří třeba:
-
Středník řadí spouštění příkazů do série. Například
sleep 10; scrot
počká deset vteřin a následně sejme screenshot obrazovky. -
Ampersand (znak &) spustí příkaz na pozadí. Takto se dají snadno spouštět další procesy paralelně.
-
Svislítko (znak |) propojí standardní výstup programu se standardním vstupem následujícího programu.
-
Znak „větší než“ (>) přesměruje standardní výstup do souboru.
Následující čtyři příklady rozvíjejí předcházející seznam na konkrétních příkladech:
-
Příkaz
chmod +x skript_gnuplotu; ./skript_gnuplotu
přidá souboru skript_gnuplotu právo na spuštění a spustí jej. (Připomínám, že v gnuplotu příkazsave
uloží postup pro vykreslení posledního grafu a použitá nastavení.) -
Po obměně příkazu na
./skript_gnuplotu &
již skript nečeká na konec gnuplotu. Skript pokračuje s vykreslujícím gnuplotem souběžně. -
Příkaz
echo plot x**3 | gnuplot
nechá gnuplot vykreslit třetí mocninu. Bohužel okno s grafem se hned spolu s gnuplotem zavře. Přepínačpersist
vecho plot x**3 | gnuplot -persist
způsobí, že okno s grafem přežije svůj gnuplot. -
Rozeberme komplikovanější příkaz
echo -e "set terminal png \n plot x**3" | gnuplot > mocnina.png
. Nejprve se v gnuplotu nastaví výstupní formát png (set terminal png
), následně se vykreslí graf znázorňující průběh třetí mocniny a nakonec se finální graf ve formátu png pošle na standardní výstup, který Bash přesměruje do souboru mocnina.png. Téhož efektu lze neelegantně docílit explicitním nastavením výstupu přímo v gnuplotuecho -e "set terminal png \n set output \"mocnina.png\" \n plot x**3" | gnuplot
.
Více o úžasných vlastnostech Bashe se dozvíte v našem seriálu.
Do skriptu řešitele Sudoku jsem připsal část logující údaje o času a zdraví populace do csv souborů. Další připsaná část kódu mění podíl náhodných dat (poměr proměnných velikost_populace_min a pocet_mutací), pro každé jedno nastavení provede simulací tisíc a v závěru uloží vždy do samostatného souboru údaje o průměrném zdraví populace. Na závěr kódu jsem skrze os.system postupně zavolal v gnuplotu příkazy:
set key right bottom title "Podíl náhodných mutací :" set xlabel "Počet iterací" set ylabel "Průměrné fitness" plot "ran005.csv" with lines title "5%" "ran01.csv" with lines title "10%", "ran02.csv" with lines title "20%"
Výsledný graf je vidět výše. Doprovodná funkční ukázka se spokojuje pouze s jednou simulaci pro tisíc iterací, čímž se snižuje čas běhu na přijatelný řád vteřin. V ostatních ohledech se ukázka schoduje s popsaným skriptem. Příklad vygenerovaného výstupu skriptu je uveden na předchozím obrázku.