{"id":70432,"date":"2017-03-27T13:55:14","date_gmt":"2017-03-27T13:55:14","guid":{"rendered":"https:\/\/www.simple-talk.com\/?p=70432"},"modified":"2021-09-15T13:22:21","modified_gmt":"2021-09-15T13:22:21","slug":"generating-plots-automatically-powershell-sql-server-using-gnuplot","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/devops\/database-devops\/generating-plots-automatically-powershell-sql-server-using-gnuplot\/","title":{"rendered":"Generating Plots Automatically From PowerShell and SQL Server Using Gnuplot"},"content":{"rendered":"<p>There are many excellent ways of plotting data from SQL Server databases. There are many R libraries for example, there is Reporting Services, Plotly or PowerBI. I\u2019ve even used Excel and <a href=\"http:\/\/jpgraph.net\/\">JpGraph<\/a>. If I had to learn just one though, I\u2019d use GnuPlot because it is so versatile. If you haven\u2019t heard of <a href=\"http:\/\/www.gnuplot.info\/\">Gnuplot<\/a>, it is the standard way of plotting scientific data which works via the command-line and uses a domain-specific scripting language (DSL) , and there are two books, along with countless samples, tutorials and articles about using it.<\/p>\n<h1>So what is Gnuplot?<\/h1>\n<p><a href=\"http:\/\/www.gnuplot.info\/\">GnuPlot<\/a>, which runs under a free software license, has its origins in the nineteen eighties. You\u2019d have thought that these were primitive times for graphs, but no, they weren\u2019t. If anything, the standard of graphs have deteriorated since then as the tools have become more commoditised. GnuPlot has been cherished and developed mainly for scientific graphs, but it is very versatile. It covers <a href=\"http:\/\/gnuplot.sourceforge.net\/demo_5.0\/\">a vast range of graph types<\/a> and there are a large number of samples and <a href=\"http:\/\/www.usm.uni-muenchen.de\/people\/puls\/lessons\/intro_general\/gnuplot\/gnuplot_for_beginners.pdf\">tutorials<\/a> <a href=\"https:\/\/en.wikibooks.org\/wiki\/Gnuplot\">around<\/a>. It is a tool for the professional, and isn\u2019t really suitable for fancy graphs in PowerPoint presentations.<\/p>\n<p>GnuPlot is one of the last of the applications that can use a classic vector-based pen plotter as easily as a laser printer. It can draw plots onscreen, even in ASCII. Most of us nowadays want graphs as bitmapped graphics to display within a webpage or embed in a document. It does that as well, but also in vector graphics or as a Pdf. The list is endless. It can even do animated graphs. So many impoverished scientists, with antique output devices, have been accommodated over the years and have blessed Gnuplot\u2019s ability to produce graphs on just about any printer. Python, Java, Ruby, Haskell Fortran 95 and Smalltalk all have libraries for accessing Gnuplot.<\/p>\n<p>Another great advantage of GnuPlot is that allows the separation of script from data. GnuPlot runs a script, and generally the data is read from a data file specified by the script in the <strong>plot<\/strong> command. It likes columnar or tab-separated data, which suits SQL Server.<\/p>\n<p>Although GnuPlot is best known for plotting scientific data and mathematical expressions, it is excellent in business, particularly for financial data. Here is an example<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"641\" height=\"314\" class=\"wp-image-70433\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2017\/03\/word-image-19.png\" \/><\/p>\n<p>The existing teaching material on GnuPlot is so good that it would be silly to attempt to add to it. Instead, I\u2019ll start by showing a basic PowerShell-integration.<\/p>\n<h1>Hello Plot<\/h1>\n<p>Gnuplot can be installed via Chocolatey, or done the old-fashioned way via Sourceforge.<\/p>\n<p>There is a windows GUI version of Gnuplot, which is handy for creating scripts. With a script you can use the many &#8216;set&#8217; commands to specify how the image is to be formatted and presented, including such things as the type of output, size of the graph, the fonts and colors to be used, the scale, x,y coordinates, and the output image name. The \u2018plot\u2019 command is then used to actually generate the image. The process has sensible defaults. There are a whole host of other commands, of course. Although you can execute commands interactively via the GUI or the command interface, it is usually best to end up with a script file that can be rendered reusable by means of variables in the script file. If the script contains any errors, these will be displayed during this process, highlighting where the error is.<\/p>\n<p>Once you have the design roughed out, you can run it in PowerShell, or whatever other scripting language you choose.<\/p>\n<p>I use Gnuplot mainly for SQL Server performance testing, because it can be done entirely automated as part of a rapid integration. Without twitching a muscle, if all goes well, you end up with a cute website stocked with all the graphs you\u2019d possibly need for checking that your processes scale properly. However, as I can\u2019t really show that for a general introduction, I\u2019ll get some Open Data and do a bit of analysis on that.<\/p>\n<p>As an example, I\u2019ve taken the data for the annual consumption of Petroleum since 1980. I\u2019ve imported it into SQL Server, created a normalised version and started generating reports. Although it is trivial for Gnuplot to get data from a tab delimited or column delimited file, we\u2019ll, for the first two examples, just use SSMS to get the data. In SSMS, I\u2019ve set the query to text. (Query -&gt; Results to\u2026-&gt;Results to Text) and set the query options (query-&gt;Query Options-&gt;Results-Text) to Output Format:tab delimited and \u2018<em>Include Column headers in the result set\u2019<\/em> to \u2018<em>no<\/em>\u2019. With these settings we can simply cut and paste the results from SSMS into GnuPlot via PowerShell. Firstly we just sum the petroleum consumption for the whole world aggregated per year.<\/p>\n<pre class=\"theme:powershell-ise lang:ps decode:true\">#first set an alias for gnuplot. I've installed this in the default place\r\nSet-Alias GnuPlot 'C:\\Program Files\\gnuplot\\bin\\gnuplot.exe' -Scope Script\r\n#now we just define where we want to put the files\r\n$gpscriptsPath='PathToMyGnuPlotScripts'\r\n$ScriptName='currentScript.gp'\r\n$PlotPath='PathToMyPlots'\r\n$PlotFilename=\"$gpscriptsPath\\Total.gif\"\r\n\r\n#here is the gnuplot script. note that a dollars sign in the script\r\n#has to be escaped because we want to add PowerShell variables\r\n$TheScript=@\"\r\nset termoption enhanced\r\nset terminal gif font 'Calibri' 12 size 800,600   \r\nset output '$PlotFilename'\r\nsave_encoding = GPVAL_ENCODING\r\nset encoding utf8\r\nset title 'petroleum (annual) consumption' font ',18'\r\nset xlabel 'Year' font ',12'\r\nset ylabel '1000 bbl\/d' font 'arial,12'\r\nset yrange [ 0 : 100000 ]\r\n`$grid &lt;&lt; EOD\r\n1980\t62781.10\r\n1981\t60953.22\r\n1982\t59553.92\r\n1983\t58784.42\r\n1984\t59796.52\r\n1985\t60083.74\r\n1986\t61819.74\r\n1987\t63107.96\r\n1988\t64974.76\r\n1989\t66090.26\r\n1990\t66525.76\r\n1991\t67186.54\r\n1992\t67350.04\r\n1993\t67557.56\r\n1994\t68897.56\r\n1995\t70090.65\r\n1996\t71672.55\r\n1997\t73421.55\r\n1998\t74077.26\r\n1999\t75843.76\r\n2000\t77063.05\r\n2001\t77727.37\r\n2002\t78418.88\r\n2003\t80074.61\r\n2004\t83210.17\r\n2005\t84627.08\r\n2006\t85701.29\r\n2007\t86493.46\r\n2008\t85642.56\r\n2009\t85580.92\r\n2010\t89173.90\r\n2011\t89882.73\r\n2012\t91091.43\r\n2013\t92314.09\r\n2014\t93599.79\r\nEOD\r\nplot '`$grid' using 1:2 with boxes title ''\r\n\"@\r\n#we are using UTF8- usually a good idea with these applications.\r\n[System.IO.File]::WriteAllLines(\"$gpscriptsPath\\$ScriptName\",$TheScript, (New-Object System.Text.UTF8Encoding $False))\r\n#now we simply execute it and admire the gif file containing the plot\r\ngnuplot \"$gpscriptsPath\\$ScriptName\" \r\n\"@\r\n[System.IO.File]::WriteAllLines(\"$gpscriptsPath\\$ScriptName\",$TheScript, (New-Object System.Text.UTF8Encoding $False)) \r\n\r\n<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"600\" class=\"wp-image-70434\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2017\/03\/word-image.gif\" \/><\/p>\n<p>This seems a startling rise when we are all trying to prevent global pollution and climate change. Is this consistent, or are there some nations guzzling petroleum? We therefore go back to our SQL and produce a column for each continent which we can then plot as separate lines to see what is going on. We\u2019ll change to a line graph as well.<\/p>\n<pre class=\"theme:powershell-ise lang:ps decode:true\">Set-Alias GnuPlot 'C:\\Program Files\\gnuplot\\bin\\gnuplot.exe' -Scope Script\r\n$gpscriptsPath='PathToMyGnuPlotScripts'\r\n$ScriptName='currentScript.gp'\r\n$PlotPath='PathToMyPlots'\r\n$PlotFilename=\"$PlotPath\\ByContinent.gif\"\r\n\r\n$TheScript=@\"\r\nset termoption enhanced\r\nset terminal gif font 'Calibri' 12 size 800,600   \r\nset output '$PlotFilename'\r\nsave_encoding = GPVAL_ENCODING\r\nset encoding utf8\r\nset title 'petroleum (annual) consumption' font ',18'\r\nset yrange [0:60000]\r\nset xlabel 'Year' font ',12'\r\nset ylabel '1000 bbl\/d' font 'arial,12'\r\n`$grid &lt;&lt; EOD\r\n1980\t1662.10\t1.00\t12656.80\t24547.90\t20908.30\t724.90\t2633.20\r\n1981\t1796.62\t1.00\t12664.50\t23273.20\t20233.10\t746.42\t2592.38\r\n1982\t1895.92\t1.00\t12597.40\t22846.50\t19264.50\t767.62\t2548.08\r\n1983\t1920.42\t1.00\t12806.00\t22355.40\t18901.80\t740.02\t2414.68\r\n1984\t1991.92\t1.30\t13224.10\t22141.80\t19501.20\t772.42\t2438.28\r\n1985\t2074.42\t1.40\t13414.50\t22120.00\t19557.80\t767.02\t2434.40\r\n1986\t2054.32\t1.30\t13935.30\t22543.50\t20164.10\t779.42\t2666.30\r\n1987\t2083.04\t1.30\t14501.50\t22643.60\t20709.70\t802.42\t2745.90\r\n1988\t2166.34\t1.40\t15406.70\t22720.00\t21413.70\t838.42\t2811.20\r\n1989\t2248.94\t1.30\t16297.50\t22608.10\t21691.10\t874.92\t2784.30\r\n1990\t2343.14\t1.40\t17219.30\t22360.00\t21223.60\t907.42\t2927.10\r\n1991\t2405.82\t1.40\t17793.40\t22498.00\t21048.80\t886.62\t2979.00\r\n1992\t2445.22\t1.40\t19750.60\t20486.00\t21420.00\t903.72\t3107.30\r\n1993\t2471.44\t1.40\t20629.80\t19291.00\t21703.00\t941.92\t3234.30\r\n1994\t2461.64\t1.40\t21672.70\t18719.00\t22366.60\t986.62\t3369.10\r\n1995\t2558.14\t1.50\t22632.30\t18745.20\t22347.29\t1007.52\t3527.30\r\n1996\t2614.74\t1.50\t23474.80\t18599.30\t23019.19\t1026.02\t3729.50\r\n1997\t2672.64\t1.50\t24401.20\t18695.40\t23541.39\t1050.02\t3903.60\r\n1998\t2689.14\t1.50\t24237.90\t18896.40\t23986.30\t1048.92\t4018.70\r\n1999\t2733.24\t1.50\t25228.60\t18689.20\t24794.70\t1076.72\t4085.30\r\n2000\t2838.51\t1.50\t26186.26\t18543.10\t25009.60\t1075.22\t4199.00\r\n2001\t2971.40\t1.50\t26528.65\t18866.50\t25035.90\t1078.12\t4155.82\r\n2002\t3075.38\t1.50\t27172.05\t18828.50\t25111.98\t1109.72\t4053.65\r\n2003\t3112.97\t1.50\t28156.52\t19037.50\t25535.98\t1157.72\t3980.22\r\n2004\t3209.04\t1.50\t29916.38\t19222.60\t26413.78\t1177.92\t4178.91\r\n2005\t3353.84\t1.60\t30727.55\t19188.60\t26545.48\t1205.73\t4373.66\r\n2006\t3355.07\t1.60\t31521.53\t19325.80\t26466.88\t1221.23\t4540.30\r\n2007\t3365.11\t1.60\t32322.05\t19025.90\t26537.20\t1238.03\t4711.59\r\n2008\t3559.53\t1.80\t32607.75\t19136.60\t25202.60\t1233.12\t4696.16\r\n2009\t3705.04\t1.60\t33739.84\t18322.70\t24316.30\t1214.12\t5017.45\r\n2010\t3922.55\t1.60\t35840.87\t18524.00\t24934.20\t1272.62\t5443.19\r\n2011\t3826.26\t0.09\t36884.88\t18356.10\t24735.30\t1297.22\t5534.51\r\n2012\t4026.77\t0.09\t38448.34\t17808.80\t24412.20\t1325.22\t5827.02\r\n2013\t4205.69\t0.09\t39172.13\t17582.00\t24846.60\t1375.56\t5887.85\r\n2014\t4406.60\t0.09\t39917.67\t17730.40\t24907.50\t1377.16\t6043.18\r\nEOD\r\nplot '`$grid' using 1:2 with lines title 'Africa',\\\r\n     '`$grid' using 1:4 with lines title 'Asia', \\\r\n     '`$grid' using 1:5 with lines title 'Europe', \\\r\n     '`$grid' using 1:6 with lines title 'North America', \\\r\n     '`$grid' using 1:7 with lines title 'Australia', \\\r\n     '`$grid' using 1:8 with lines title 'South America'\r\n\"@\r\n[System.IO.File]::WriteAllLines(\"$gpscriptsPath\\$ScriptName\",$TheScript, (New-Object System.Text.UTF8Encoding $False))\r\n\r\ngnuplot \"$gpscriptsPath\\$ScriptName\"\r\n<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"600\" class=\"wp-image-70435\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2017\/03\/word-image-1.gif\" \/><\/p>\n<p>Basically, the plots seem to illustrate that, while Europe and North America has got its petroleum consumption under control, Asia hasn\u2019t. Our figures aren\u2019t particularly accurate because asia is a very broad grouping, and Russia is considered to be in Europe in the data. (the Urals actually separate the Asian and European sides). As a side-note, petroleum consumption is also considered a sign of industrial economic activity.<\/p>\n<p>At this point, we\u2019d want to investigate the details of the main petroleum consumers to home in on the countries that are increasing their usage fastest. For this, we really need a way of finding the countries who are affecting the overall figurs the most.<\/p>\n<p>If we assume that all countries are increasing, or decreasing their consumption in a linear fashion, then we can filter out the countries with the greatest rise as well as the highest consumers, simply by doing a linear regression in SQL Server.<\/p>\n<p>Our data table is very simple.<\/p>\n<pre class=\"theme:ssms2012-simple-talk lang:tsql decode:true\">CREATE TABLE petroleumAnnualConsumption\r\n    (\r\n    country VARCHAR(40) NOT NULL,\r\n    AnnualConsumption NUMERIC(18, 2) NOT NULL,\r\n    year INT NOT NULL,\r\n    CONSTRAINT CountryYear PRIMARY KEY(country, year)\r\n    )<\/pre>\n<p>..and our first plot data was created by executing \u2026.<\/p>\n<pre class=\"theme:ssms2012-simple-talk lang:tsql decode:true\">SELECT  \r\n      [year],\r\n      SUM(AnnualConsumption)\r\n    FROM dbo.petroleumAnnualConsumption\r\n    WHERE [year] &lt; 2015\r\n    GROUP BY [year]\r\n    ORDER BY [year] <\/pre>\n<p>We can get the intercept, slope, and predicted petroleum consumption for a particular year from a slightly more complicated query that calculates the linear regression. Here we list the predicted top twenty consumers from the data (which is only as far as 2014)<\/p>\n<pre class=\"theme:ssms2012-simple-talk lang:tsql decode:true\">SELECT TOP 20 country, slope,\r\n    (2016 * regression.Slope) + regression.intercept AS prediction\r\n    FROM\r\n      (\r\n      SELECT CONVERT(NUMERIC(18, 2), (SumY - (slope * SumX)) \/ readings) AS intercept,\r\n        CONVERT(NUMERIC(18, 2), slope) AS Slope, Country\r\n        FROM\r\n          (\r\n          SELECT country,\r\n            ((tb.readings * tb.SumXY) - (tb.SumX * tb.SumY))\r\n              \/ (tb.readings * tb.SumX2 - POWER(tb.SumX, 2)) AS slope, tb.SumX,\r\n            tb.SumY, tb.readings\r\n            FROM\r\n              (\r\n              SELECT country, COUNT(*) AS readings, --readings\r\n                CONVERT(NUMERIC(18, 2), SUM(Year)) AS SumX, \r\n                CONVERT(NUMERIC(18, 2), SUM(AnnualConsumption)) AS SumY, \r\n                CONVERT(NUMERIC(18, 2), SUM(AnnualConsumption * year)) AS SumXy, \r\n                CONVERT(NUMERIC(18, 2), SUM(POWER(year, 2))) AS SumX2 \r\n                FROM dbo.petroleumAnnualConsumption\r\n                WHERE AnnualConsumption IS NOT NULL\r\n                GROUP BY country\r\n              ) tb(country, readings, SumX, SumY, SumXY, SumX2)\r\n          )SlopeAndIntercept\r\n      ) regression\r\n    ORDER BY prediction DESC;<\/pre>\n<p>Now that we know who is increasing their consumption most rapidly, and who the most prolific consumers are, we simply generate plots for the most significant fifty petrol consumers. This would be somewhat a trial by the dreaded \u2018point-and-click\u2019 With GnuPlot it is the work of a moment.<\/p>\n<pre class=\"theme:powershell-ise lang:ps decode:true\">#first set an alias for gnuplot. I've installed this in the default place\r\nSet-Alias GnuPlot 'C:\\Program Files\\gnuplot\\bin\\gnuplot.exe' -Scope Script\r\n$Sourceinstance = 'MyServer\\Dancy'\r\n$Sourcedatabase = 'PetroleumConsumption'\r\n\r\n#now we just define where we want to put the files\r\n$PlotPath = 'PathToMyPlots'\r\n$ScriptName = 'currentScript.gp'\r\n\r\n#we now read in a list of nations that are increasing their petroleum consumption rapidly\r\n#or are high consumers of Petroleum\r\nGet-Content \"$PlotPath\\nations.dat\" | foreach {\r\n    #for each of these nations, we query the database, get their data onto file and plot it\r\n    $nation = $_\r\n    $PlotFilename = \"$PlotPath\\$nation.gif\"\r\n    \r\n    try #connecting to the database\r\n    {\r\n        $SourceConnectionString = \"Data Source=$Sourceinstance;Initial Catalog=$Sourcedatabase;Integrated Security=True\"\r\n        $SqlConnection = new-object System.Data.SqlClient.SqlConnection\r\n        $SqlConnection.ConnectionString = $SourceConnectionString\r\n        $SqlCommand = $SqlConnection.CreateCommand()\r\n        #now we query the database\r\n        $SqlCommand.CommandText = @\"\r\nSELECT \r\n\t  petroleumAnnualConsumption.[year],\r\n\t  SUM(dbo.petroleumAnnualConsumption.AnnualConsumption)\r\n  FROM dbo.petroleumAnnualConsumption\r\n    LEFT OUTER JOIN CountryMapping\r\n      ON CountryMapping.countryNameThen = petroleumAnnualConsumption.country\r\n    LEFT OUTER JOIN CountryContinent\r\n      ON CountryContinent.country \r\n\t   = COALESCE(CountryMapping.CurrentName, petroleumAnnualConsumption.country)\r\nWHERE COALESCE(CountryMapping.CurrentName, petroleumAnnualConsumption.country)='$nation'\r\nGROUP BY [year] ORDER BY [year]\r\n\"@\r\n        # We then simply write out the query as a tab-delimited file in UTF\r\n        $DataAdapter = new-object System.Data.SqlClient.SqlDataAdapter $SqlCommand\r\n        $dataset = new-object System.Data.Dataset\r\n        if ($DataAdapter.Fill($dataset) -gt 0)\r\n        {\r\n            $output = $dataSet.Tables.Rows | foreach { [string]::Join(\"`t\", $_.ItemArray) }\r\n        }\r\n        else\r\n        { $output = ''; write-warning 'The query returned no data.' }\r\n        # here we write out the file\r\n        [System.IO.File]::WriteAllLines(\"$PlotPath\\Data.dat\", $output, (New-Object System.Text.UTF8Encoding $False))\r\n        \r\n    }\r\n    catch\r\n    {\r\n        $ex = $_.Exception\r\n        Write-Error \"whilst opening source $Sourceinstance . $Sourcedatabase . $SourceTable : Error'$($_)' in script $($_.InvocationInfo.ScriptName) $($_.InvocationInfo.Line.Trim()) (line $($_.InvocationInfo.ScriptLineNumber)) char $($_.InvocationInfo.OffsetInLine)\"\r\n    }\r\n    \r\n    # here is the gnuplot script. note that a dollars sign in the script\r\n    # has to be escaped because we want to add PowerShell variables\r\n    \r\n    $TheScript =@\"\r\nset termoption enhanced\r\nset terminal gif font 'Calibri' 12 size 800,600   \r\nset output '$PlotFilename'\r\nsave_encoding = GPVAL_ENCODING\r\nset encoding utf8\r\nset title 'petroleum (annual) consumption of $nation' font ',18'\r\nset xlabel 'Year' font ',12'\r\nset yrange [0:]\r\nset ylabel '1000 bbl\/d' font 'arial,12'\r\n\r\nplot '$PlotPath\\Data.dat' using 1:2 with lines title ''\r\n\"@\r\n    #we are using UTF8- usually a good idea with these applications.\r\n    [System.IO.File]::WriteAllLines(\"$gpscriptsPath\\$ScriptName\", $TheScript, (New-Object System.Text.UTF8Encoding $False))\r\n    #now we simply execute it and admire the gif file containing the plot\r\n    gnuplot \"$gpscriptsPath\\$ScriptName\"\r\n} \r\n<\/pre>\n<p>We can now inspect these graphs either by referencing them from a webpage or via a file-viewing application such as Directory Opus. You can also embed them in Word files.<\/p>\n<p>Here is an example of the many plots generated by this routine<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"833\" height=\"629\" class=\"wp-image-70436\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2017\/03\/word-image-20.png\" \/><\/p>\n<h1>Conclusion<\/h1>\n<p>I\u2019ve been as guilty as anyone in the past of clinging to Excel as the only way of doing any sort of graph plotting. It is good for one-off work but if you are doing lots of graphs, and automating their production and update, then the old classic, Gnuplot, is definitely worth considering. I know of nothing else that is so sympathetic with the way that SQL Server exports data, and which runs on the command line, generating bitmap or vector graphics directly, as well as most other formats that you\u2019d want. I recommend it for those occasions such as data-science, performance testing and monitoring, where you need information more than you need fancy presentation. It is valuable for reporting on any automation tasks, and very good for integration tests and other aspects of continuous integration and deployment.<\/p>\n<h1>Further Reading<\/h1>\n<ol style=\"list-style: none;\">\n<li>Gnuplot in Action by Philipp K. Janert (2009). ISBN 978-1933988399.<\/li>\n<li>gnuplot Cookbook by Lee Phillips (2012). ISBN 978-1849517249.<\/li>\n<li>Gnuplot 5.0. by Thomas Williams and Colin Kelley (2015). ISBN 978-988-14436-4-9.<\/li>\n<li><a href=\"https:\/\/en.wikipedia.org\/wiki\/Gnuplot\">Gnuplot on Wikipedia<\/a><\/li>\n<li><a href=\"https:\/\/en.wikibooks.org\/wiki\/Gnuplot\">Gnuplot introduction on Wikimedia<\/a><\/li>\n<li><a href=\"https:\/\/commons.wikimedia.org\/wiki\/Category:Gnuplot_diagrams\">Gnuplot examples on Wikimedia commons<\/a><\/li>\n<li><a href=\"http:\/\/www.gnuplot.info\/docs_4.0\/gpcard.pdf\">Gnuplot Reference Card<\/a><\/li>\n<li><a href=\"https:\/\/commons.wikimedia.org\/wiki\/Category:Images_with_Gnuplot_source_code\">Images of plots with Gnuplot source code<\/a><\/li>\n<li><a href=\"http:\/\/www.gnuplot.info\/documentation.html\">Official Gnuplot Documentation<\/a><\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>When you are automating a number of tasks,  or performing a batch of tests, you want a way of automating the production of your plots and graphs.  Nothing beats a good graphical plot for giving the indications of how the process went.  If you are using PowerShell and maybe also SQL Server, it pays to use a command-line plotting tool such as Gnuplot to do all the hard work.  It  turns out to be handy for a range of data jobs, turning PowerShell into a handy data science tool.&hellip;<\/p>\n","protected":false},"author":154613,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143528,143516],"tags":[],"coauthors":[6813],"class_list":["post-70432","post","type-post","status-publish","format-standard","hentry","category-bi-sql-server","category-database-devops"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/70432","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/154613"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=70432"}],"version-history":[{"count":11,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/70432\/revisions"}],"predecessor-version":[{"id":85586,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/70432\/revisions\/85586"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=70432"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=70432"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=70432"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=70432"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}