JSON 数据的动态 tikz 条形图

JSON 数据的动态 tikz 条形图

我有一个类似这样的 JSON 文件

{
    "data": [
    {
        "type": "SENIOR",
        "male": 350000.0,
        "female": 225000.0
    },
    {
        "type": "ENTRY",
        "male": 100000.0,
        "female": 40000.0
    },
    {
        "type": "MID",
        "male": 225000.0,
        "female": 150000.0
    }
    ]
}

我需要创建一个带有动态 x 字段的条形图,这些字段是从 json 读取的。

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{luacode}
\usepackage{tikz}
\usepackage{pgfplots}
\usepackage{ifthen}

%%%%% Lua code %%%%%%
\begin{luacode}
    local json = require("json")
    local file = io.open("mwe.json")
    tab = json.parse(file:read("*all"))
    file:close()
\end{luacode}

\begin{document}
% Number of labels
\newcommand{\nrlabels}{\directlua{tex.print(table.getn(tab['data']))}}

% Create counter for loop through labels
\newcounter{labelctr}\stepcounter{labelctr}
\newcounter{totallabels}
\setcounter{totallabels}{\nrlabels}\stepcounter{totallabels}
\newcounter{onemorelabel}\setcounter{onemorelabel}{\value{totallabels}}\addtocounter{onemorelabel}{-1}

\begin{tikzpicture}
    \begin{axis}[
        width  = 0.85*\textwidth,
        height = 8cm,
        %major x tick style = transparent,
        ybar=2*\pgflinewidth,
        bar width=20pt,
        %ymajorgrids = true,
        ylabel = {Average Wage},
        %symbolic x coords= {\whiledo{\value{labelctr} < \value{totallabels}}{\directlua{tex.print(tab['data'][\thelabelctr]['type'])}\ifthenelse{\value{labelctr}<\value{onemorelabel}}{,}{}\stepcounter{labelctr}}}
        symbolic x coords={SENIOR,ENTRY,MID}
        ]
        \addplot[fill=blue] coordinates {\whiledo{\value{labelctr} < \value{totallabels}}{(\directlua{tex.print(tab['data'][\thelabelctr]['type'])}, \directlua{tex.print(tab['data'][\thelabelctr]['male'])}) \stepcounter{labelctr}}};
    \end{axis}
\end{tikzpicture}


\end{document}

这是我目前拥有的。我需要类似的东西在此处输入图片描述

谢谢..

答案1

合并如何绘制 JSON 数据x 坐标中的逗号(间隔)给出下面的 MWE。

这个想法是使用tex.sprint正确的格式将表写入输入流,就好像表数据实际写入文件中一样.tex。然后\pgfplotstableread可以一次读取整个表。

对于绘图,这需要选项xticklabels from tablextick=data。每个类别都有一个单独的\addplot命令,并y在表中有相应的索引。

\documentclass{article}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\pgfplotsset{compat=newest}

\begin{document}
%%%%% Lua code %%%%%%
%% This prints the following table to the input stream:
%% type male female
%% SENIOR 350000.0 225000.0
%% ENTRY 100000.0 40000.0
%% MID 225000.0 150000.0

\expandafter\pgfplotstableread\directlua{
    local json = utilities.json.load("groupeddata.json")
    tex.sprint("{\string\r")
    tex.sprint("type male female\string\r")
    for n, row in ipairs(json.data) do
        tex.sprint(row.type .. " " .. row.male .. " " .. row.female .. "\string\r")
    end
    tex.sprint("}")
}\loadedtable

\begin{tikzpicture}
    \begin{axis}[
        width  = 0.85*\textwidth,
        height = 8cm,
        ybar=2*\pgflinewidth,
        area legend,
        bar width=20pt,
        ylabel = {Average Wage},
        xticklabels from table={\loadedtable}{type},
        xtick = data,
        legend pos=north east,
        ]
        \addplot table[x expr=\coordindex,y index=1] {\loadedtable};
        \addplot table[x expr=\coordindex,y index=2] {\loadedtable};
        \legend{male,female}
    \end{axis}
\end{tikzpicture}

\end{document}

在此处输入图片描述


请注意,有些内容仍是硬编码的,即表中的列标题、数据行中的字段名称、类别数(带有关联y值)和图例。标题实际上不是必需的(的类别列xticklabels也可以通过索引引用),但这需要选项,header=false\pgfplotstableread会使情况\expandafter更加复杂。循环 json 数组可能可以在 Lua 代码中推广,但对于这个概念验证答案,我没有研究这一点。最后是单独的语句\addplot table和图例,可以使用来完成\foreach。参见使用表格的第一行作为 pgfplot 图中的图例条目?有关上述评论的一些例子。

相关内容