Wolfram 语言

更丰富的知识库访问

可视化每日参考营养值

Wolfram Knowledgebase 中不但包括了超过 37,000 种 "Food" 和 1,000 种 "FoodType" 相关详细属性和营养成分信息,还有关于 175 种营养的每日参考值数据. 这些大量数据的一同使用可以计算探索几乎任意膳食的营养成分,并使用简单绘图进行直观可视化.

In[1]:=
Click for copyable input
EntityValue["Nutrient", "EntityCount"]
Out[1]=

按照 2000 卡/天的饮食提取每日参考营养值的列表.

In[2]:=
Click for copyable input
allDailyValues = Append[DeleteMissing[ EntityValue["Nutrient", "DailyValue", "EntityAssociation"]], Entity["Nutrient", "Energy"] -> Quantity[2000, ("LargeCalories")/("Days")]]*Quantity[1, "Days"]
Out[2]=

将食品属性映射到营养成分.

In[3]:=
Click for copyable input
propertyNutrientRules = {EntityProperty["Food", "AbsoluteSodiumContent"] -> Entity["Nutrient", "Sodium"], EntityProperty["Food", "AbsoluteTotalCarbohydratesContent"] -> Entity["Nutrient", "TotalCarbohydrates"], EntityProperty["Food", "AbsoluteTotalFatContent"] -> Entity["Nutrient", "TotalFat"], EntityProperty["Food", "AbsoluteTotalFiberContent"] -> Entity["Nutrient", "DietaryFiber"], EntityProperty["Food", "AbsoluteIronContent"] -> Entity["Nutrient", "Iron"], EntityProperty["Food", "AbsoluteTotalCaloriesContent"] -> Entity["Nutrient", "Energy"]};

EntityGroupEntityInstance 将典型的早餐编码.

In[4]:=
Click for copyable input
breakfast = EntityGroup[{ EntityInstance[Entity[ "Food", { EntityProperty["Food", "CookingMethod"] -> Entity[ "CookingMethod", "HardBoiled"], EntityProperty["Food", "FoodType"] -> ContainsExactly[{ Entity["FoodType", "Egg"]}], EntityProperty[ "Food", "AddedFoodTypes"] -> ContainsExactly[{}]}], Quantity[2, "Servings"]], EntityInstance[Entity[ "Food", {EntityProperty["Food", "FoodType"] -> ContainsExactly[{ Entity["FoodType", "Bacon"]}], EntityProperty[ "Food", "AddedFoodTypes"] -> ContainsExactly[{}]}], Quantity[3, "Slices"]], EntityInstance[Entity[ "Food", {EntityProperty["Food", "FoodType"] -> ContainsExactly[{ Entity["FoodType", "HashBrown"]}], EntityProperty[ "Food", "AddedFoodTypes"] -> ContainsExactly[{}]}], Quantity[1, "Servings"]], EntityInstance[Entity[ "Food", {EntityProperty["Food", "FoodType"] -> ContainsExactly[{ Entity["FoodType", "OrangeJuice"]}], EntityProperty[ "Food", "AddedFoodTypes"] -> ContainsExactly[{}]}], Quantity[2, "Servings"]] }];

创建一个 罗盘图,显示有放射状嵌套的六边形,表明六种主要营养的每日建议值的 50%、100%(用绿色表示)和 150%.

显示完整的 Wolfram 语言输入
In[5]:=
Click for copyable input
breakfast = EntityGroup[{ EntityInstance[Entity[ "Food", { EntityProperty["Food", "CookingMethod"] -> Entity[ "CookingMethod", "HardBoiled"], EntityProperty["Food", "FoodType"] -> ContainsExactly[{ Entity["FoodType", "Egg"]}], EntityProperty[ "Food", "AddedFoodTypes"] -> ContainsExactly[{}]}], Quantity[2, "Servings"]], EntityInstance[Entity[ "Food", {EntityProperty["Food", "FoodType"] -> ContainsExactly[{ Entity["FoodType", "Bacon"]}], EntityProperty[ "Food", "AddedFoodTypes"] -> ContainsExactly[{}]}], Quantity[3, "Slices"]], EntityInstance[Entity[ "Food", {EntityProperty["Food", "FoodType"] -> ContainsExactly[{ Entity["FoodType", "HashBrown"]}], EntityProperty[ "Food", "AddedFoodTypes"] -> ContainsExactly[{}]}], Quantity[1, "Servings"]], EntityInstance[Entity[ "Food", {EntityProperty["Food", "FoodType"] -> ContainsExactly[{ Entity["FoodType", "OrangeJuice"]}], EntityProperty[ "Food", "AddedFoodTypes"] -> ContainsExactly[{}]}], Quantity[2, "Servings"]] }];; compassPlot[ent : _EntityGroup | {__EntityGroup}, opts : OptionsPattern[Graphics]] := Module[{data, n, circlePoints, dailyValues, scaledData, coordinates, fillStyle, opacityStyle, pointStyle, labelCoordPairs, missingPositions, rMax}, (* Get data, total up nutrients *) data = EntityValue[ Replace[ent, eg_EntityGroup :> {eg}], {EntityProperty["Food", "AbsoluteTotalCarbohydratesContent"], EntityProperty["Food", "AbsoluteTotalFatContent"], EntityProperty["Food", "AbsoluteSodiumContent"], EntityProperty["Food", "AbsoluteTotalFiberContent"], EntityProperty["Food", "AbsoluteIronContent"], EntityProperty["Food", "AbsoluteTotalCaloriesContent"]}, "PropertyAssociation" ]; data = Merge[data, Total]; (* Get DailyValues, scale data to DailyValues *) dailyValues = Keys[data] /. propertyNutrientRules /. allDailyValues; scaledData = 100*AssociationThread[ Keys[data], (Values[data]/dailyValues) /. {_Missing -> Quantity[0, "Grams"]}]; (* Compute the coordinates for each of the points *) n = Length[data]; circlePoints = CirclePoints[n]; missingPositions = Cases[MapIndexed[If[Not[FreeQ[#, _Missing]], #2] &, Values[data]], _Integer, Infinity]; coordinates = Normal@AssociationThread[Keys[scaledData], circlePoints*Values[scaledData]]; (* Precompute the label-coordinate pairs *) labelCoordPairs = Thread[Keys[data] -> circlePoints] /. {_Missing -> Quantity[0, "Grams"]}; fillStyle = Opacity[0.5, Black]; opacityStyle = Opacity[0.01, Black]; pointStyle = Blue; rMax = 150; (* Create the plot *) Graphics[{ (* Add lines from the center outwards to indicate "axes" for the \ nutrients *) {Thin, Opacity[0.75], Gray, Dashed, Line[{{0, 0}, #}]} & /@ (rMax*circlePoints), (* For each position, draw a triangle and a line (taking missing values into account) *) MapIndexed[ With[{currentPosition = First[#2], nextPosition = Replace[First[#2] + 1, (n + 1) -> 1]}, { (* For each position, draw a triangle (origin -> point -> next point) *) { fillStyle, EdgeForm[], Polygon[ {{0, 0}, coordinates[[currentPosition, 2]], coordinates[[nextPosition, 2]]}, VertexColors -> { fillStyle, If[MemberQ[missingPositions, currentPosition], opacityStyle, fillStyle], If[MemberQ[missingPositions, nextPosition], opacityStyle, fillStyle] } ] // If[MemberQ[missingPositions, nextPosition | currentPosition], Tooltip[#, Missing["NotAvailable"]] &, Identity] }, (* Connect two points if neither of them are missing data *) If[ FreeQ[missingPositions, nextPosition | currentPosition], {Thickness[0.0033], Gray, Line[{coordinates[[currentPosition, 2]], coordinates[[nextPosition, 2]]}]} ] } ] &, coordinates[[;; -1, -1]]], (* For each non-missing position, put a small point *) { pointStyle, PointSize[0.0100], Tooltip[Point[coordinates[[#, 2]]], Grid[{{ToString[ Round[100*(data[[#]]/dailyValues[[#]]), 0.1]] <> " %", "", coordinates[[#, 1]]}, {data[[#]], "of", dailyValues[[#]]}}]] } & /@ Complement[Range[n], Flatten[missingPositions]], (* Radially nested polygons to indicate 50%, 100%, 150%, etc... of DV *) Table[ {Thin, Opacity[0.75], Sequence @@ If[r === 100, {Thick, Darker@Green}, {Gray, Dashed}], Tooltip[Line[r*Join[circlePoints, circlePoints[[;; 1]]]], ToString[r] <> "%"]}, {r, 50, rMax, 50}], (* Label the axes afterwards so that they aren't covered/ unreadable *) {Text[ Style[StringTrim@ StringReplace[ EntityValue[#1, "Description"], ("absolute" | "content") -> ""]], (rMax*1.175)*#2]} & @@@ labelCoordPairs }, opts ] ]
In[6]:=
Click for copyable input
compassPlot[breakfast]
Out[6]=

在早餐的基础上设定午餐和晚餐.

In[7]:=
Click for copyable input
lunch = EntityGroup[{ EntityInstance[Entity[ "Food", {EntityProperty["Food", "FoodType"] -> ContainsExactly[{ Entity["FoodType", "PeanutButter"]}], EntityProperty[ "Food", "AddedFoodTypes"] -> ContainsExactly[{}]}], Quantity[2, "Tablespoons"]], EntityInstance[Entity[ "Food", {EntityProperty["Food", "FoodType"] -> ContainsExactly[{ Entity["FoodType", "Bread"]}], EntityProperty[ "Food", "AddedFoodTypes"] -> ContainsExactly[{}]}], Quantity[2, "Slices"]], EntityInstance[Entity[ "Food", {EntityProperty["Food", "FoodType"] -> ContainsExactly[{ Entity["FoodType", "Jelly"]}], EntityProperty[ "Food", "AddedFoodTypes"] -> ContainsExactly[{}]}], Quantity[1, "Servings"]] }];
In[8]:=
Click for copyable input
dinner = EntityGroup[{ EntityInstance[Entity[ "Food", {EntityProperty["Food", "FoodType"] -> ContainsExactly[{ Entity["FoodType", "Spaghetti"]}], EntityProperty[ "Food", "AddedFoodTypes"] -> ContainsExactly[{}]}], Quantity[1, "Servings"]], EntityInstance[Entity[ "Food", {EntityProperty["Food", "FoodType"] -> ContainsExactly[{ Entity["FoodType", "Meatball"]}], EntityProperty[ "Food", "AddedFoodTypes"] -> ContainsExactly[{}]}], Quantity[3, "Items"]], EntityInstance[Entity[ "Food", { EntityProperty["Food", "BrandName"] -> Entity[ "FoodBrandName", "Bertolli"], EntityProperty["Food", "FoodType"] -> ContainsExactly[{ Entity["FoodType", "Sauce"]}], EntityProperty[ "Food", "AddedFoodTypes"] -> ContainsExactly[{}]}], Quantity[1.5, "Servings"]], EntityInstance[Entity[ "Food", { EntityProperty["Food", "Flavor"] -> Entity[ "FoodFlavor", "Cola"], EntityProperty["Food", "FoodType"] -> ContainsExactly[{ Entity["FoodType", "CarbonatedBeverage"]}], EntityProperty[ "Food", "AddedFoodTypes"] -> ContainsExactly[{}]}], Quantity[1, "USSodaCanVolumes"]] }];

可视化每餐之后的营养增加.

显示完整的 Wolfram 语言输入
In[9]:=
Click for copyable input
Grid[Partition[ MapThread[ compassPlot[#1, PlotLabel -> #2] &, {Rest[ FoldList[ Append, {}, {breakfast, lunch, dinner}]], {"After Breakfast", "After Lunch", "After Dinner"}}], UpTo[2]]]
Out[9]=

相关范例

de en es ja ko pt-br ru