1"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[970],{787(e,t,a){a.d(t,{A:()=>n});const n=a.p+"assets/images/metric_summary_example-03d847fc224619f6c70f0a2853260eb8.png"},1295(e,t,a){a.d(t,{z:()=>o});var n=a(96540),i=a(53259),r=a.n(i),s=(a(78478),a(74848)),l=r()({loader:function(){return a.e(1236).then(a.bind(a,91236))},loading:function(e){return e.timedOut?(0,s.jsx)("blockquote",{children:"Error: Loading Plotly timed out."}):(0,s.jsx)("div",{children:"loading..."})},timeout:1e4}),o=n.memo(function(e){var t=e.data;return(0,s.jsx)("div",{className:"plotly-figure",style:{"overflow-x":"auto"},children:(0,s.jsx)(l,{data:t.data,layout:t.layout})})})},6126(e,t,a){a.d(t,{A:()=>n});const n=a.p+"assets/images/slice_plot_example-492c22aceb223ecbcacfa2a5d71c0eb3.png"},7877(e,t,a){a.d(t,{A:()=>r});a(96540);var n=a(29068),i=a(74848);const r=function(e){return(0,i.jsx)(n.A,{language:"python",title:"Output:",children:e.children})}},12215(e,t,a){a.d(t,{A:()=>n});const n=a.p+"assets/images/parallel_coordinates_example-379e6894e11b4375a4d88ea6fa499042.png"},13988(e,t,a){a.d(t,{A:()=>n});const n=a.p+"assets/images/search_space_summary_example-a81743b5ddff89283a353c04ddc785a3.png"},17278(e,t,a){a.d(t,{A:()=>n});const n=a.p+"assets/images/scatter_plot_example-1dc4993a55f6706c868794060f0032af.png"},17389(e){e.exports=JSON.parse('{"data":[{"hovertemplate":"status=%{x}<br>count=%{y}<extra></extra>","legendgroup":"","marker":{"color":"#636efa","pattern":{"shape":""}},"name":"","orientation":"v","showlegend":false,"textposition":"auto","type":"bar","x":["FAILED","COMPLETED","ABANDONED"],"xaxis":"x","y":{"bdata":"MzMzMzMzwz+amZmZmZnpP5qZmZmZmak/","dtype":"f8"},"yaxis":"y"}],"layout":{"barmode":"relative","legend":{"tracegroupgap":0},"margin":{"t":60},"template":{"data":{"bar":[{"error_x":{"color":"#2a3f5f"},"error_y":{"color":"#2a3f5f"},"marker":{"line":{"color":"#E5ECF6","width":0.5},"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"bar"}],"barpolar":[{"marker":{"line":{"color":"#E5ECF6","width":0.5},"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"barpolar"}],"carpet":[{"aaxis":{"endlinecolor":"#2a3f5f","gridcolor":"white","linecolor":"white","minorgridcolor":"white","startlinecolor":"#2a3f5f"},"baxis":{"endlinecolor":"#2a3f5f","gridcolor":"white","linecolor":"white","minorgridcolor":"white","startlinecolor":"#2a3f5f"},"type":"carpet"}],"choropleth":[{"colorbar":{"outlinewidth":0,"ticks":""},"type":"choropleth"}],"contour":[{"colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1,"#f0f921"]],"type":"contour"}],"contourcarpet":[{"colorbar":{"outlinewidth":0,"ticks":""},"type":"contourcarpet"}],"heatmap":[{"colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1,"#f0f921"]],"type":"heatmap"}],"histogram":[{"marker":{"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"histogram"}],"histogram2d":[{"colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1,"#f0f921"]],"type":"histogram2d"}],"histogram2dcontour":[{"colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1,"#f0f921"]],"type":"histogram2dcontour"}],"mesh3d":[{"colorbar":{"outlinewidth":0,"ticks":""},"type":"mesh3d"}],"parcoords":[{"line":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"parcoords"}],"pie":[{"automargin":true,"type":"pie"}],"scatter":[{"fillpattern":{"fillmode":"overlay","size":10,"solidity":0.2},"type":"scatter"}],"scatter3d":[{"line":{"colorbar":{"outlinewidth":0,"ticks":""}},"marker":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"scatter3d"}],"scattercarpet":[{"marker":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"scattercarpet"}],"scattergeo":[{"marker":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"scattergeo"}],"scattergl":[{"marker":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"scattergl"}],"scattermap":[{"marker":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"scattermap"}],"scatterpolar":[{"marker":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"scatterpolar"}],"scatterpolargl":[{"marker":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"scatterpolargl"}],"scatterternary":[{"marker":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"scatterternary"}],"surface":[{"colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1,"#f0f921"]],"type":"surface"}],"table":[{"cells":{"fill":{"color":"#EBF0F8"},"line":{"color":"white"}},"header":{"fill":{"color":"#C8D4E3"},"line":{"color":"white"}},"type":"table"}]},"layout":{"annotationdefaults":{"arrowcolor":"#2a3f5f","arrowhead":0,"arrowwidth":1},"autotypenumbers":"strict","coloraxis":{"colorbar":{"outlinewidth":0,"ticks":""}},"colorscale":{"diverging":[[0,"#8e0152"],[0.1,"#c51b7d"],[0.2,"#de77ae"],[0.3,"#f1b6da"],[0.4,"#fde0ef"],[0.5,"#f7f7f7"],[0.6,"#e6f5d0"],[0.7,"#b8e186"],[0.8,"#7fbc41"],[0.9,"#4d9221"],[1,"#276419"]],"sequential":[[0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1,"#f0f921"]],"sequentialminus":[[0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1,"#f0f921"]]},"colorway":["#636efa","#EF553B","#00cc96","#ab63fa","#FFA15A","#19d3f3","#FF6692","#B6E880","#FF97FF","#FECB52"],"font":{"color":"#2a3f5f"},"geo":{"bgcolor":"white","lakecolor":"white","landcolor":"#E5ECF6","showlakes":true,"showland":true,"subunitcolor":"white"},"hoverlabel":{"align":"left"},"hovermode":"closest","paper_bgcolor":"white","plot_bgcolor":"#E5ECF6","polar":{"angularaxis":{"gridcolor":"white","linecolor":"white","t
1icks":""},"bgcolor":"#E5ECF6","radialaxis":{"gridcolor":"white","linecolor":"white","ticks":""}},"scene":{"xaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","gridwidth":2,"linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white"},"yaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","gridwidth":2,"linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white"},"zaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","gridwidth":2,"linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white"}},"shapedefaults":{"line":{"color":"#2a3f5f"}},"ternary":{"aaxis":{"gridcolor":"white","linecolor":"white","ticks":""},"baxis":{"gridcolor":"white","linecolor":"white","ticks":""},"bgcolor":"#E5ECF6","caxis":{"gridcolor":"white","linecolor":"white","ticks":""}},"title":{"x":0.05},"xaxis":{"automargin":true,"gridcolor":"white","linecolor":"white","ticks":"","title":{"standoff":15},"zerolinecolor":"white","zerolinewidth":2},"yaxis":{"automargin":true,"gridcolor":"white","linecolor":"white","ticks":"","title":{"standoff":15},"zerolinecolor":"white","zerolinewidth":2}}},"xaxis":{"anchor":"y","domain":[0,1],"title":{"text":"status"}},"yaxis":{"anchor":"x","domain":[0,1],"title":{"text":"count"}}}}')},23915(e,t,a){a.d(t,{A:()=>n});const n=a.p+"assets/images/summary_analysis_example-b92ac0aa0ab5a2d239f1254185072d08.png"},28453(e,t,a){a.d(t,{R:()=>s,x:()=>l});var n=a(96540);const i={},r=n.createContext(i);function s(e){const t=n.useContext(r);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),n.createElement(r.Provider,{value:t},e.children)}},34073(e,t,a){a.r(t),a.d(t,{assets:()=>h,contentTitle:()=>d,default:()=>m,frontMatter:()=>c,metadata:()=>n,toc:()=>p});const n=JSON.parse('{"id":"tutorials/analyses/index","title":"Utilizing and Creating Ax Analyses","description":"<LinkButtons","source":"@site/../docs/tutorials/analyses/index.mdx","sourceDirName":"tutorials/analyses","slug":"/tutorials/analyses/","permalink":"/docs/next/tutorials/analyses/","draft":false,"unlisted":false,"tags":[],"version":"current","lastUpdatedBy":null,"lastUpdatedAt":null,"frontMatter":{"title":"Utilizing and Creating Ax Analyses","sidebar_label":"Utilizing and Creating Ax Analyses"},"sidebar":"tutorials","previous":{"title":"Using external methods for candidate generation in Ax","permalink":"/docs/next/tutorials/external_generation_node/"},"next":{"title":"Simple and interpretable arms with BONSAI.","permalink":"/docs/next/tutorials/bonsai/"}}');var i=a(74848),r=a(28453),s=a(38987),l=a(7877),o=a(1295);const c={title:"Utilizing and Creating Ax Analyses",sidebar_label:"Utilizing and Creating Ax Analyses"},d="Utilizing and Creating Ax Analyses",h={},p=[{value:"Using Analyses",id:"using-analyses",level:2},{value:"Creating a new Analysis",id:"creating-a-new-analysis",level:2},{value:"Adding options to an Analysis",id:"adding-options-to-an-analysis",level:2},{value:"Plotly Analyses",id:"plotly-analyses",level:2},{value:"Example Analyses in Ax",id:"example-analyses-in-ax",level:2},{value:"Miscellaneous tips",id:"miscellaneous-tips",level:2}];function x(e){const t={blockquote:"blockquote",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(s.A,{githubUrl:"https://github.com/facebook/ax/blob/main/tutorials/analyses/analyses.ipynb",colabUrl:"https://colab.research.google.com/github/facebook/ax/blob/main/tutorials/analyses/analyses.ipynb"}),"\n",(0,i.jsxs)(t.blockquote,{children:["\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"\u26a0 INFO \u26a0"})}),"\n",(0,i.jsx)(t.p,{children:"This document discusses non-API components of Ax, which may be subject to backwards\ncompatibility breaking changes between major library versions."}),"\n"]}),"\n",(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"utilizing-and-creating-ax-analyses",children:"Utilizing and Creating Ax Analyses"})}),"\n",(0,i.jsxs)(t.p,{children:["Ax\u2019s Analysis module provides a framework for producing plots, tables, messages, and\nmore to help users understand their experiments. This is facilitated via the ",(0,i.jsx)(t.code,{children:"Analysis"}),"\nprotocol and its various subclasses."]}),"\n",(0,i.jsxs)(t.p,{children:["Analysis classes implement a method ",(0,i.jsx)(t.code,{children:"compute"})," which consumes an ",(0,i.jsx)(t.code,{children:"Experiment"}),",\n",(0,i.jsx)(t.code,{children:"GenerationStrategy"}),", and/or ",(0,i.jsx)(t.code,{children:"Adapter"})," and outputs an ",(0,i.jsx)(t.code,{children:"AnalysisCardBase"}),". This can\neither be an ",(0,i.jsx)(t.code,{children:"AnalysisCard"}),", which contains a dataframe with relevant data, a \u201cblob\u201d\nwhich contains data to be rendered (ex. a plot), and miscellaneous metadata like a title\nand subt
1itle. It could also be an ",(0,i.jsx)(t.code,{children:"AnalysisCardGroup"})," which contains a name and list of\nchildren ",(0,i.jsx)(t.code,{children:"AnalyisCardBase"})," -- this allows cards to exist within nested groups as is\nrelevant. For example: the ",(0,i.jsx)(t.code,{children:"TopSurfacesPlot"})," computes a ",(0,i.jsx)(t.code,{children:"SensitivityAnalysisPlot"})," to\nunderstand which parameters in the search space are most relevent, then produces\n",(0,i.jsx)(t.code,{children:"SlicePlot"}),"s and ",(0,i.jsx)(t.code,{children:"ContourPlot"}),"s for the most important surfaces."]}),"\n",(0,i.jsxs)(t.p,{children:["Importantly Ax is able to save these cards to the database using ",(0,i.jsx)(t.code,{children:"save_analysis_cards"}),",\nallowing for analyses to be pre-computed and displayed at a later time. This is done\nautomatically when ",(0,i.jsx)(t.code,{children:"Client.compute_analyses"})," is called."]}),"\n",(0,i.jsx)(t.h2,{id:"using-analyses",children:"Using Analyses"}),"\n",(0,i.jsxs)(t.p,{children:["The simplest way to use an ",(0,i.jsx)(t.code,{children:"Analysis"})," is to call ",(0,i.jsx)(t.code,{children:"Client.compute_analyses"}),". This will\nheuristically select the most relevant analyses to compute, save the cards to the\ndatabase, return them, and display them in your IPython environment if possible. Users\ncan also specify which analyses to compute and pass them in manually, for example:\n",(0,i.jsx)(t.code,{children:"client.compute_analyses(analyses=[TopSurfacesPlot(), Summary(), ...])"}),"."]}),"\n",(0,i.jsxs)(t.p,{children:["When developing a new ",(0,i.jsx)(t.code,{children:"Analysis"}),' it can be useful to compute an analysis "a-la carte".\nTo do this, manually instantiate the ',(0,i.jsx)(t.code,{children:"Analysis"})," and call its ",(0,i.jsx)(t.code,{children:"compute"})," method. This will\nreturn a collection of ",(0,i.jsx)(t.code,{children:"AnalysisCards"})," which can be displayed."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-python",children:'from ax.api.client import Client\nfrom ax.api.configs import RangeParameterConfig\n\n# Create a Client and populate it with some data\nclient = Client()\nclient.configure_experiment(\n name="booth_function",\n parameters=[\n RangeParameterConfig(\n name="x1",\n bounds=(-10.0, 10.0),\n parameter_type="float",\n ),\n RangeParameterConfig(\n name="x2",\n bounds=(-10.0, 10.0),\n parameter_type="float",\n ),\n ],\n)\nclient.configure_optimization(objective="-1 * booth")\n\nfor _ in range(10):\n for trial_index, parameters in client.get_next_trials(max_trials=1).items():\n client.complete_trial(\n trial_index=trial_index,\n raw_data={\n "booth": (parameters["x1"] + 2 * parameters["x2"] - 7) ** 2\n + (2 * parameters["x1"] + parameters["x2"] - 5) ** 2\n },\n )\n'})}),"\n",(0,i.jsx)(l.A,{children:"[INFO 09-24 05:12:50] ax.storage.sqa_store.with_db_settings_base: Ax SQL storage initialized with SQLAlchemy 1.4.17\n[INFO 09-24 05:12:51] ax.api.client: GenerationStrategy(name='Center+Sobol+MBM:fast', nodes=[CenterGenerationNode(next_node_name='Sobol', use_existing_trials_for_initialization=True), GenerationNode(name='Sobol', generator_specs=[GeneratorSpec(generator_enum=Sobol, generator_key_override=None)], transition_criteria=[MinTrials(transition_to='MBM'), MinTrials(transition_to='MBM')], suggested_experiment_status=ExperimentStatus.INITIALIZATION, pausing_criteria=[MaxTrialsAwaitingData(threshold=5)]), GenerationNode(name='MBM', generator_specs=[GeneratorSpec(generator_enum=BoTorch, generator_key_override=None)], transition_criteria=None, suggested_experiment_status=ExperimentStatus.OPTIMIZATION, pausing_criteria=None)]) chosen based on user input and problem structure.\n[INFO 09-24 05:12:51] ax.api.client: Generated new trial 0 with parameters {'x1': 0.0, 'x2': 0.0} using GenerationNode CenterOfSearchSpace.\n[INFO 09-24 05:12:51] ax.api.client: Trial 0 marked COMPLETED.\n[INFO 09-24 05:12:51] ax.api.client: Generated new trial 1 with parameters {'x1': 6.572685, 'x2': -0.298538} using GenerationNode Sobol.\n[INFO 09-24 05:12:51] ax.api.client: Trial 1 marked COMPLETED.\n[INFO 09-24 05:12:51] ax.api.client: Generated new trial 2 with parameters {'x1': -3.558488, 'x2': 0.455847} using GenerationNode Sobol.\n[INFO 09-24 05:12:51] ax.api.client: Trial 2 marked COMPLETED.\n[INFO 09-24 05:12:51] ax.api.client: Generated new trial 3 with parameters {'x1': -7.427622, 'x2': -8.137527} using GenerationNode Sobol.\n[INFO 09-24 05:12:51] ax.api.client: Trial 3 marked COMPLETED.\n[INFO 09-24 05:12:51] ax.api.client: Generated new trial 4 with parameters {'x1': 3.027335, 'x2': 8.608088} using GenerationNode Sobol.\n[INFO 09-24 05:12:51] ax.api.client: Trial 4 marked COMPLETED.\n[INFO 09-24 05:12:51] ax.api.client: Generated new trial 5 with parameters {'x1': 3.376422, 'x2': 0.058566} using GenerationNode MBM.\n[INFO 09-24 05:12:51] ax.api.client: Trial 5 marked COMPLETED.\n[INFO 09-24 05:12:52] ax.api.client: Generated new trial 6 with parameters {'x1': 4.073497, 'x2': -3.285828} using GenerationNode MBM.\n[INFO 09-24 05:12:52] ax.api.client: Trial 6 marked COMPLETED.\n[INFO 09-24 05:12:52] ax.api.client: Generated new trial 7 with parameters {'x1': 3.323742, 'x2': 1.246521} using GenerationNode MBM.\n[INFO 09-24 05:12:52] ax.api.client: Trial 7 marked COMPLETED.\n[INFO 09-24 05:12:52] ax.api.client: Generated new trial 8 with parameters {'x1': -10.0, 'x2': 10.0} using GenerationNode MBM.\n[INFO 09-24 05:12:52] ax.api.client: Trial 8 marked COMPLETED.\n[INFO 09-24 05:12:53] ax.api.client: Generated new trial 9 with parameters {'x1': 10.0, 'x2': -10.0} using GenerationNode MBM.\n[INFO 09-24 05:12:53] ax.api.client: Trial 9 marked COMPLETED."}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-python",children:"from ax.analysis.plotly.parallel_coordinates import ParallelCoordinatesPlot\n\nanalysis
1= ParallelCoordinatesPlot()\n\nanalysis.compute(\n experiment=client._experiment,\n generation_strategy=client._generation_strategy,\n # compute can optionally take in an Adapter directly instead of a GenerationStrategy\n adapter=None,\n)\n"})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Parallel Coordinates for booth"})}),"\n",(0,i.jsx)(t.p,{children:"The parallel coordinates plot displays multi-dimensional data by representing each\nparameter as a parallel axis. This plot helps in assessing how thoroughly the search\nspace has been explored and in identifying patterns or clusterings associated with\nhigh-performing (good) or low-performing (bad) arms. By tracing lines across the axes,\none can observe correlations and interactions between parameters, gaining insights into\nthe relationships that contribute to the success or failure of different configurations\nwithin the experiment."}),"\n",(0,i.jsx)(o.z,{data:a(98186)}),"\n",(0,i.jsx)(t.h2,{id:"creating-a-new-analysis",children:"Creating a new Analysis"}),"\n",(0,i.jsxs)(t.p,{children:["Let's implement a simple Analysis that returns a table counting the number of trials in\neach ",(0,i.jsx)(t.code,{children:"TrialStatus"})," . We'll make a new class that implements the ",(0,i.jsx)(t.code,{children:"Analysis"})," protocol\n(i.e. it defines a ",(0,i.jsx)(t.code,{children:"compute"})," method)."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-python",children:'import random\nfrom typing import Sequence\n\nimport pandas as pd\n\nfrom ax.analysis.analysis import (\n Analysis,\n AnalysisCard,\n)\n\nfrom ax.core.experiment import Experiment\nfrom ax.generation_strategy.generation_strategy import GenerationStrategy\nfrom ax.adapter.base import Adapter\n\n\nclass TrialStatusTable(Analysis):\n def compute(\n self,\n experiment: Experiment | None = None,\n generation_strategy: GenerationStrategy | None = None,\n adapter: Adapter | None = None,\n ) -> AnalysisCard:\n trials_by_status = experiment.trials_by_status\n\n records = [\n {"status": status.name, "count": len(trials)}\n for status, trials in trials_by_status.items()\n if len(trials) > 0\n ]\n\n return self._create_analysis_card(\n title="Trials by Status",\n subtitle="How many trials are in each status?",\n df=pd.DataFrame.from_records(records),\n )\n\n\n# Let\'s add some more trials of miscellaneous statuses before computing the new Analysis\nfor _ in range(10):\n for trial_index, parameters in client.get_next_trials(max_trials=1).items():\n roll = random.random()\n\n if roll < 0.2:\n client.mark_trial_failed(trial_index=trial_index)\n elif roll < 0.5:\n client.mark_trial_abandoned(trial_index=trial_index)\n else:\n client.complete_trial(\n trial_index=trial_index,\n raw_data={\n "booth": (parameters["x1"] + 2 * parameters["x2"] - 7) ** 2\n + (2 * parameters["x1"] + parameters["x2"] - 5) ** 2\n },\n )\n\n# Client.compute_analyses will display cards individually if display=True\ncard = client.compute_analyses(analyses=[TrialStatusTable()], display=True)\n'})}),"\n",(0,i.jsx)(l.A,{children:"[INFO 09-24 05:12:55] ax.api.client: Generated new trial 10 with parameters {'x1': 3.251964, 'x2': 0.659769} using GenerationNode MBM.\n[INFO 09-24 05:12:55] ax.api.client: Trial 10 marked FAILED.\n[INFO 09-24 05:12:55] ax.api.client: Generated new trial 11 with parameters {'x1': 3.278162, 'x2': 0.653157} using GenerationNode MBM.\n[INFO 09-24 05:12:55] ax.api.client: Trial 11 marked FAILED.\n[INFO 09-24 05:12:55] ax.api.client: Generated new trial 12 with parameters {'x1': 3.24162, 'x2': 0.663184} using GenerationNode MBM.\n[INFO 09-24 05:12:55] ax.api.client: Trial 12 marked ABANDONED. ABANDONED trials are not able to be re-suggested by get_next_trials.\n[INFO 09-24 05:12:56] ax.api.client: Generated new trial 13 with parameters {'x1': 10.0, 'x2': 5.199227} using GenerationNode MBM.\n[INFO 09-24 05:12:56] ax.api.client: Trial 13 marked COMPLETED.\n[INFO 09-24 05:12:56] ax.api.client: Generated new trial 14 with parameters {'x1': -1.003267, 'x2': 4.765916} using GenerationNode MBM.\n[INFO 09-24 05:12:56] ax.api.client: Trial 14 marked COMPLETED.\n[INFO 09-24 05:12:56] ax.api.client: Generated new trial 15 with parameters {'x1': 0.998306, 'x2': 2.774199} using GenerationNode MBM.\n[INFO 09-24 05:12:56] ax.api.client: Trial 15 marked COMPLETED.\n[INFO 09-24 05:12:57] ax.api.client: Generated new trial 16 with parameters {'x1': -3.484695, 'x2': 10.0} using GenerationNode MBM.\n[INFO 09-24 05:12:57] ax.api.client: Trial 16 marked FAILED.\n[INFO 09-24 05:12:57] ax.api.client: Generated new trial 17 with parameters {'x1': -3.487453, 'x2': 10.0} using GenerationNode MBM.\n[INFO 09-24 05:12:57] ax.api.client: Trial 17 marked COMPLETED.\n[INFO 09-24 05:12:57] ax.api.client: Generated new trial 18 with parameters {'x1': 1.849403, 'x2': 1.743396} using GenerationNode MBM.\n[INFO 09-24 05:12:58] ax.api.client: Trial 18 marked COMPLETED.\n[INFO 09-24 05:12:58] ax.api.client: Generated new trial 19 with parameters {'x1': 0.26386, 'x2': 3.502503} using GenerationNode MBM.\n[INFO 09-24 05:12:58] ax.api.client: Trial 19 marked COMPLETED."}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Trials by Status"})}),"\n",(0,i.jsx)(t.p,{children:"How many trials are in each status?"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{style:{textAlign:"right"}}),(0,i.jsx)(t.th,{style:{textAlign:"left"},children:"status"}),(0,i.jsx)(t.th,{style:{textAlign:"right"},children:"count"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"right"},children:"0"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"FAILED"}),(0,i.jsx)(t.td,{style:{textAlign:"right"},children:"3"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"right"},children:"1"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"COMPLETED"}),(0,i.jsx)(t.td,{style:{textAlign:"right"},children:"16"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"right"},children:"2"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"ABANDONED"}),(0,i.jsx)(t.td,{style:{textAlign:"right"},children:"1"})]})]})]}),"\n",(0,i.jsx)(t.h2,{id:"adding-options-to-an-analysis",children:"Adding options to an Analysis"}),"\n",(0,i.jsxs)(t.p,{children:["Imagine we wanted to add an option to change how this analysis is computed, say we wish\nto toggle whether the analysis computes the ",(0,i.jsx)(t.em,{children:"number"})," of trials in a given state or the\n",(0,i.jsx)(t.em,{children:"percentage"})," of trials in a given state. We cannot change the input arguments to\n",(0,i.jsx)(t.code,{children:"compute"}),", so this must be added elsewhere."]}),"\n",(0,i.jsxs)(t.p,{children:["The analysis' initializer is a natural place to put additional settings. We'll create a\n",(0,i.jsx)(t.code,{children:"TrialStatusTable.__init__"})," method which takes in the option as a boolean, then modify\n",(0,i.jsx)(t.code,{children:"compute"})," to consume this option as well. Following this patterns allows users to\nspecify all relevant settings before calling ",(0,i.jsx)(t.code,{children:"Client.compute_analyses"})," while still\nallowing the underlying ",(0,i.jsx)(t.code,{children:"compute"})," call to remain unchanged. Standarization of the\n",(0,i.jsx)(t.code,{children:"compute"})," call simplifies logic elsewhere in the stack."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-python",children:'class TrialStatusTable(Analysis):\n def __init__(self, as_fraction: bool) -> None:\n super().__init__()\n\n self.as_fraction = as_fraction\n\n def compute(\n self,\n experiment: Experiment | None = None,\n generation_strategy: GenerationStrategy | None = None,\n adapter: Adapter | None = None,\n ) -> AnalysisCard:\n trials_by_status = experiment.trials_by_status\n denominator = len(experiment.trials) if self.as_fraction else 1\n\n records = [\n {"status": status.name, "count": len(trials) / denominator}\n for status, trials in trials_by_status.items()\n if len(trials) > 0\n ]\n\n # Use _create_analysis_card rather than AnalysisCard to automatically populate relevant metadata\n return self._create_analysis_card(\n title="Trials by Status",\n subtitle="How many trials are in each status?",\n df=pd.DataFrame.from_records(records),\n )\n\n\ncard = client.compute_analyses(\n analyses=[TrialStatusTable(as_fraction=True)], display=True\n)\n'})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Trials by Status"})}),"\n",(0,i.jsx)(t.p,{children:"How many trials are in each status?"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{style:{textAlign:"right"}}),(0,i.jsx)(t.th,{style:{textAlign:"left"},children:"status"}),(0,i.jsx)(t.th,{style:{textAlign:"right"},children:"count"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"right"},children:"0"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"FAILED"}),(0,i.jsx)(t.td,{style:{textAlign:"right"},children:"0.15"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"right"},children:"1"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"COMPLETED"}),(0,i.jsx)(t.td,{style:{textAlign:"right"},children:"0.8"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{style:{textAlign:"right"},children:"2"}),(0,i.jsx)(t.td,{style:{textAlign:"left"},children:"ABANDONED"}),(0,i.jsx)(t.td,{style:{textAlign:"right"},children:"0.05"})]})]})]}),"\n",(0,i.jsx)(t.h2,{id:"plotly-analyses",children:"Plotly Analyses"}),"\n",(0,i.jsxs)(t.p,{children:["Analyses do not just have to be Pandas dataframes. Ax also defines a class\n",(0,i.jsx)(t.code,{children:"PlotlyAnalysisCard"})," containing both a dataframe and a plotly ",(0,i.jsx)(t.code,{children:"Figure"}),"."]}),"\n",(0,i.jsxs)(t.p,{children:["Let's create a bar chart based on ",(0,i.jsx)(t.code,{children:"TrialStatusTable"}),"."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-python",children:'from ax.analysis.plotly.plotly_analysis import PlotlyAnalysisCard, create_plotly_analysis_card\nfrom plotly import express as px\n\n\nclass TrialStatusTable(Analysis):\n def __init__(self, as_fraction: bool) -> None:\n super().__init__()\n\n self.as_fraction = as_fraction\n\n def compute(\n self,\n experiment: Experiment | None = None,\n generation_strategy: GenerationStrategy | None = None,\n adapter: Adapter | None = None,\n ) -> PlotlyAnalysisCard:\n trials_by_status = experiment.trials_by_status\n denominator = len(experiment.trials) if self.as_fraction else 1\n\n records = [\n {"status": status.name, "count": len(trials) / denominator}\n for status, trials in trials_by_status.items()\n if len(trials) > 0\n ]\n df = pd.DataFrame.from_records(records)\n\n # Create a Plotly figure using the df we generated before\n fig = px.bar
1(df, x="status", y="count")\n\n # Use _create_plotly_analysis_card rather than AnalysisCard to automatically populate relevant metadata\n return create_plotly_analysis_card(\n name=self.__class__.__name__,\n title="Trials by Status",\n subtitle="How many trials are in each status?",\n df=df,\n fig=fig,\n )\n\n\ncard = client.compute_analyses(\n analyses=[TrialStatusTable(as_fraction=True)], display=True\n)\n'})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Trials by Status"})}),"\n",(0,i.jsx)(t.p,{children:"How many trials are in each status?"}),"\n",(0,i.jsx)(o.z,{data:a(17389)}),"\n",(0,i.jsx)(t.h2,{id:"example-analyses-in-ax",children:"Example Analyses in Ax"}),"\n",(0,i.jsx)(t.p,{children:"Ax offers a wide range of analyses to help you monitor optimization results, gain deeper\ninsights into parameters and metrics based on model learning, and assess model\ndiagnostics to ensure your optimization is progressing effectively."}),"\n",(0,i.jsxs)(t.p,{children:["The following table contains examples of each ",(0,i.jsx)(t.code,{children:"Analysis"})," currently implemented in Ax:"]}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Name"}),(0,i.jsx)(t.th,{children:"Description"}),(0,i.jsx)(t.th,{children:"Example"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Metric Effects"})}),(0,i.jsx)(t.td,{children:"Shows predicted metric changes per arm using Ax's model, adjusted for noise and data non-stationarity for more reliable long-term effects. Can also plot raw \u201cObserved\u201d effects for the arms instead of model predicted effects."}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.img,{alt:"Metric Effects",src:a(44511).A+"",width:"1046",height:"600"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Scatter Plot"})}),(0,i.jsx)(t.td,{children:"Displays effects of each arm on two metrics, useful for visualizing trade-offs and the Pareto frontier."}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.img,{alt:"Scatter Plot",src:a(17278).A+"",width:"1030",height:"676"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Slice Plot"})}),(0,i.jsx)(t.td,{children:"One-dimensional view of predicted outcomes for a given metric by varying one parameter, with others fixed at a baseline."}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.img,{alt:"Slice Plot",src:a(6126).A+"",width:"1084",height:"592"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Sensitivity Analysis"})}),(0,i.jsx)(t.td,{children:"Shows how each parameter influences a metric via second-order sensitivity analysis. Helps identify which parameters have the greatest impact on a specific metric and whether their influence is positive or negative."}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.img,{alt:"Sensitivity Analysis",src:a(39440).A+"",width:"1070",height:"606"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Contour Plot"})}),(0,i.jsx)(t.td,{children:"Visualizes predicted metric outcomes over two parameters, highlighting optimal regions and gradients."}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.img,{alt:"Contour Plot",src:a(41102).A+"",width:"1088",height:"558"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Cross Validation Plot"})}),(0,i.jsx)(t.td,{children:"Compares model predictions to actual values using leave-one-out validation, showing fit quality and prediction uncertainty."}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.img,{alt:"Cross Validation Plot",src:a(86934).A+"",width:"496",height:"528"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Parallel Coordinates Plot"})}),(0,i.jsx)(t.td,{children:"Represents multi-dimensional parameters on parallel axes to assess search space coverage and identify patterns in performance."}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.img,{alt:"Parallel Coordinates Plot",src:a(12215).A+"",width:"1088",height:"492"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Summary"})}),(0,i.jsx)(t.td,{children:"Provides a high level summary of all arms/trials + metric results of your experiment in a tabular manner."}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.img,{alt:"Summary",src:a(23915).A+"",width:"1086",height:"424"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Metric Summary"})}),(0,i.jsx)(t.td,{children:"Tabular view of the metrics in the experiment."}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.img,{alt:"Metric Summary",src:a(787).A+"",width:"454",height:"118"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Search Space Summary"})}),(0,i.jsx)(t.td,{children:"Tabular view of the search space on the experiment."}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.img,{alt:"Search Space Summary",src:a(13988).A+"",width:"572",height:"410"})})]})]})]}),"\n",(0,i.jsx)(t.h2,{id:"miscellaneous-tips",children:"Miscellaneous tips"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["Many analyses rely on the same infrastru
1cture and utility functions -- check to see if\nwhat you need has already been implemented somewhere.","\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["Many analyses require an ",(0,i.jsx)(t.code,{children:"Adapter"})," but can use either the ",(0,i.jsx)(t.code,{children:"Adapter"})," provided or the\ncurrent ",(0,i.jsx)(t.code,{children:"Adapter"})," on the ",(0,i.jsx)(t.code,{children:"GenerationStrategy"})," -- ",(0,i.jsx)(t.code,{children:"extract_relevant_adapter"})," handles\nthis in a consistent way"]}),"\n",(0,i.jsxs)(t.li,{children:["Analyses which use an ",(0,i.jsx)(t.code,{children:"Arm"})," as the fundamental unit of analysis will find the\n",(0,i.jsx)(t.code,{children:"prepare_arm_data"})," utility useful; using it will also lend the ",(0,i.jsx)(t.code,{children:"Analysis"})," useful\nfeatures like relativization for free"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["When writing a new ",(0,i.jsx)(t.code,{children:"PlotlyAnalysis"})," check out ",(0,i.jsx)(t.code,{children:"ax.analysis.plotly.utils"})," for guidance\non using color schemes and unified tool tips"]}),"\n",(0,i.jsxs)(t.li,{children:["Try to follow consistent design patterns;
1 many analyses take an optional list of\n",(0,i.jsx)(t.code,{children:"metric_names"})," on initialization, and interpret ",(0,i.jsx)(t.code,{children:"None"})," to mean the user wants to\ncompute a card for each metric present. Following these conventions makes things\neasier for downstream consumers."]}),"\n"]})]})}function m(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(x,{...e})}):x(e)}},38987(e,t,a){a.d(t,{A:()=>s});a(96540);var n=a(28774),i=a(35088),r=a(74848);const s=function(e){var t=e.githubUrl,a=e.colabUrl;return(0,r.jsxs)("div",{className:"margin-top--sm margin-bottom--lg",children:[(0,r.jsxs)(n.A,{to:t,className:"button button--outline button--primary margin-right--xs",children:["Open in GitHub",(0,r.jsx)(i.A,{})]}),(0,r.jsxs)(n.A,{to:a,className:"button button--outline button--primary margin--xs",children:["Run in Google Colab",(0,r.jsx)(i.A,{})]})]})}},39440(e,t,a){a.d(t,{A:()=>n});const n=a.p+"assets/images/sensitivity_analysis_example-4dae85566500f957574cea72473b9116.png"},41102(e,t,a){a.d(t,{A:()=>n});const n=a.p+"assets/images/contour_plot_example-fb0b9c6bd5a462366142cfd1004e9e4d.png"},44511(e,t,a){a.d(t,{A:()=>n});const n=a.p+"assets/images/arm_effects_example-67f0b3e53f2ff0cda8282118a56af80e.png"},86934(e,t,a){a.d(t,{A:()=>n});const n=a.p+"assets/images/cross_validation_plot_example-5cdf2b90227a32066150f4a0429940c9.png"},98186(e){e.exports=JSON.parse('{"data":[{"dimensions":[{"label":"trial_index","values":[0,1,2,3,4,5,6,7,8,9]},{"label":"x1","values":[0,6.572685241699219,-3.558487817645073,-7.42762191221118,3.027334902435541,3.376422218833225,4.073497022053537,3.3237418703339543,-10,10]},{"label":"x2","values":[0,-0.2985382080078125,0.45584654435515404,-8.137527238577604,8.608087711036205,0.05856624152537864,-3.285827830675555,1.246520790436106,10,-10]},{"label":"booth","values":[74,62.62215403612936,229.0425802176539,1726.2495692556845,268.7594485265715,15.576367277370128,90.23429235755603,9.775263627390158,234,314]}],"labelangle":-45,"line":{"color":{"bdata":"AAAAAACAUkAAIFO+ok9PQPZIMNFcoWxAAj0Vj//4mkDriX+zJsxwQBqUnZwZJy9A+llfpf6OVkCP1qpa74wjQAAAAAAAQG1AAAAAAACgc0A=","dtype":"f8"},"colorscale":[[0,"rgb(161, 105, 40)"],[0.16666666666666666,"rgb(189, 146, 90)"],[0.3333333333333333,"rgb(214, 189, 141)"],[0.5,"rgb(237, 234, 194)"],[0.6666666666666666,"rgb(181, 200, 184)"],[0.8333333333333334,"rgb(121, 167, 172)"],[1,"rgb(40, 135, 161)"]],"showscale":true},"type":"parcoords"}],"layout":{"template":{"data":{"bar":[{"error_x":{"color":"#2a3f5f"},"error_y":{"color":"#2a3f5f"},"marker":{"line":{"color":"#E5ECF6","width":0.5},"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"bar"}],"barpolar":[{"marker":{"line":{"color":"#E5ECF6","width":0.5},"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"barpolar"}],"carpet":[{"aaxis":{"endlinecolor":"#2a3f5f","gridcolor":"white","linecolor":"white","minorgridcolor":"white","startlinecolor":"#2a3f5f"},"baxis":{"endlinecolor":"#2a3f5f","gridcolor":"white","linecolor":"white","minorgridcolor":"white","startlinecolor":"#2a3f5f"},"type":"carpet"}],"choropleth":[{"colorbar":{"outlinewidth":0,"ticks":""},"type":"choropleth"}],"contour":[{"colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1,"#f0f921"]],"type":"contour"}],"contourcarpet":[{"colorbar":{"outlinewidth":0,"ticks":""},"type":"contourcarpet"}],"heatmap":[{"colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1,"#f0f921"]],"type":"heatmap"}],"histogram":[{"marker":{"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"histogram"}],"histogram2d":[{"colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1,"#f0f921"]],"type":"histogram2d"}],"histogram2dcontour":[{"colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1,"#f0f921"]],"type":"histogram2dcontour"}],"mesh3d":[{"colorbar":{"outlinewidth":0,"ticks":""},"type":"mesh3d"}],"parcoords":[{"line":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"parcoords"}],"pie":[{"automargin":true,"type":"pie"}],"scatter":[{"fillpattern":{"fillmode":"overlay","size":10,"solidity":0.2},"type":"scatter"}],"scatter3d":[{"line":{"colorbar":{"outlinewidth":0,"ticks":""}},"marker":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"scatter3d"}],"scattercarpet":[{"marker":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"scattercarpet"}],"scattergeo":[{"marker":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"scattergeo"}],"scattergl":[{"marker":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"scattergl"}],"scattermap":[{"marker":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"scattermap"}],"scatterpolar":[{"marker":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"scatterpolar"}],"scatterpolargl":[{"marker":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"scatterpolargl"}],"scatterternary":[{"marker":{"colorbar":{"outlinewidth":0,"ticks":""}},"type":"scatterternary"}],"surface":[{"colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1,"#f0f921"]],"type":"surface"}],"table":[{"cells":{"fill":{"color":"#EBF0F8"},"line":{"color":"white"}},"header":{"fill":{"color":"#C8D4E3"},"line":{"color":"white"}},"type":"table"}]},"layout":{"annotationdefaults":{"arrowcolor":"#2a3f5f","arrowhead":0,"arrowwidth":1},"autotypenumbers":"strict","coloraxis":{"colorbar":{"outlinewidth":0,"ticks":""}},"colorscale":{"diverging":[[0,"#8e0152"],[0.1,"#c51b7d"],[0.2,"#de77ae"],[0.3,"#f1b6da"],[0.4,"#fde0ef"],[0.5,"#f7f7f7"],[0.6,"#e6f5d0"],[0.7,"#b8e186"],[0.8,"#7fbc41"],[0.9,"#4d9221"],[1,"#276419"]],"sequential":[[0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1,"#f0f921"]],"sequentialminus":[[0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1,"#f0f921"]]},"colorway":["#636efa","#EF553B","#00cc96","#ab63fa","#FFA15A","#19d3f3","#FF6692","#B6E880","#FF97FF","#FECB52"],"font":{"color":"#2a3f5f"},"geo":{"bgcolor":"white","lakecolor":"white","landcolor":"#E5ECF6","showlakes":true,"showland":true,"subunitcolor":"white"},"hoverlabel":{"align":"left"},"hovermode":"closest","paper_bgcolor":"white","plot_bgcolor":"#E5ECF6","polar":{"angularaxis":{"gridcolor":"white","linecolor":"white","t
1icks":""},"bgcolor":"#E5ECF6","radialaxis":{"gridcolor":"white","linecolor":"white","ticks":""}},"scene":{"xaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","gridwidth":2,"linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white"},"yaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","gridwidth":2,"linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white"},"zaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","gridwidth":2,"linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white"}},"shapedefaults":{"line":{"color":"#2a3f5f"}},"ternary":{"aaxis":{"gridcolor":"white","linecolor":"white","ticks":""},"baxis":{"gridcolor":"white","linecolor":"white","ticks":""},"bgcolor":"#E5ECF6","caxis":{"gridcolor":"white","linecolor":"white","ticks":""}},"title":{"x":0.05},"xaxis":{"automargin":true,"gridcolor":"white","linecolor":"white","ticks":"","title":{"standoff":15},"zerolinecolor":"white","zerolinewidth":2},"yaxis":{"automargin":true,"gridcolor":"white","linecolor":"white","ticks":"","title":{"standoff":15},"zerolinecolor":"white","zerolinewidth":2}}}}}')}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.