Package: matplotcli
MatplotCLICreate matplotlib visualizations from the command-lineMatplotCLI is a simple utility to quickly create plots from the command-line, leveragingMatplotlib.plt"scatter(x,y,5,alpha=0.05); axis('scaled')"<sample.jsonplt"hist(x,30)"<sample.jsonMatplotCLI accepts bothJSON linesand arrays of JSON objects as input.
Look at the recipes section to learn how to handle other formats like CSV.MatplotCLI executes python code (passed as argument) where some handy imports are already done (e.g.from matplotlib.pyplot import *) and where the input JSON data is already parsed and available in variables, making plotting easy. Please refer tomatplotlib.pyplot'sreferenceandtutorialfor comprehensive documentation about the plotting commands.Data from the input JSON is made available in the following way. Given the inputmyfile.json:{"a":1,"b":2}{"a":10,"b":20}{"a":30,"c$d":40}The following variables are made available:data={"a":[1,10,30],"b":[2,20,None],"c_d":[None,None,40]}a=[1,10,30]b=[2,20,None]c_d=[None,None,40]col_names=("a","b","c_d")So, for a scatter plota vs b, you could simply do:plt "scatter(a,b); title('a vs b')" < myfile.jsonNotice that the names of JSON properties are converted into valid Python identifiers whenever they are not (e.g.c$dwas converted intoc_d).Execution flowImport matplotlib and other libs;Read JSON data from standard input;Execute user code;Show the plot.All steps (except step 3) can be skipped through command-line options.InstallationThe easiest way to install MatplotCLI is frompip:pipinstallmatplotcliRecipes and ExamplesPlotting JSON dataMatplotCLI natively supports JSON lines:echo'{"a":0, "b":1}{"a":1, "b":0}{"a":3, "b":3}'|plt"plot(a,b)"and arrays of JSON objects:echo'[{"a":0, "b":1},{"a":1, "b":0},{"a":3, "b":3}]'|plt"plot(a,b)"Plotting from a csvSPyQLis a data querying tool that allows running SQL queries with Python expressions on top of different data formats. Here, SPyQL is reading a CSV file, automatically detecting if there's an header row, the dialect and the data type of each column, and converting the output to JSON lines before handing over to MatplotCLI.catmy.csv|spyql"SELECT * FROM csv TO json"|plt"plot(x,y)"Plotting from a yaml/xml/tomlyqconverts yaml, xml and toml files to json, allowing to easily plot any of these with MatplotCLI.catfile.yaml|yq-c|plt"plot(x,y)"catfile.xml|xq-c|plt"plot(x,y)"catfile.toml|tomlq-c|plt"plot(x,y)"Plotting from a parquet fileparquet-toolsallows dumping a parquet file to JSON format.jq -cmakes sure that the output has 1 JSON object per line before handing over to MatplotCLI.parquet-toolscat--jsonmy.parquet|jq-c|plt"plot(x,y)"Plotting from a databaseDatabases CLIs typically have an option to output query results in CSV format (e.g.psql --csv -c queryfor PostgreSQL,sqlite3 -csv -header file.db queryfor SQLite).Here we are visualizing how much space each namespace is taking in a PostgreSQL database.SPyQLconverts CSV output from the psql client to JSON lines, and makes sure there are no more than 10 items, aggregating the smaller namespaces in anAll otherscategory.
Finally, MatplotCLI makes a pie chart based on the space each namespace is taking.psql-Umyusermydb--csv-c'SELECTN.nspname,sum(pg_relation_size(C.oid))*1e-6 AS size_mbFROM pg_class CLEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)GROUP BY 1ORDER BY 2 DESC'|spyql"SELECTnspname if row_number < 10 else 'All others' as name,sum_agg(size_mb) AS size_mbFROM csvGROUP BY 1TO json"|plt"nice_labels = ['{0}\n{1:,.0f} MB'.format(n,s) for n,s in zip(name,size_mb)];pie(size_mb, labels=nice_labels, autopct='%1.f%%', pctdistance=0.8, rotatelabels=True)"Plotting a functionDisabling reading from stdin and generating the output usingnumpy.plt--no-input"x = np.linspace(-1,1,2000);y = x*np.sin(1/x);plot(x,y);axis('scaled');grid(True)"Saving the plot to an imageSaving the output without showing the interactive window.catsample.json|plt--no-show"hist(x,30);savefig('myimage.png', bbox_inches='tight')"Plot of the global temperatureHere's a complete pipeline from getting the data to transforming and plotting it:Downloading a CSV file withcurl;Skipping the first row withsed;Grabbing the year column and 12 columns with monthly temperatures to an array and converting to JSON lines format usingSPyQL;Exploding the monthly array with SPyQL (resulting in 12 rows per year) while removing invalid monthly measurements;Plotting with MatplotCLI  .curlhttps://data.giss.nasa.gov/gistemp/tabledata_v4/GLB.Ts+dSST.csv|sed1d|spyql"SELECT Year, cols[1:13] AS tempsFROM csvTO json"|spyql"SELECTjson->Year + ((row_number-1)%12)/12 AS year,json->temps AS tempFROM jsonEXPLODE json->tempsWHERE json->temps is not NullTO json"|plt"scatter(year, temp, 2, temp);xlabel('Year');ylabel('Temperature anomaly w.r.t. 1951-80 (ºC)');title('Global surface temperature (land and ocean)')"