{"spec_id":"errorbar-asymmetric","library":"plotly","language":"python","code":"\"\"\" anyplot.ai\nerrorbar-asymmetric: Asymmetric Error Bars Plot\nLibrary: plotly 6.7.0 | Python 3.13.13\nQuality: 88/100 | Updated: 2026-05-15\n\"\"\"\n\nimport os\n\nimport numpy as np\nimport plotly.graph_objects as go\n\n\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\n\nPAGE_BG = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nELEVATED_BG = \"#FFFDF6\" if THEME == \"light\" else \"#242420\"\nINK = \"#1A1A17\" if THEME == \"light\" else \"#F0EFE8\"\nINK_SOFT = \"#4A4A44\" if THEME == \"light\" else \"#B8B7B0\"\nINK_MUTED = \"#6B6A63\" if THEME == \"light\" else \"#A8A79F\"\nGRID = \"rgba(26,26,23,0.10)\" if THEME == \"light\" else \"rgba(240,239,232,0.10)\"\nBRAND = \"#009E73\"\n\nnp.random.seed(42)\n\nproducts = [\"Product A\", \"Product B\", \"Product C\", \"Product D\", \"Product E\", \"Product F\"]\nsales_median = np.array([85, 62, 45, 78, 95, 55])\nerror_lower = np.array([12, 8, 15, 10, 18, 7])\nerror_upper = np.array([25, 18, 10, 22, 35, 20])\n\nlower_bound = sales_median - error_lower\nupper_bound = sales_median + error_upper\n\nfig = go.Figure()\n\nfig.add_trace(\n    go.Scatter(\n        x=products,\n        y=sales_median,\n        mode=\"markers\",\n        marker=dict(size=18, color=BRAND, line=dict(width=2, color=PAGE_BG)),\n        error_y=dict(\n            type=\"data\", symmetric=False, array=error_upper, arrayminus=error_lower, color=BRAND, thickness=3, width=12\n        ),\n        name=\"Median Sales (10th–90th percentile)\",\n        showlegend=True,\n        hovertemplate=(\n            \"<b>%{x}</b><br>\"\n            \"Median: %{y:.0f}k USD<br>\"\n            \"10th–90th: %{customdata[0]:.0f}k – %{customdata[1]:.0f}k USD\"\n            \"<extra></extra>\"\n        ),\n        customdata=np.column_stack([lower_bound, upper_bound]),\n    )\n)\n\nfig.update_layout(\n    title=dict(\n        text=\"errorbar-asymmetric · plotly · anyplot.ai\", font=dict(size=32, color=INK), x=0.5, xanchor=\"center\"\n    ),\n    xaxis=dict(\n        title=dict(text=\"Product Category\", font=dict(size=24, color=INK)),\n        tickfont=dict(size=20, color=INK_SOFT),\n        showgrid=False,\n        showline=True,\n        linecolor=INK_SOFT,\n        mirror=False,\n        zeroline=False,\n    ),\n    yaxis=dict(\n        title=dict(text=\"Quarterly Sales (thousands USD)\", font=dict(size=24, color=INK)),\n        tickfont=dict(size=20, color=INK_SOFT),\n        showgrid=True,\n        gridcolor=GRID,\n        gridwidth=1,\n        showline=True,\n        linecolor=INK_SOFT,\n        mirror=False,\n        zeroline=False,\n        range=[0, 150],\n    ),\n    template=\"none\",\n    paper_bgcolor=PAGE_BG,\n    plot_bgcolor=PAGE_BG,\n    font=dict(color=INK),\n    legend=dict(\n        font=dict(size=18, color=INK_SOFT),\n        x=0.02,\n        y=0.98,\n        xanchor=\"left\",\n        yanchor=\"top\",\n        bgcolor=ELEVATED_BG,\n        bordercolor=INK_SOFT,\n        borderwidth=1,\n    ),\n    margin=dict(l=100, r=80, t=120, b=100),\n)\n\nfig.add_annotation(\n    x=0.98,\n    y=0.02,\n    xref=\"paper\",\n    yref=\"paper\",\n    text=\"Error bars show 10th–90th percentile range\",\n    showarrow=False,\n    font=dict(size=16, color=INK_MUTED),\n    align=\"right\",\n    xanchor=\"right\",\n    yanchor=\"bottom\",\n)\n\nfig.write_image(f\"plot-{THEME}.png\", width=1600, height=900, scale=3)\nfig.write_html(f\"plot-{THEME}.html\", include_plotlyjs=\"cdn\")\n"}