{"spec_id":"ohlc-bar","library":"bokeh","language":"python","code":"\"\"\" anyplot.ai\nohlc-bar: OHLC Bar Chart\nLibrary: bokeh 3.9.0 | Python 3.13.13\nQuality: 82/100 | Updated: 2026-05-17\n\"\"\"\n\nimport numpy as np\nimport pandas as pd\nfrom bokeh.io import export_png, output_file, save\nfrom bokeh.models import ColumnDataSource, HoverTool\nfrom bokeh.plotting import figure\n\n\n# Data - Generate 50 trading days of OHLC data\nnp.random.seed(42)\nn_days = 50\ndates = pd.date_range(\"2025-06-01\", periods=n_days, freq=\"B\")  # Business days\n\n# Generate realistic price movement starting around $150\nprice = 150.0\nopens, highs, lows, closes = [], [], [], []\n\nfor _ in range(n_days):\n    open_price = price\n    # Random daily movement\n    change = np.random.randn() * 3\n    close_price = open_price + change\n    # High and low based on volatility\n    volatility = abs(np.random.randn() * 2) + 1\n    high_price = max(open_price, close_price) + volatility\n    low_price = min(open_price, close_price) - volatility\n\n    opens.append(open_price)\n    highs.append(high_price)\n    lows.append(low_price)\n    closes.append(close_price)\n\n    # Next day opens near previous close\n    price = close_price + np.random.randn() * 0.5\n\ndf = pd.DataFrame({\"date\": dates, \"open\": opens, \"high\": highs, \"low\": lows, \"close\": closes})\n\n# Determine up/down bars for coloring (blue for up, orange for down - colorblind safe)\ndf[\"color\"] = np.where(df[\"close\"] >= df[\"open\"], \"#306998\", \"#E07020\")\ndf[\"date_str\"] = df[\"date\"].dt.strftime(\"%Y-%m-%d\")\ndf[\"x\"] = range(len(df))  # Numeric x for positioning\n\n# Create figure\np = figure(\n    width=4800,\n    height=2700,\n    title=\"ohlc-bar · bokeh · pyplots.ai\",\n    x_axis_label=\"Date\",\n    y_axis_label=\"Price ($)\",\n    tools=\"pan,wheel_zoom,box_zoom,reset,save\",\n)\n\n# Create ColumnDataSource\nsource = ColumnDataSource(df)\n\n# OHLC bar width for tick marks\ntick_width = 0.35\n\n# Draw high-low vertical lines (segments)\np.segment(x0=\"x\", y0=\"low\", x1=\"x\", y1=\"high\", source=source, color=\"color\", line_width=4)\n\n# Draw open ticks (horizontal line to the left)\np.segment(x0=df[\"x\"] - tick_width, y0=df[\"open\"], x1=df[\"x\"], y1=df[\"open\"], color=df[\"color\"].tolist(), line_width=4)\n\n# Draw close ticks (horizontal line to the right)\np.segment(x0=df[\"x\"], y0=df[\"close\"], x1=df[\"x\"] + tick_width, y1=df[\"close\"], color=df[\"color\"].tolist(), line_width=4)\n\n# Add hover tool\nhover = HoverTool(\n    tooltips=[\n        (\"Date\", \"@date_str\"),\n        (\"Open\", \"$@open{0.2f}\"),\n        (\"High\", \"$@high{0.2f}\"),\n        (\"Low\", \"$@low{0.2f}\"),\n        (\"Close\", \"$@close{0.2f}\"),\n    ],\n    mode=\"vline\",\n)\np.add_tools(hover)\n\n# Customize x-axis to show dates\ntick_positions = list(range(0, len(df), 5))\ntick_labels = {i: df.loc[i, \"date\"].strftime(\"%b %d\") for i in tick_positions}\np.xaxis.ticker = tick_positions\np.xaxis.major_label_overrides = tick_labels\n\n# Text styling for large canvas\np.title.text_font_size = \"36pt\"\np.xaxis.axis_label_text_font_size = \"28pt\"\np.yaxis.axis_label_text_font_size = \"28pt\"\np.xaxis.major_label_text_font_size = \"22pt\"\np.yaxis.major_label_text_font_size = \"22pt\"\n\n# Grid styling\np.grid.grid_line_alpha = 0.3\np.grid.grid_line_dash = \"dashed\"\n\n# Background\np.background_fill_color = \"#fafafa\"\n\n# Axis styling\np.xaxis.axis_line_width = 2\np.yaxis.axis_line_width = 2\np.xaxis.major_tick_line_width = 2\np.yaxis.major_tick_line_width = 2\n\n# Save PNG\nexport_png(p, filename=\"plot.png\")\n\n# Save interactive HTML\noutput_file(\"plot.html\", title=\"OHLC Bar Chart\")\nsave(p)\n"}