streamlit-nightly 1.43.2.dev20250307__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (563) hide show
  1. streamlit/__init__.py +306 -0
  2. streamlit/__main__.py +20 -0
  3. streamlit/auth_util.py +218 -0
  4. streamlit/cli_util.py +105 -0
  5. streamlit/column_config.py +56 -0
  6. streamlit/commands/__init__.py +13 -0
  7. streamlit/commands/echo.py +126 -0
  8. streamlit/commands/execution_control.py +238 -0
  9. streamlit/commands/experimental_query_params.py +169 -0
  10. streamlit/commands/logo.py +189 -0
  11. streamlit/commands/navigation.py +385 -0
  12. streamlit/commands/page_config.py +311 -0
  13. streamlit/components/__init__.py +13 -0
  14. streamlit/components/lib/__init__.py +13 -0
  15. streamlit/components/lib/local_component_registry.py +84 -0
  16. streamlit/components/types/__init__.py +13 -0
  17. streamlit/components/types/base_component_registry.py +99 -0
  18. streamlit/components/types/base_custom_component.py +150 -0
  19. streamlit/components/v1/__init__.py +31 -0
  20. streamlit/components/v1/component_arrow.py +141 -0
  21. streamlit/components/v1/component_registry.py +130 -0
  22. streamlit/components/v1/components.py +38 -0
  23. streamlit/components/v1/custom_component.py +243 -0
  24. streamlit/config.py +1513 -0
  25. streamlit/config_option.py +311 -0
  26. streamlit/config_util.py +177 -0
  27. streamlit/connections/__init__.py +28 -0
  28. streamlit/connections/base_connection.py +174 -0
  29. streamlit/connections/snowflake_connection.py +562 -0
  30. streamlit/connections/snowpark_connection.py +213 -0
  31. streamlit/connections/sql_connection.py +425 -0
  32. streamlit/connections/util.py +97 -0
  33. streamlit/cursor.py +210 -0
  34. streamlit/dataframe_util.py +1416 -0
  35. streamlit/delta_generator.py +602 -0
  36. streamlit/delta_generator_singletons.py +204 -0
  37. streamlit/deprecation_util.py +209 -0
  38. streamlit/development.py +21 -0
  39. streamlit/elements/__init__.py +13 -0
  40. streamlit/elements/alert.py +234 -0
  41. streamlit/elements/arrow.py +962 -0
  42. streamlit/elements/balloons.py +47 -0
  43. streamlit/elements/bokeh_chart.py +133 -0
  44. streamlit/elements/code.py +114 -0
  45. streamlit/elements/deck_gl_json_chart.py +546 -0
  46. streamlit/elements/dialog_decorator.py +267 -0
  47. streamlit/elements/doc_string.py +558 -0
  48. streamlit/elements/empty.py +130 -0
  49. streamlit/elements/exception.py +331 -0
  50. streamlit/elements/form.py +354 -0
  51. streamlit/elements/graphviz_chart.py +150 -0
  52. streamlit/elements/heading.py +302 -0
  53. streamlit/elements/html.py +105 -0
  54. streamlit/elements/iframe.py +191 -0
  55. streamlit/elements/image.py +196 -0
  56. streamlit/elements/json.py +139 -0
  57. streamlit/elements/layouts.py +879 -0
  58. streamlit/elements/lib/__init__.py +13 -0
  59. streamlit/elements/lib/built_in_chart_utils.py +1157 -0
  60. streamlit/elements/lib/color_util.py +263 -0
  61. streamlit/elements/lib/column_config_utils.py +542 -0
  62. streamlit/elements/lib/column_types.py +2188 -0
  63. streamlit/elements/lib/dialog.py +147 -0
  64. streamlit/elements/lib/dicttools.py +154 -0
  65. streamlit/elements/lib/event_utils.py +37 -0
  66. streamlit/elements/lib/file_uploader_utils.py +66 -0
  67. streamlit/elements/lib/form_utils.py +77 -0
  68. streamlit/elements/lib/image_utils.py +441 -0
  69. streamlit/elements/lib/js_number.py +105 -0
  70. streamlit/elements/lib/mutable_status_container.py +183 -0
  71. streamlit/elements/lib/options_selector_utils.py +250 -0
  72. streamlit/elements/lib/pandas_styler_utils.py +274 -0
  73. streamlit/elements/lib/policies.py +194 -0
  74. streamlit/elements/lib/streamlit_plotly_theme.py +207 -0
  75. streamlit/elements/lib/subtitle_utils.py +176 -0
  76. streamlit/elements/lib/utils.py +250 -0
  77. streamlit/elements/map.py +508 -0
  78. streamlit/elements/markdown.py +277 -0
  79. streamlit/elements/media.py +793 -0
  80. streamlit/elements/metric.py +301 -0
  81. streamlit/elements/plotly_chart.py +546 -0
  82. streamlit/elements/progress.py +156 -0
  83. streamlit/elements/pyplot.py +194 -0
  84. streamlit/elements/snow.py +47 -0
  85. streamlit/elements/spinner.py +113 -0
  86. streamlit/elements/text.py +76 -0
  87. streamlit/elements/toast.py +98 -0
  88. streamlit/elements/vega_charts.py +1984 -0
  89. streamlit/elements/widgets/__init__.py +13 -0
  90. streamlit/elements/widgets/audio_input.py +310 -0
  91. streamlit/elements/widgets/button.py +1123 -0
  92. streamlit/elements/widgets/button_group.py +1008 -0
  93. streamlit/elements/widgets/camera_input.py +263 -0
  94. streamlit/elements/widgets/chat.py +647 -0
  95. streamlit/elements/widgets/checkbox.py +352 -0
  96. streamlit/elements/widgets/color_picker.py +265 -0
  97. streamlit/elements/widgets/data_editor.py +983 -0
  98. streamlit/elements/widgets/file_uploader.py +486 -0
  99. streamlit/elements/widgets/multiselect.py +338 -0
  100. streamlit/elements/widgets/number_input.py +545 -0
  101. streamlit/elements/widgets/radio.py +407 -0
  102. streamlit/elements/widgets/select_slider.py +437 -0
  103. streamlit/elements/widgets/selectbox.py +366 -0
  104. streamlit/elements/widgets/slider.py +880 -0
  105. streamlit/elements/widgets/text_widgets.py +628 -0
  106. streamlit/elements/widgets/time_widgets.py +970 -0
  107. streamlit/elements/write.py +574 -0
  108. streamlit/emojis.py +34 -0
  109. streamlit/env_util.py +61 -0
  110. streamlit/error_util.py +105 -0
  111. streamlit/errors.py +452 -0
  112. streamlit/external/__init__.py +13 -0
  113. streamlit/external/langchain/__init__.py +23 -0
  114. streamlit/external/langchain/streamlit_callback_handler.py +406 -0
  115. streamlit/file_util.py +247 -0
  116. streamlit/git_util.py +173 -0
  117. streamlit/hello/__init__.py +13 -0
  118. streamlit/hello/animation_demo.py +82 -0
  119. streamlit/hello/dataframe_demo.py +71 -0
  120. streamlit/hello/hello.py +37 -0
  121. streamlit/hello/mapping_demo.py +114 -0
  122. streamlit/hello/plotting_demo.py +55 -0
  123. streamlit/hello/streamlit_app.py +55 -0
  124. streamlit/hello/utils.py +28 -0
  125. streamlit/logger.py +130 -0
  126. streamlit/material_icon_names.py +25 -0
  127. streamlit/navigation/__init__.py +13 -0
  128. streamlit/navigation/page.py +302 -0
  129. streamlit/net_util.py +125 -0
  130. streamlit/platform.py +33 -0
  131. streamlit/proto/Alert_pb2.py +29 -0
  132. streamlit/proto/Alert_pb2.pyi +90 -0
  133. streamlit/proto/AppPage_pb2.py +27 -0
  134. streamlit/proto/AppPage_pb2.pyi +64 -0
  135. streamlit/proto/ArrowNamedDataSet_pb2.py +28 -0
  136. streamlit/proto/ArrowNamedDataSet_pb2.pyi +57 -0
  137. streamlit/proto/ArrowVegaLiteChart_pb2.py +29 -0
  138. streamlit/proto/ArrowVegaLiteChart_pb2.pyi +84 -0
  139. streamlit/proto/Arrow_pb2.py +33 -0
  140. streamlit/proto/Arrow_pb2.pyi +188 -0
  141. streamlit/proto/AudioInput_pb2.py +28 -0
  142. streamlit/proto/AudioInput_pb2.pyi +58 -0
  143. streamlit/proto/Audio_pb2.py +27 -0
  144. streamlit/proto/Audio_pb2.pyi +58 -0
  145. streamlit/proto/AuthRedirect_pb2.py +27 -0
  146. streamlit/proto/AuthRedirect_pb2.pyi +41 -0
  147. streamlit/proto/AutoRerun_pb2.py +27 -0
  148. streamlit/proto/AutoRerun_pb2.pyi +45 -0
  149. streamlit/proto/BackMsg_pb2.py +29 -0
  150. streamlit/proto/BackMsg_pb2.pyi +105 -0
  151. streamlit/proto/Balloons_pb2.py +27 -0
  152. streamlit/proto/Balloons_pb2.pyi +43 -0
  153. streamlit/proto/Block_pb2.py +53 -0
  154. streamlit/proto/Block_pb2.pyi +322 -0
  155. streamlit/proto/BokehChart_pb2.py +27 -0
  156. streamlit/proto/BokehChart_pb2.pyi +49 -0
  157. streamlit/proto/ButtonGroup_pb2.py +36 -0
  158. streamlit/proto/ButtonGroup_pb2.pyi +169 -0
  159. streamlit/proto/Button_pb2.py +27 -0
  160. streamlit/proto/Button_pb2.pyi +71 -0
  161. streamlit/proto/CameraInput_pb2.py +28 -0
  162. streamlit/proto/CameraInput_pb2.pyi +58 -0
  163. streamlit/proto/ChatInput_pb2.py +31 -0
  164. streamlit/proto/ChatInput_pb2.pyi +111 -0
  165. streamlit/proto/Checkbox_pb2.py +30 -0
  166. streamlit/proto/Checkbox_pb2.pyi +90 -0
  167. streamlit/proto/ClientState_pb2.py +30 -0
  168. streamlit/proto/ClientState_pb2.pyi +90 -0
  169. streamlit/proto/Code_pb2.py +27 -0
  170. streamlit/proto/Code_pb2.pyi +55 -0
  171. streamlit/proto/ColorPicker_pb2.py +28 -0
  172. streamlit/proto/ColorPicker_pb2.pyi +67 -0
  173. streamlit/proto/Common_pb2.py +51 -0
  174. streamlit/proto/Common_pb2.pyi +293 -0
  175. streamlit/proto/Components_pb2.py +35 -0
  176. streamlit/proto/Components_pb2.pyi +172 -0
  177. streamlit/proto/DataFrame_pb2.py +56 -0
  178. streamlit/proto/DataFrame_pb2.pyi +397 -0
  179. streamlit/proto/DateInput_pb2.py +28 -0
  180. streamlit/proto/DateInput_pb2.pyi +83 -0
  181. streamlit/proto/DeckGlJsonChart_pb2.py +29 -0
  182. streamlit/proto/DeckGlJsonChart_pb2.pyi +102 -0
  183. streamlit/proto/Delta_pb2.py +31 -0
  184. streamlit/proto/Delta_pb2.pyi +74 -0
  185. streamlit/proto/DocString_pb2.py +29 -0
  186. streamlit/proto/DocString_pb2.pyi +93 -0
  187. streamlit/proto/DownloadButton_pb2.py +27 -0
  188. streamlit/proto/DownloadButton_pb2.pyi +70 -0
  189. streamlit/proto/Element_pb2.py +78 -0
  190. streamlit/proto/Element_pb2.pyi +312 -0
  191. streamlit/proto/Empty_pb2.py +27 -0
  192. streamlit/proto/Empty_pb2.pyi +36 -0
  193. streamlit/proto/Exception_pb2.py +27 -0
  194. streamlit/proto/Exception_pb2.pyi +72 -0
  195. streamlit/proto/Favicon_pb2.py +27 -0
  196. streamlit/proto/Favicon_pb2.pyi +40 -0
  197. streamlit/proto/FileUploader_pb2.py +28 -0
  198. streamlit/proto/FileUploader_pb2.pyi +78 -0
  199. streamlit/proto/ForwardMsg_pb2.py +53 -0
  200. streamlit/proto/ForwardMsg_pb2.pyi +293 -0
  201. streamlit/proto/GitInfo_pb2.py +29 -0
  202. streamlit/proto/GitInfo_pb2.pyi +83 -0
  203. streamlit/proto/GraphVizChart_pb2.py +27 -0
  204. streamlit/proto/GraphVizChart_pb2.pyi +53 -0
  205. streamlit/proto/Heading_pb2.py +27 -0
  206. streamlit/proto/Heading_pb2.pyi +56 -0
  207. streamlit/proto/Html_pb2.py +27 -0
  208. streamlit/proto/Html_pb2.pyi +42 -0
  209. streamlit/proto/IFrame_pb2.py +27 -0
  210. streamlit/proto/IFrame_pb2.pyi +59 -0
  211. streamlit/proto/Image_pb2.py +29 -0
  212. streamlit/proto/Image_pb2.pyi +84 -0
  213. streamlit/proto/Json_pb2.py +27 -0
  214. streamlit/proto/Json_pb2.pyi +53 -0
  215. streamlit/proto/LabelVisibilityMessage_pb2.py +29 -0
  216. streamlit/proto/LabelVisibilityMessage_pb2.pyi +68 -0
  217. streamlit/proto/LinkButton_pb2.py +27 -0
  218. streamlit/proto/LinkButton_pb2.pyi +58 -0
  219. streamlit/proto/Logo_pb2.py +27 -0
  220. streamlit/proto/Logo_pb2.pyi +51 -0
  221. streamlit/proto/Markdown_pb2.py +29 -0
  222. streamlit/proto/Markdown_pb2.pyi +86 -0
  223. streamlit/proto/Metric_pb2.py +32 -0
  224. streamlit/proto/Metric_pb2.pyi +101 -0
  225. streamlit/proto/MetricsEvent_pb2.py +30 -0
  226. streamlit/proto/MetricsEvent_pb2.pyi +200 -0
  227. streamlit/proto/MultiSelect_pb2.py +28 -0
  228. streamlit/proto/MultiSelect_pb2.pyi +81 -0
  229. streamlit/proto/NamedDataSet_pb2.py +28 -0
  230. streamlit/proto/NamedDataSet_pb2.pyi +59 -0
  231. streamlit/proto/Navigation_pb2.py +30 -0
  232. streamlit/proto/Navigation_pb2.pyi +84 -0
  233. streamlit/proto/NewSession_pb2.py +51 -0
  234. streamlit/proto/NewSession_pb2.pyi +481 -0
  235. streamlit/proto/NumberInput_pb2.py +30 -0
  236. streamlit/proto/NumberInput_pb2.pyi +121 -0
  237. streamlit/proto/PageConfig_pb2.py +33 -0
  238. streamlit/proto/PageConfig_pb2.pyi +126 -0
  239. streamlit/proto/PageInfo_pb2.py +27 -0
  240. streamlit/proto/PageInfo_pb2.pyi +43 -0
  241. streamlit/proto/PageLink_pb2.py +27 -0
  242. streamlit/proto/PageLink_pb2.pyi +63 -0
  243. streamlit/proto/PageNotFound_pb2.py +27 -0
  244. streamlit/proto/PageNotFound_pb2.pyi +42 -0
  245. streamlit/proto/PageProfile_pb2.py +31 -0
  246. streamlit/proto/PageProfile_pb2.pyi +127 -0
  247. streamlit/proto/PagesChanged_pb2.py +28 -0
  248. streamlit/proto/PagesChanged_pb2.pyi +48 -0
  249. streamlit/proto/ParentMessage_pb2.py +27 -0
  250. streamlit/proto/ParentMessage_pb2.pyi +46 -0
  251. streamlit/proto/PlotlyChart_pb2.py +31 -0
  252. streamlit/proto/PlotlyChart_pb2.pyi +131 -0
  253. streamlit/proto/Progress_pb2.py +27 -0
  254. streamlit/proto/Progress_pb2.pyi +43 -0
  255. streamlit/proto/Radio_pb2.py +28 -0
  256. streamlit/proto/Radio_pb2.pyi +84 -0
  257. streamlit/proto/RootContainer_pb2.py +27 -0
  258. streamlit/proto/RootContainer_pb2.pyi +56 -0
  259. streamlit/proto/Selectbox_pb2.py +28 -0
  260. streamlit/proto/Selectbox_pb2.pyi +80 -0
  261. streamlit/proto/SessionEvent_pb2.py +28 -0
  262. streamlit/proto/SessionEvent_pb2.pyi +62 -0
  263. streamlit/proto/SessionStatus_pb2.py +27 -0
  264. streamlit/proto/SessionStatus_pb2.pyi +57 -0
  265. streamlit/proto/Skeleton_pb2.py +29 -0
  266. streamlit/proto/Skeleton_pb2.pyi +71 -0
  267. streamlit/proto/Slider_pb2.py +32 -0
  268. streamlit/proto/Slider_pb2.pyi +142 -0
  269. streamlit/proto/Snow_pb2.py +27 -0
  270. streamlit/proto/Snow_pb2.pyi +43 -0
  271. streamlit/proto/Spinner_pb2.py +27 -0
  272. streamlit/proto/Spinner_pb2.pyi +49 -0
  273. streamlit/proto/TextArea_pb2.py +28 -0
  274. streamlit/proto/TextArea_pb2.pyi +80 -0
  275. streamlit/proto/TextInput_pb2.py +30 -0
  276. streamlit/proto/TextInput_pb2.pyi +107 -0
  277. streamlit/proto/Text_pb2.py +27 -0
  278. streamlit/proto/Text_pb2.pyi +46 -0
  279. streamlit/proto/TimeInput_pb2.py +28 -0
  280. streamlit/proto/TimeInput_pb2.pyi +74 -0
  281. streamlit/proto/Toast_pb2.py +27 -0
  282. streamlit/proto/Toast_pb2.pyi +45 -0
  283. streamlit/proto/VegaLiteChart_pb2.py +29 -0
  284. streamlit/proto/VegaLiteChart_pb2.pyi +71 -0
  285. streamlit/proto/Video_pb2.py +31 -0
  286. streamlit/proto/Video_pb2.pyi +117 -0
  287. streamlit/proto/WidgetStates_pb2.py +31 -0
  288. streamlit/proto/WidgetStates_pb2.pyi +126 -0
  289. streamlit/proto/__init__.py +15 -0
  290. streamlit/proto/openmetrics_data_model_pb2.py +60 -0
  291. streamlit/proto/openmetrics_data_model_pb2.pyi +522 -0
  292. streamlit/py.typed +0 -0
  293. streamlit/runtime/__init__.py +50 -0
  294. streamlit/runtime/app_session.py +982 -0
  295. streamlit/runtime/caching/__init__.py +98 -0
  296. streamlit/runtime/caching/cache_data_api.py +665 -0
  297. streamlit/runtime/caching/cache_errors.py +142 -0
  298. streamlit/runtime/caching/cache_resource_api.py +527 -0
  299. streamlit/runtime/caching/cache_type.py +33 -0
  300. streamlit/runtime/caching/cache_utils.py +523 -0
  301. streamlit/runtime/caching/cached_message_replay.py +290 -0
  302. streamlit/runtime/caching/hashing.py +637 -0
  303. streamlit/runtime/caching/legacy_cache_api.py +169 -0
  304. streamlit/runtime/caching/storage/__init__.py +29 -0
  305. streamlit/runtime/caching/storage/cache_storage_protocol.py +239 -0
  306. streamlit/runtime/caching/storage/dummy_cache_storage.py +60 -0
  307. streamlit/runtime/caching/storage/in_memory_cache_storage_wrapper.py +145 -0
  308. streamlit/runtime/caching/storage/local_disk_cache_storage.py +223 -0
  309. streamlit/runtime/connection_factory.py +436 -0
  310. streamlit/runtime/context.py +280 -0
  311. streamlit/runtime/credentials.py +364 -0
  312. streamlit/runtime/forward_msg_cache.py +296 -0
  313. streamlit/runtime/forward_msg_queue.py +240 -0
  314. streamlit/runtime/fragment.py +477 -0
  315. streamlit/runtime/media_file_manager.py +234 -0
  316. streamlit/runtime/media_file_storage.py +143 -0
  317. streamlit/runtime/memory_media_file_storage.py +181 -0
  318. streamlit/runtime/memory_session_storage.py +77 -0
  319. streamlit/runtime/memory_uploaded_file_manager.py +138 -0
  320. streamlit/runtime/metrics_util.py +486 -0
  321. streamlit/runtime/pages_manager.py +165 -0
  322. streamlit/runtime/runtime.py +792 -0
  323. streamlit/runtime/runtime_util.py +106 -0
  324. streamlit/runtime/script_data.py +46 -0
  325. streamlit/runtime/scriptrunner/__init__.py +38 -0
  326. streamlit/runtime/scriptrunner/exec_code.py +159 -0
  327. streamlit/runtime/scriptrunner/magic.py +273 -0
  328. streamlit/runtime/scriptrunner/magic_funcs.py +32 -0
  329. streamlit/runtime/scriptrunner/script_cache.py +89 -0
  330. streamlit/runtime/scriptrunner/script_runner.py +756 -0
  331. streamlit/runtime/scriptrunner_utils/__init__.py +19 -0
  332. streamlit/runtime/scriptrunner_utils/exceptions.py +48 -0
  333. streamlit/runtime/scriptrunner_utils/script_requests.py +307 -0
  334. streamlit/runtime/scriptrunner_utils/script_run_context.py +287 -0
  335. streamlit/runtime/secrets.py +534 -0
  336. streamlit/runtime/session_manager.py +394 -0
  337. streamlit/runtime/state/__init__.py +41 -0
  338. streamlit/runtime/state/common.py +191 -0
  339. streamlit/runtime/state/query_params.py +205 -0
  340. streamlit/runtime/state/query_params_proxy.py +218 -0
  341. streamlit/runtime/state/safe_session_state.py +138 -0
  342. streamlit/runtime/state/session_state.py +772 -0
  343. streamlit/runtime/state/session_state_proxy.py +153 -0
  344. streamlit/runtime/state/widgets.py +135 -0
  345. streamlit/runtime/stats.py +109 -0
  346. streamlit/runtime/uploaded_file_manager.py +148 -0
  347. streamlit/runtime/websocket_session_manager.py +167 -0
  348. streamlit/source_util.py +98 -0
  349. streamlit/static/favicon.png +0 -0
  350. streamlit/static/index.html +61 -0
  351. streamlit/static/static/css/index.Bmkmz40k.css +1 -0
  352. streamlit/static/static/css/index.DpJG_94W.css +1 -0
  353. streamlit/static/static/css/index.DzuxGC_t.css +1 -0
  354. streamlit/static/static/js/FileDownload.esm.Bp9m5jrx.js +1 -0
  355. streamlit/static/static/js/FileHelper.D_3pbilj.js +5 -0
  356. streamlit/static/static/js/FormClearHelper.Ct2rwLXo.js +1 -0
  357. streamlit/static/static/js/Hooks.BKdzj5MJ.js +1 -0
  358. streamlit/static/static/js/InputInstructions.DB3QGNJP.js +1 -0
  359. streamlit/static/static/js/ProgressBar.D40A5xc2.js +2 -0
  360. streamlit/static/static/js/RenderInPortalIfExists.DLUCooTN.js +1 -0
  361. streamlit/static/static/js/Toolbar.BiGGIQun.js +1 -0
  362. streamlit/static/static/js/UploadFileInfo.C-jY39rj.js +1 -0
  363. streamlit/static/static/js/base-input.CQBQT24M.js +4 -0
  364. streamlit/static/static/js/checkbox.Buj8gd_M.js +9 -0
  365. streamlit/static/static/js/createDownloadLinkElement.DZMwyjvU.js +1 -0
  366. streamlit/static/static/js/createSuper.CesK3I23.js +1 -0
  367. streamlit/static/static/js/data-grid-overlay-editor.B69OOFM4.js +1 -0
  368. streamlit/static/static/js/downloader.BZQhlBNT.js +1 -0
  369. streamlit/static/static/js/es6.D9Zhqujy.js +2 -0
  370. streamlit/static/static/js/iframeResizer.contentWindow.CAzcBpCC.js +1 -0
  371. streamlit/static/static/js/index.08vcOOvb.js +1 -0
  372. streamlit/static/static/js/index.0uqKfJUS.js +1 -0
  373. streamlit/static/static/js/index.B02M5u69.js +203 -0
  374. streamlit/static/static/js/index.B7mcZKMx.js +1 -0
  375. streamlit/static/static/js/index.BAQDHFA_.js +1 -0
  376. streamlit/static/static/js/index.BI60cMVr.js +2 -0
  377. streamlit/static/static/js/index.BLug2inK.js +1 -0
  378. streamlit/static/static/js/index.BM6TMY8g.js +2 -0
  379. streamlit/static/static/js/index.BZ9p1t7G.js +1 -0
  380. streamlit/static/static/js/index.BZqa87a1.js +2 -0
  381. streamlit/static/static/js/index.BcsRUzZZ.js +1 -0
  382. streamlit/static/static/js/index.BgVMiY_P.js +197 -0
  383. streamlit/static/static/js/index.BtuGy7By.js +6 -0
  384. streamlit/static/static/js/index.BuDuBmrs.js +1 -0
  385. streamlit/static/static/js/index.BvXU2oKV.js +1 -0
  386. streamlit/static/static/js/index.BxcwPacT.js +73 -0
  387. streamlit/static/static/js/index.CWX8KB81.js +1 -0
  388. streamlit/static/static/js/index.CXzZTo_q.js +1 -0
  389. streamlit/static/static/js/index.CcRWp_KL.js +1 -0
  390. streamlit/static/static/js/index.Cd-_xe55.js +3 -0
  391. streamlit/static/static/js/index.CdG2PXln.js +4537 -0
  392. streamlit/static/static/js/index.CjXvXmcP.js +1 -0
  393. streamlit/static/static/js/index.D1HZENZx.js +776 -0
  394. streamlit/static/static/js/index.D21Efo64.js +1617 -0
  395. streamlit/static/static/js/index.D9WgGVBx.js +7 -0
  396. streamlit/static/static/js/index.DEcsHtvb.js +12 -0
  397. streamlit/static/static/js/index.DFeMfr_K.js +1 -0
  398. streamlit/static/static/js/index.DHFBoItz.js +1 -0
  399. streamlit/static/static/js/index.D_PrBKnJ.js +3 -0
  400. streamlit/static/static/js/index.DmuRkekN.js +3855 -0
  401. streamlit/static/static/js/index.Do6eY8sf.js +1 -0
  402. streamlit/static/static/js/index.Dz3lP2P-.js +1 -0
  403. streamlit/static/static/js/index.Dz_UqF-s.js +1 -0
  404. streamlit/static/static/js/index.GkSUsPhJ.js +1 -0
  405. streamlit/static/static/js/index.H1U1IC_d.js +3 -0
  406. streamlit/static/static/js/index.g6p_4DPr.js +1 -0
  407. streamlit/static/static/js/index.g9x_GKss.js +1 -0
  408. streamlit/static/static/js/index.zo9jm08y.js +1 -0
  409. streamlit/static/static/js/input.DnaFglHq.js +2 -0
  410. streamlit/static/static/js/inputUtils.CQWz5UKz.js +1 -0
  411. streamlit/static/static/js/memory.Crb9x4-F.js +1 -0
  412. streamlit/static/static/js/mergeWith.ouAz0sK3.js +1 -0
  413. streamlit/static/static/js/number-overlay-editor._UaN-O48.js +9 -0
  414. streamlit/static/static/js/possibleConstructorReturn.CtGjGFHz.js +1 -0
  415. streamlit/static/static/js/sandbox.CBybYOhV.js +1 -0
  416. streamlit/static/static/js/sprintf.D7DtBTRn.js +1 -0
  417. streamlit/static/static/js/textarea.Cb_uJt5U.js +2 -0
  418. streamlit/static/static/js/threshold.DjX0wlsa.js +1 -0
  419. streamlit/static/static/js/timepicker.DKT7pfoF.js +4 -0
  420. streamlit/static/static/js/timer.CAwTRJ_g.js +1 -0
  421. streamlit/static/static/js/toConsumableArray.05Ikp13-.js +3 -0
  422. streamlit/static/static/js/uniqueId.D2FMWUEI.js +1 -0
  423. streamlit/static/static/js/useBasicWidgetState.urnZLANY.js +1 -0
  424. streamlit/static/static/js/useOnInputChange.BOKIIdJ1.js +1 -0
  425. streamlit/static/static/js/value.CgPGBV_l.js +1 -0
  426. streamlit/static/static/js/withFullScreenWrapper.C_N8J0Xx.js +1 -0
  427. streamlit/static/static/media/KaTeX_AMS-Regular.BQhdFMY1.woff2 +0 -0
  428. streamlit/static/static/media/KaTeX_AMS-Regular.DMm9YOAa.woff +0 -0
  429. streamlit/static/static/media/KaTeX_AMS-Regular.DRggAlZN.ttf +0 -0
  430. streamlit/static/static/media/KaTeX_Caligraphic-Bold.ATXxdsX0.ttf +0 -0
  431. streamlit/static/static/media/KaTeX_Caligraphic-Bold.BEiXGLvX.woff +0 -0
  432. streamlit/static/static/media/KaTeX_Caligraphic-Bold.Dq_IR9rO.woff2 +0 -0
  433. streamlit/static/static/media/KaTeX_Caligraphic-Regular.CTRA-rTL.woff +0 -0
  434. streamlit/static/static/media/KaTeX_Caligraphic-Regular.Di6jR-x-.woff2 +0 -0
  435. streamlit/static/static/media/KaTeX_Caligraphic-Regular.wX97UBjC.ttf +0 -0
  436. streamlit/static/static/media/KaTeX_Fraktur-Bold.BdnERNNW.ttf +0 -0
  437. streamlit/static/static/media/KaTeX_Fraktur-Bold.BsDP51OF.woff +0 -0
  438. streamlit/static/static/media/KaTeX_Fraktur-Bold.CL6g_b3V.woff2 +0 -0
  439. streamlit/static/static/media/KaTeX_Fraktur-Regular.CB_wures.ttf +0 -0
  440. streamlit/static/static/media/KaTeX_Fraktur-Regular.CTYiF6lA.woff2 +0 -0
  441. streamlit/static/static/media/KaTeX_Fraktur-Regular.Dxdc4cR9.woff +0 -0
  442. streamlit/static/static/media/KaTeX_Main-Bold.Cx986IdX.woff2 +0 -0
  443. streamlit/static/static/media/KaTeX_Main-Bold.Jm3AIy58.woff +0 -0
  444. streamlit/static/static/media/KaTeX_Main-Bold.waoOVXN0.ttf +0 -0
  445. streamlit/static/static/media/KaTeX_Main-BoldItalic.DxDJ3AOS.woff2 +0 -0
  446. streamlit/static/static/media/KaTeX_Main-BoldItalic.DzxPMmG6.ttf +0 -0
  447. streamlit/static/static/media/KaTeX_Main-BoldItalic.SpSLRI95.woff +0 -0
  448. streamlit/static/static/media/KaTeX_Main-Italic.3WenGoN9.ttf +0 -0
  449. streamlit/static/static/media/KaTeX_Main-Italic.BMLOBm91.woff +0 -0
  450. streamlit/static/static/media/KaTeX_Main-Italic.NWA7e6Wa.woff2 +0 -0
  451. streamlit/static/static/media/KaTeX_Main-Regular.B22Nviop.woff2 +0 -0
  452. streamlit/static/static/media/KaTeX_Main-Regular.Dr94JaBh.woff +0 -0
  453. streamlit/static/static/media/KaTeX_Main-Regular.ypZvNtVU.ttf +0 -0
  454. streamlit/static/static/media/KaTeX_Math-BoldItalic.B3XSjfu4.ttf +0 -0
  455. streamlit/static/static/media/KaTeX_Math-BoldItalic.CZnvNsCZ.woff2 +0 -0
  456. streamlit/static/static/media/KaTeX_Math-BoldItalic.iY-2wyZ7.woff +0 -0
  457. streamlit/static/static/media/KaTeX_Math-Italic.DA0__PXp.woff +0 -0
  458. streamlit/static/static/media/KaTeX_Math-Italic.flOr_0UB.ttf +0 -0
  459. streamlit/static/static/media/KaTeX_Math-Italic.t53AETM-.woff2 +0 -0
  460. streamlit/static/static/media/KaTeX_SansSerif-Bold.CFMepnvq.ttf +0 -0
  461. streamlit/static/static/media/KaTeX_SansSerif-Bold.D1sUS0GD.woff2 +0 -0
  462. streamlit/static/static/media/KaTeX_SansSerif-Bold.DbIhKOiC.woff +0 -0
  463. streamlit/static/static/media/KaTeX_SansSerif-Italic.C3H0VqGB.woff2 +0 -0
  464. streamlit/static/static/media/KaTeX_SansSerif-Italic.DN2j7dab.woff +0 -0
  465. streamlit/static/static/media/KaTeX_SansSerif-Italic.YYjJ1zSn.ttf +0 -0
  466. streamlit/static/static/media/KaTeX_SansSerif-Regular.BNo7hRIc.ttf +0 -0
  467. streamlit/static/static/media/KaTeX_SansSerif-Regular.CS6fqUqJ.woff +0 -0
  468. streamlit/static/static/media/KaTeX_SansSerif-Regular.DDBCnlJ7.woff2 +0 -0
  469. streamlit/static/static/media/KaTeX_Script-Regular.C5JkGWo-.ttf +0 -0
  470. streamlit/static/static/media/KaTeX_Script-Regular.D3wIWfF6.woff2 +0 -0
  471. streamlit/static/static/media/KaTeX_Script-Regular.D5yQViql.woff +0 -0
  472. streamlit/static/static/media/KaTeX_Size1-Regular.C195tn64.woff +0 -0
  473. streamlit/static/static/media/KaTeX_Size1-Regular.Dbsnue_I.ttf +0 -0
  474. streamlit/static/static/media/KaTeX_Size1-Regular.mCD8mA8B.woff2 +0 -0
  475. streamlit/static/static/media/KaTeX_Size2-Regular.B7gKUWhC.ttf +0 -0
  476. streamlit/static/static/media/KaTeX_Size2-Regular.Dy4dx90m.woff2 +0 -0
  477. streamlit/static/static/media/KaTeX_Size2-Regular.oD1tc_U0.woff +0 -0
  478. streamlit/static/static/media/KaTeX_Size3-Regular.CTq5MqoE.woff +0 -0
  479. streamlit/static/static/media/KaTeX_Size3-Regular.DgpXs0kz.ttf +0 -0
  480. streamlit/static/static/media/KaTeX_Size4-Regular.BF-4gkZK.woff +0 -0
  481. streamlit/static/static/media/KaTeX_Size4-Regular.DWFBv043.ttf +0 -0
  482. streamlit/static/static/media/KaTeX_Size4-Regular.Dl5lxZxV.woff2 +0 -0
  483. streamlit/static/static/media/KaTeX_Typewriter-Regular.C0xS9mPB.woff +0 -0
  484. streamlit/static/static/media/KaTeX_Typewriter-Regular.CO6r4hn1.woff2 +0 -0
  485. streamlit/static/static/media/KaTeX_Typewriter-Regular.D3Ib7_Hf.ttf +0 -0
  486. streamlit/static/static/media/MaterialSymbols-Rounded.DcZbplWk.woff2 +0 -0
  487. streamlit/static/static/media/SourceCodePro-Bold.CFEfr7-q.woff2 +0 -0
  488. streamlit/static/static/media/SourceCodePro-BoldItalic.C-LkFXxa.woff2 +0 -0
  489. streamlit/static/static/media/SourceCodePro-Italic.CxFOx7N-.woff2 +0 -0
  490. streamlit/static/static/media/SourceCodePro-Regular.CBOlD63d.woff2 +0 -0
  491. streamlit/static/static/media/SourceCodePro-SemiBold.CFHwW3Wd.woff2 +0 -0
  492. streamlit/static/static/media/SourceCodePro-SemiBoldItalic.Cg2yRu82.woff2 +0 -0
  493. streamlit/static/static/media/SourceSansPro-Bold.-6c9oR8J.woff2 +0 -0
  494. streamlit/static/static/media/SourceSansPro-BoldItalic.DmM_grLY.woff2 +0 -0
  495. streamlit/static/static/media/SourceSansPro-Italic.I1ipWe7Q.woff2 +0 -0
  496. streamlit/static/static/media/SourceSansPro-Regular.DZLUzqI4.woff2 +0 -0
  497. streamlit/static/static/media/SourceSansPro-SemiBold.sKQIyTMz.woff2 +0 -0
  498. streamlit/static/static/media/SourceSansPro-SemiBoldItalic.C0wP0icr.woff2 +0 -0
  499. streamlit/static/static/media/SourceSerifPro-Bold.8TUnKj4x.woff2 +0 -0
  500. streamlit/static/static/media/SourceSerifPro-BoldItalic.CBVO7Ve7.woff2 +0 -0
  501. streamlit/static/static/media/SourceSerifPro-Italic.DkFgL2HZ.woff2 +0 -0
  502. streamlit/static/static/media/SourceSerifPro-Regular.CNJNET2S.woff2 +0 -0
  503. streamlit/static/static/media/SourceSerifPro-SemiBold.CHyh9GC5.woff2 +0 -0
  504. streamlit/static/static/media/SourceSerifPro-SemiBoldItalic.CBtz8sWN.woff2 +0 -0
  505. streamlit/static/static/media/balloon-0.Czj7AKwE.png +0 -0
  506. streamlit/static/static/media/balloon-1.CNvFFrND.png +0 -0
  507. streamlit/static/static/media/balloon-2.DTvC6B1t.png +0 -0
  508. streamlit/static/static/media/balloon-3.CgSk4tbL.png +0 -0
  509. streamlit/static/static/media/balloon-4.mbtFrzxf.png +0 -0
  510. streamlit/static/static/media/balloon-5.CSwkUfRA.png +0 -0
  511. streamlit/static/static/media/fireworks.B4d-_KUe.gif +0 -0
  512. streamlit/static/static/media/flake-0.DgWaVvm5.png +0 -0
  513. streamlit/static/static/media/flake-1.B2r5AHMK.png +0 -0
  514. streamlit/static/static/media/flake-2.BnWSExPC.png +0 -0
  515. streamlit/static/static/media/snowflake.JU2jBHL8.svg +11 -0
  516. streamlit/string_util.py +203 -0
  517. streamlit/temporary_directory.py +56 -0
  518. streamlit/testing/__init__.py +13 -0
  519. streamlit/testing/v1/__init__.py +17 -0
  520. streamlit/testing/v1/app_test.py +1050 -0
  521. streamlit/testing/v1/element_tree.py +2083 -0
  522. streamlit/testing/v1/local_script_runner.py +180 -0
  523. streamlit/testing/v1/util.py +53 -0
  524. streamlit/time_util.py +75 -0
  525. streamlit/type_util.py +460 -0
  526. streamlit/url_util.py +122 -0
  527. streamlit/user_info.py +519 -0
  528. streamlit/util.py +72 -0
  529. streamlit/vendor/__init__.py +0 -0
  530. streamlit/vendor/pympler/__init__.py +0 -0
  531. streamlit/vendor/pympler/asizeof.py +2869 -0
  532. streamlit/version.py +18 -0
  533. streamlit/watcher/__init__.py +28 -0
  534. streamlit/watcher/event_based_path_watcher.py +406 -0
  535. streamlit/watcher/folder_black_list.py +82 -0
  536. streamlit/watcher/local_sources_watcher.py +233 -0
  537. streamlit/watcher/path_watcher.py +185 -0
  538. streamlit/watcher/polling_path_watcher.py +124 -0
  539. streamlit/watcher/util.py +207 -0
  540. streamlit/web/__init__.py +13 -0
  541. streamlit/web/bootstrap.py +353 -0
  542. streamlit/web/cache_storage_manager_config.py +38 -0
  543. streamlit/web/cli.py +369 -0
  544. streamlit/web/server/__init__.py +26 -0
  545. streamlit/web/server/app_static_file_handler.py +93 -0
  546. streamlit/web/server/authlib_tornado_integration.py +60 -0
  547. streamlit/web/server/browser_websocket_handler.py +246 -0
  548. streamlit/web/server/component_request_handler.py +116 -0
  549. streamlit/web/server/media_file_handler.py +141 -0
  550. streamlit/web/server/oauth_authlib_routes.py +176 -0
  551. streamlit/web/server/oidc_mixin.py +108 -0
  552. streamlit/web/server/routes.py +295 -0
  553. streamlit/web/server/server.py +479 -0
  554. streamlit/web/server/server_util.py +161 -0
  555. streamlit/web/server/stats_request_handler.py +95 -0
  556. streamlit/web/server/upload_file_request_handler.py +137 -0
  557. streamlit/web/server/websocket_headers.py +56 -0
  558. streamlit_nightly-1.43.2.dev20250307.data/scripts/streamlit.cmd +16 -0
  559. streamlit_nightly-1.43.2.dev20250307.dist-info/METADATA +207 -0
  560. streamlit_nightly-1.43.2.dev20250307.dist-info/RECORD +563 -0
  561. streamlit_nightly-1.43.2.dev20250307.dist-info/WHEEL +5 -0
  562. streamlit_nightly-1.43.2.dev20250307.dist-info/entry_points.txt +2 -0
  563. streamlit_nightly-1.43.2.dev20250307.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1984 @@
1
+ # Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022-2025)
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Collection of chart commands that are rendered via our vega-lite chart component."""
16
+
17
+ from __future__ import annotations
18
+
19
+ import json
20
+ import re
21
+ from contextlib import nullcontext
22
+ from dataclasses import dataclass
23
+ from typing import (
24
+ TYPE_CHECKING,
25
+ Any,
26
+ Final,
27
+ Literal,
28
+ TypedDict,
29
+ Union,
30
+ cast,
31
+ overload,
32
+ )
33
+
34
+ from typing_extensions import TypeAlias
35
+
36
+ import streamlit.elements.lib.dicttools as dicttools
37
+ from streamlit import dataframe_util, type_util
38
+ from streamlit.elements.lib.built_in_chart_utils import (
39
+ AddRowsMetadata,
40
+ ChartStackType,
41
+ ChartType,
42
+ generate_chart,
43
+ maybe_raise_stack_warning,
44
+ )
45
+ from streamlit.elements.lib.event_utils import AttributeDictionary
46
+ from streamlit.elements.lib.form_utils import current_form_id
47
+ from streamlit.elements.lib.policies import check_widget_policies
48
+ from streamlit.elements.lib.utils import Key, compute_and_register_element_id, to_key
49
+ from streamlit.errors import StreamlitAPIException
50
+ from streamlit.proto.ArrowVegaLiteChart_pb2 import (
51
+ ArrowVegaLiteChart as ArrowVegaLiteChartProto,
52
+ )
53
+ from streamlit.runtime.metrics_util import gather_metrics
54
+ from streamlit.runtime.scriptrunner_utils.script_run_context import get_script_run_ctx
55
+ from streamlit.runtime.state import WidgetCallback, register_widget
56
+ from streamlit.util import calc_md5
57
+
58
+ if TYPE_CHECKING:
59
+ from collections.abc import Iterable, Sequence
60
+
61
+ import altair as alt
62
+
63
+ from streamlit.dataframe_util import Data
64
+ from streamlit.delta_generator import DeltaGenerator
65
+ from streamlit.elements.lib.color_util import Color
66
+
67
+ # See https://vega.github.io/vega-lite/docs/encoding.html
68
+ _CHANNELS: Final = {
69
+ "x",
70
+ "y",
71
+ "x2",
72
+ "y2",
73
+ "xError",
74
+ "xError2",
75
+ "yError",
76
+ "yError2",
77
+ "longitude",
78
+ "latitude",
79
+ "color",
80
+ "opacity",
81
+ "fillOpacity",
82
+ "strokeOpacity",
83
+ "strokeWidth",
84
+ "size",
85
+ "shape",
86
+ "text",
87
+ "tooltip",
88
+ "href",
89
+ "key",
90
+ "order",
91
+ "detail",
92
+ "facet",
93
+ "row",
94
+ "column",
95
+ }
96
+
97
+ VegaLiteSpec: TypeAlias = "dict[str, Any]"
98
+ AltairChart: TypeAlias = Union[
99
+ "alt.Chart",
100
+ "alt.ConcatChart",
101
+ "alt.FacetChart",
102
+ "alt.HConcatChart",
103
+ "alt.LayerChart",
104
+ "alt.RepeatChart",
105
+ "alt.VConcatChart",
106
+ ]
107
+
108
+
109
+ class VegaLiteState(TypedDict, total=False):
110
+ """
111
+ The schema for the Vega-Lite event state.
112
+
113
+ The event state is stored in a dictionary-like object that supports both
114
+ key and attribute notation. Event states cannot be programmatically
115
+ changed or set through Session State.
116
+
117
+ Only selection events are supported at this time.
118
+
119
+ Attributes
120
+ ----------
121
+ selection : dict
122
+ The state of the ``on_select`` event. This attribute returns a
123
+ dictionary-like object that supports both key and attribute notation.
124
+ The name of each Vega-Lite selection parameter becomes an attribute in
125
+ the ``selection`` dictionary. The format of the data within each
126
+ attribute is determined by the selection parameter definition within
127
+ Vega-Lite.
128
+
129
+ Examples
130
+ --------
131
+ The following two examples have equivalent definitions. Each one has a
132
+ point and interval selection parameter include in the chart definition.
133
+ The point selection parameter is named ``"point_selection"``. The interval
134
+ or box selection parameter is named ``"interval_selection"``.
135
+
136
+ The follow example uses ``st.altair_chart``:
137
+
138
+ >>> import streamlit as st
139
+ >>> import pandas as pd
140
+ >>> import numpy as np
141
+ >>> import altair as alt
142
+ >>>
143
+ >>> if "data" not in st.session_state:
144
+ >>> st.session_state.data = pd.DataFrame(
145
+ ... np.random.randn(20, 3), columns=["a", "b", "c"]
146
+ ... )
147
+ >>> df = st.session_state.data
148
+ >>>
149
+ >>> point_selector = alt.selection_point("point_selection")
150
+ >>> interval_selector = alt.selection_interval("interval_selection")
151
+ >>> chart = (
152
+ ... alt.Chart(df)
153
+ ... .mark_circle()
154
+ ... .encode(
155
+ ... x="a",
156
+ ... y="b",
157
+ ... size="c",
158
+ ... color="c",
159
+ ... tooltip=["a", "b", "c"],
160
+ ... fillOpacity=alt.condition(point_selector, alt.value(1), alt.value(0.3)),
161
+ ... )
162
+ ... .add_params(point_selector, interval_selector)
163
+ ... )
164
+ >>>
165
+ >>> event = st.altair_chart(chart, key="alt_chart", on_select="rerun")
166
+ >>>
167
+ >>> event
168
+
169
+ The following example uses ``st.vega_lite_chart``:
170
+
171
+ >>> import streamlit as st
172
+ >>> import pandas as pd
173
+ >>> import numpy as np
174
+ >>>
175
+ >>> if "data" not in st.session_state:
176
+ >>> st.session_state.data = pd.DataFrame(
177
+ ... np.random.randn(20, 3), columns=["a", "b", "c"]
178
+ ... )
179
+ >>>
180
+ >>> spec = {
181
+ ... "mark": {"type": "circle", "tooltip": True},
182
+ ... "params": [
183
+ ... {"name": "interval_selection", "select": "interval"},
184
+ ... {"name": "point_selection", "select": "point"},
185
+ ... ],
186
+ ... "encoding": {
187
+ ... "x": {"field": "a", "type": "quantitative"},
188
+ ... "y": {"field": "b", "type": "quantitative"},
189
+ ... "size": {"field": "c", "type": "quantitative"},
190
+ ... "color": {"field": "c", "type": "quantitative"},
191
+ ... "fillOpacity": {
192
+ ... "condition": {"param": "point_selection", "value": 1},
193
+ ... "value": 0.3,
194
+ ... },
195
+ ... },
196
+ ... }
197
+ >>>
198
+ >>> event = st.vega_lite_chart(
199
+ ... st.session_state.data, spec, key="vega_chart", on_select="rerun"
200
+ ... )
201
+ >>>
202
+ >>> event
203
+
204
+ Try selecting points in this interactive example. When you click a point,
205
+ the selection will appear under the attribute, ``"point_selection"``, which
206
+ is the name given to the point selection parameter. Similarly, when you
207
+ make an interval selection, it will appear under the attribute
208
+ ``"interval_selection"``. You can give your selection parameters other
209
+ names if desired.
210
+
211
+ If you hold ``Shift`` while selecting points, existing point selections
212
+ will be preserved. Interval selections are not preserved when making
213
+ additional selections.
214
+
215
+ .. output::
216
+ https://doc-chart-events-vega-lite-state.streamlit.app
217
+ height: 600px
218
+
219
+ """
220
+
221
+ selection: AttributeDictionary
222
+
223
+
224
+ @dataclass
225
+ class VegaLiteStateSerde:
226
+ """VegaLiteStateSerde is used to serialize and deserialize the VegaLite Chart state."""
227
+
228
+ selection_parameters: Sequence[str]
229
+
230
+ def deserialize(self, ui_value: str | None, widget_id: str = "") -> VegaLiteState:
231
+ empty_selection_state: VegaLiteState = {
232
+ "selection": AttributeDictionary(
233
+ # Initialize the select state with empty dictionaries for each selection parameter.
234
+ {param: {} for param in self.selection_parameters}
235
+ ),
236
+ }
237
+
238
+ selection_state = (
239
+ empty_selection_state
240
+ if ui_value is None
241
+ else cast(VegaLiteState, AttributeDictionary(json.loads(ui_value)))
242
+ )
243
+
244
+ if "selection" not in selection_state:
245
+ selection_state = empty_selection_state
246
+
247
+ return cast(VegaLiteState, AttributeDictionary(selection_state))
248
+
249
+ def serialize(self, selection_state: VegaLiteState) -> str:
250
+ return json.dumps(selection_state, default=str)
251
+
252
+
253
+ def _prepare_vega_lite_spec(
254
+ spec: VegaLiteSpec,
255
+ use_container_width: bool,
256
+ **kwargs,
257
+ ) -> VegaLiteSpec:
258
+ if len(kwargs):
259
+ # Support passing in kwargs. Example:
260
+ # marshall(proto, {foo: 'bar'}, baz='boz')
261
+ # Merge spec with unflattened kwargs, where kwargs take precedence.
262
+ # This only works for string keys, but kwarg keys are strings anyways.
263
+ spec = dict(spec, **dicttools.unflatten(kwargs, _CHANNELS))
264
+ else:
265
+ # Clone the spec dict, since we may be mutating it.
266
+ spec = dict(spec)
267
+
268
+ if len(spec) == 0:
269
+ raise StreamlitAPIException("Vega-Lite charts require a non-empty spec dict.")
270
+
271
+ if "autosize" not in spec:
272
+ # type fit does not work for many chart types. This change focuses
273
+ # on vconcat with use_container_width=True as there are unintended
274
+ # consequences of changing the default autosize for all charts.
275
+ # fit-x fits the width and height can be adjusted.
276
+ if "vconcat" in spec and use_container_width:
277
+ spec["autosize"] = {"type": "fit-x", "contains": "padding"}
278
+ else:
279
+ spec["autosize"] = {"type": "fit", "contains": "padding"}
280
+
281
+ return spec
282
+
283
+
284
+ def _marshall_chart_data(
285
+ proto: ArrowVegaLiteChartProto,
286
+ spec: VegaLiteSpec,
287
+ data: Data = None,
288
+ ) -> None:
289
+ """Adds the data to the proto and removes it from the spec dict.
290
+ These operations will happen in-place."""
291
+
292
+ # Pull data out of spec dict when it's in a 'datasets' key:
293
+ # datasets: {foo: df1_bytes, bar: df2_bytes}, ...}
294
+ if "datasets" in spec:
295
+ for dataset_name, dataset_data in spec["datasets"].items():
296
+ dataset = proto.datasets.add()
297
+ dataset.name = str(dataset_name)
298
+ dataset.has_name = True
299
+ # The ID transformer (id_transform function registered before conversion to dict)
300
+ # already serializes the data into Arrow IPC format (bytes) when the Altair object
301
+ # gets converted into the vega-lite spec dict.
302
+ # If its already in bytes, we don't need to serialize it here again.
303
+ # We just need to pass the data information into the correct proto fields.
304
+
305
+ # TODO(lukasmasuch): Are there any other cases where we need to serialize the data
306
+ # or can we remove the convert_anything_to_arrow_bytes here?
307
+ dataset.data.data = (
308
+ dataset_data
309
+ if isinstance(dataset_data, bytes)
310
+ else dataframe_util.convert_anything_to_arrow_bytes(dataset_data)
311
+ )
312
+ del spec["datasets"]
313
+
314
+ # Pull data out of spec dict when it's in a top-level 'data' key:
315
+ # {data: df}
316
+ # {data: {values: df, ...}}
317
+ # {data: {url: 'url'}}
318
+ # {data: {name: 'foo'}}
319
+ if "data" in spec:
320
+ data_spec = spec["data"]
321
+
322
+ if isinstance(data_spec, dict):
323
+ if "values" in data_spec:
324
+ data = data_spec["values"]
325
+ del spec["data"]
326
+ else:
327
+ data = data_spec
328
+ del spec["data"]
329
+
330
+ if data is not None:
331
+ proto.data.data = dataframe_util.convert_anything_to_arrow_bytes(data)
332
+
333
+
334
+ def _convert_altair_to_vega_lite_spec(
335
+ altair_chart: AltairChart,
336
+ ) -> VegaLiteSpec:
337
+ """Convert an Altair chart object to a Vega-Lite chart spec."""
338
+ import altair as alt
339
+
340
+ # Normally altair_chart.to_dict() would transform the dataframe used by the
341
+ # chart into an array of dictionaries. To avoid that, we install a
342
+ # transformer that replaces datasets with a reference by the object id of
343
+ # the dataframe. We then fill in the dataset manually later on.
344
+
345
+ datasets = {}
346
+
347
+ def id_transform(data) -> dict[str, str]:
348
+ """Altair data transformer that serializes the data,
349
+ creates a stable name based on the hash of the data,
350
+ stores the bytes into the datasets mapping and
351
+ returns this name to have it be used in Altair.
352
+ """
353
+ # Already serialize the data to be able to create a stable
354
+ # dataset name:
355
+ data_bytes = dataframe_util.convert_anything_to_arrow_bytes(data)
356
+ # Use the md5 hash of the data as the name:
357
+ name = calc_md5(str(data_bytes))
358
+
359
+ datasets[name] = data_bytes
360
+ return {"name": name}
361
+
362
+ alt.data_transformers.register("id", id_transform) # type: ignore[attr-defined,unused-ignore]
363
+
364
+ # The default altair theme has some width/height defaults defined
365
+ # which are not useful for Streamlit. Therefore, we change the theme to
366
+ # "none" to avoid those defaults.
367
+ with alt.themes.enable("none") if alt.themes.active == "default" else nullcontext(): # type: ignore[attr-defined,unused-ignore]
368
+ with alt.data_transformers.enable("id"): # type: ignore[attr-defined,unused-ignore]
369
+ chart_dict = altair_chart.to_dict()
370
+
371
+ # Put datasets back into the chart dict:
372
+ chart_dict["datasets"] = datasets
373
+ return chart_dict
374
+
375
+
376
+ def _disallow_multi_view_charts(spec: VegaLiteSpec) -> None:
377
+ """Raise an exception if the spec contains a multi-view chart (view composition).
378
+
379
+ This is intended to be used as a temporary solution to prevent selections on
380
+ multi-view charts. There are too many edge cases to handle selections on these
381
+ charts correctly, so we're disallowing them for now.
382
+
383
+ More information about view compositions: https://vega.github.io/vega-lite/docs/composition.html
384
+ """
385
+
386
+ if (
387
+ any(key in spec for key in ["layer", "hconcat", "vconcat", "concat", "spec"])
388
+ or "encoding" not in spec
389
+ ):
390
+ raise StreamlitAPIException(
391
+ "Selections are not yet supported for multi-view charts (chart compositions). "
392
+ "If you would like to use selections on multi-view charts, please upvote "
393
+ "this [Github issue](https://github.com/streamlit/streamlit/issues/8643)."
394
+ )
395
+
396
+
397
+ def _extract_selection_parameters(spec: VegaLiteSpec) -> set[str]:
398
+ """Extract the names of all valid selection parameters from the spec."""
399
+ if not spec or "params" not in spec:
400
+ return set()
401
+
402
+ param_names = set()
403
+
404
+ for param in spec["params"]:
405
+ # Check if it looks like a valid selection parameter:
406
+ # https://vega.github.io/vega-lite/docs/selection.html
407
+ if param.get("name") and param.get("select"):
408
+ # Selection found, just return here to not show the exception.
409
+ param_names.add(param["name"])
410
+
411
+ return param_names
412
+
413
+
414
+ def _parse_selection_mode(
415
+ spec: VegaLiteSpec,
416
+ selection_mode: str | Iterable[str] | None,
417
+ ) -> list[str]:
418
+ """Parse and check the user provided selection modes.
419
+
420
+ This will raise an exception if no valid selection parameters are found in the spec
421
+ or if the user provided selection modes are not defined in the spec.
422
+
423
+ Parameters
424
+ ----------
425
+ spec : VegaLiteSpec
426
+ The Vega-Lite chart specification.
427
+
428
+ selection_mode : str, Iterable[str], or None
429
+ The user provided selection mode(s).
430
+
431
+ Returns
432
+ -------
433
+ list[str]
434
+ The parsed selection mode(s) that should be activated.
435
+ """
436
+
437
+ # Extract all selection parameters from the spec:
438
+ all_selection_params = _extract_selection_parameters(spec)
439
+
440
+ if not all_selection_params:
441
+ raise StreamlitAPIException(
442
+ "Selections are activated, but the provided chart spec does not "
443
+ "have any selections defined. To add selections to `st.altair_chart`, check out the documentation "
444
+ "[here](https://altair-viz.github.io/user_guide/interactions.html#selections-capturing-chart-interactions). "
445
+ "For adding selections to `st.vega_lite_chart`, take a look "
446
+ "at the specification [here](https://vega.github.io/vega-lite/docs/selection.html)."
447
+ )
448
+
449
+ if selection_mode is None:
450
+ # Activate all selection parameters:
451
+ return sorted(all_selection_params)
452
+
453
+ if isinstance(selection_mode, str):
454
+ # Convert single string to list:
455
+ selection_mode = [selection_mode]
456
+
457
+ # Check that all provided selection parameters are defined in the spec:
458
+ for selection_name in selection_mode:
459
+ if selection_name not in all_selection_params:
460
+ raise StreamlitAPIException(
461
+ f"Selection parameter '{selection_name}' is not defined in the chart "
462
+ f"spec. Available selection parameters are: {all_selection_params}."
463
+ )
464
+ return sorted(selection_mode)
465
+
466
+
467
+ def _reset_counter_pattern(prefix: str, vega_spec: str) -> str:
468
+ """Altair uses a global counter for unnamed parameters and views.
469
+ We need to reset these counters on a spec-level to make the
470
+ spec stable across reruns and avoid changes to the element ID.
471
+ """
472
+ pattern = re.compile(rf'"{prefix}\d+"')
473
+ # Get all matches without duplicates in order of appearance.
474
+ # Using a set here would not guarantee the order of appearance,
475
+ # which might lead to different replacements on each run.
476
+ # The order of the spec from Altair is expected to stay stable
477
+ # within the same session / Altair version.
478
+ # The order might change with Altair updates, but that's not really
479
+ # a case that is relevant for us since we mainly care about having
480
+ # this stable within a session.
481
+ if matches := list(dict.fromkeys(pattern.findall(vega_spec))):
482
+ # Add a prefix to the replacement to avoid
483
+ # replacing instances that already have been replaced before.
484
+ # The prefix here is arbitrarily chosen with the main goal
485
+ # that its extremely unlikely to already be part of the spec:
486
+ replacement_prefix = "__replace_prefix_o9hd101n22e1__"
487
+
488
+ # Replace all matches with a counter starting from 1
489
+ # We start from 1 to imitate the altair behavior.
490
+ for counter, match in enumerate(matches, start=1):
491
+ vega_spec = vega_spec.replace(
492
+ match, f'"{replacement_prefix}{prefix}{counter}"'
493
+ )
494
+
495
+ # Remove the prefix again from all replacements:
496
+ vega_spec = vega_spec.replace(replacement_prefix, "")
497
+ return vega_spec
498
+
499
+
500
+ def _stabilize_vega_json_spec(vega_spec: str) -> str:
501
+ """Makes the chart spec stay stable across reruns and sessions.
502
+
503
+ Altair auto creates names for unnamed parameters & views. It uses a global counter
504
+ for the naming which will result in a different spec on every rerun.
505
+ In Streamlit, we need the spec to be stable across reruns and sessions to prevent the chart
506
+ from getting a new identity. So we need to replace the names with counter with a stable name.
507
+ Having a stable chart spec is also important for features like forward message cache,
508
+ where we don't want to have changing messages on every rerun.
509
+
510
+ Parameter counter:
511
+ https://github.com/vega/altair/blob/f345cd9368ae2bbc98628e9245c93fa9fb582621/altair/vegalite/v5/api.py#L196
512
+
513
+ View counter:
514
+ https://github.com/vega/altair/blob/f345cd9368ae2bbc98628e9245c93fa9fb582621/altair/vegalite/v5/api.py#L2885
515
+
516
+ This is temporary solution waiting for a fix for this issue:
517
+ https://github.com/vega/altair/issues/3416
518
+
519
+ Other solutions we considered:
520
+ - working on the dict object: this would require to iterate through the object and do the
521
+ same kind of replacement; though we would need to know the structure and since we need
522
+ the spec in String-format anyways, we deemed that executing the replacement on the
523
+ String is the better alternative
524
+ - resetting the counter: the counter is incremented already when the chart object is created
525
+ (see this GitHub issue comment https://github.com/vega/altair/issues/3416#issuecomment-2098530464),
526
+ so it would be too late here to reset the counter with a thread-lock to prevent interference
527
+ between sessions
528
+ """
529
+
530
+ # We only want to apply these replacements if it is really necessary
531
+ # since there is a risk that we replace names that where chosen by the user
532
+ # and thereby introduce unwanted side effects.
533
+
534
+ # We only need to apply the param_ fix if there are actually parameters defined
535
+ # somewhere in the spec. We can check for this by looking for the '"params"' key.
536
+ # This isn't a perfect check, but good enough to prevent unnecessary executions
537
+ # for the majority of charts.
538
+ if '"params"' in vega_spec:
539
+ vega_spec = _reset_counter_pattern("param_", vega_spec)
540
+
541
+ # Simple check if the spec contains a composite chart:
542
+ # https://vega.github.io/vega-lite/docs/composition.html
543
+ # Other charts will not contain the `view_` name,
544
+ # so its better to not replace this pattern.
545
+ if re.search(r'"(vconcat|hconcat|facet|layer|concat|repeat)"', vega_spec):
546
+ vega_spec = _reset_counter_pattern("view_", vega_spec)
547
+ return vega_spec
548
+
549
+
550
+ class VegaChartsMixin:
551
+ """Mix-in class for all vega-related chart commands.
552
+
553
+ Altair is a python wrapper on top of the vega-lite spec. And our
554
+ built-in chart commands are just another layer on-top of Altair.
555
+ All of these chart commands will be eventually converted to a vega-lite
556
+ spec and rendered using the same vega-lite chart component.
557
+ """
558
+
559
+ @gather_metrics("line_chart")
560
+ def line_chart(
561
+ self,
562
+ data: Data = None,
563
+ *,
564
+ x: str | None = None,
565
+ y: str | Sequence[str] | None = None,
566
+ x_label: str | None = None,
567
+ y_label: str | None = None,
568
+ color: str | Color | list[Color] | None = None,
569
+ width: int | None = None,
570
+ height: int | None = None,
571
+ use_container_width: bool = True,
572
+ ) -> DeltaGenerator:
573
+ """Display a line chart.
574
+
575
+ This is syntax-sugar around ``st.altair_chart``. The main difference
576
+ is this command uses the data's own column and indices to figure out
577
+ the chart's Altair spec. As a result this is easier to use for many
578
+ "just plot this" scenarios, while being less customizable.
579
+
580
+ If ``st.line_chart`` does not guess the data specification
581
+ correctly, try specifying your desired chart using ``st.altair_chart``.
582
+
583
+ Parameters
584
+ ----------
585
+ data : Anything supported by st.dataframe
586
+ Data to be plotted.
587
+
588
+ x : str or None
589
+ Column name or key associated to the x-axis data. If ``x`` is
590
+ ``None`` (default), Streamlit uses the data index for the x-axis
591
+ values.
592
+
593
+ y : str, Sequence of str, or None
594
+ Column name(s) or key(s) associated to the y-axis data. If this is
595
+ ``None`` (default), Streamlit draws the data of all remaining
596
+ columns as data series. If this is a ``Sequence`` of strings,
597
+ Streamlit draws several series on the same chart by melting your
598
+ wide-format table into a long-format table behind the scenes.
599
+
600
+ x_label : str or None
601
+ The label for the x-axis. If this is ``None`` (default), Streamlit
602
+ will use the column name specified in ``x`` if available, or else
603
+ no label will be displayed.
604
+
605
+ y_label : str or None
606
+ The label for the y-axis. If this is ``None`` (default), Streamlit
607
+ will use the column name(s) specified in ``y`` if available, or
608
+ else no label will be displayed.
609
+
610
+ color : str, tuple, Sequence of str, Sequence of tuple, or None
611
+ The color to use for different lines in this chart.
612
+
613
+ For a line chart with just one line, this can be:
614
+
615
+ - None, to use the default color.
616
+ - A hex string like "#ffaa00" or "#ffaa0088".
617
+ - An RGB or RGBA tuple with the red, green, blue, and alpha
618
+ components specified as ints from 0 to 255 or floats from 0.0 to
619
+ 1.0.
620
+
621
+ For a line chart with multiple lines, where the dataframe is in
622
+ long format (that is, y is None or just one column), this can be:
623
+
624
+ - None, to use the default colors.
625
+ - The name of a column in the dataset. Data points will be grouped
626
+ into lines of the same color based on the value of this column.
627
+ In addition, if the values in this column match one of the color
628
+ formats above (hex string or color tuple), then that color will
629
+ be used.
630
+
631
+ For example: if the dataset has 1000 rows, but this column only
632
+ contains the values "adult", "child", and "baby", then those 1000
633
+ datapoints will be grouped into three lines whose colors will be
634
+ automatically selected from the default palette.
635
+
636
+ But, if for the same 1000-row dataset, this column contained
637
+ the values "#ffaa00", "#f0f", "#0000ff", then then those 1000
638
+ datapoints would still be grouped into three lines, but their
639
+ colors would be "#ffaa00", "#f0f", "#0000ff" this time around.
640
+
641
+ For a line chart with multiple lines, where the dataframe is in
642
+ wide format (that is, y is a Sequence of columns), this can be:
643
+
644
+ - None, to use the default colors.
645
+ - A list of string colors or color tuples to be used for each of
646
+ the lines in the chart. This list should have the same length
647
+ as the number of y values (e.g. ``color=["#fd0", "#f0f", "#04f"]``
648
+ for three lines).
649
+
650
+ width : int or None
651
+ Desired width of the chart expressed in pixels. If ``width`` is
652
+ ``None`` (default), Streamlit sets the width of the chart to fit
653
+ its contents according to the plotting library, up to the width of
654
+ the parent container. If ``width`` is greater than the width of the
655
+ parent container, Streamlit sets the chart width to match the width
656
+ of the parent container.
657
+
658
+ To use ``width``, you must set ``use_container_width=False``.
659
+
660
+ height : int or None
661
+ Desired height of the chart expressed in pixels. If ``height`` is
662
+ ``None`` (default), Streamlit sets the height of the chart to fit
663
+ its contents according to the plotting library.
664
+
665
+ use_container_width : bool
666
+ Whether to override ``width`` with the width of the parent
667
+ container. If ``use_container_width`` is ``True`` (default),
668
+ Streamlit sets the width of the chart to match the width of the
669
+ parent container. If ``use_container_width`` is ``False``,
670
+ Streamlit sets the chart's width according to ``width``.
671
+
672
+ Examples
673
+ --------
674
+ >>> import streamlit as st
675
+ >>> import pandas as pd
676
+ >>> import numpy as np
677
+ >>>
678
+ >>> chart_data = pd.DataFrame(np.random.randn(20, 3), columns=["a", "b", "c"])
679
+ >>>
680
+ >>> st.line_chart(chart_data)
681
+
682
+ .. output::
683
+ https://doc-line-chart.streamlit.app/
684
+ height: 440px
685
+
686
+ You can also choose different columns to use for x and y, as well as set
687
+ the color dynamically based on a 3rd column (assuming your dataframe is in
688
+ long format):
689
+
690
+ >>> import streamlit as st
691
+ >>> import pandas as pd
692
+ >>> import numpy as np
693
+ >>>
694
+ >>> chart_data = pd.DataFrame(
695
+ ... {
696
+ ... "col1": np.random.randn(20),
697
+ ... "col2": np.random.randn(20),
698
+ ... "col3": np.random.choice(["A", "B", "C"], 20),
699
+ ... }
700
+ ... )
701
+ >>>
702
+ >>> st.line_chart(chart_data, x="col1", y="col2", color="col3")
703
+
704
+ .. output::
705
+ https://doc-line-chart1.streamlit.app/
706
+ height: 440px
707
+
708
+ Finally, if your dataframe is in wide format, you can group multiple
709
+ columns under the y argument to show multiple lines with different
710
+ colors:
711
+
712
+ >>> import streamlit as st
713
+ >>> import pandas as pd
714
+ >>> import numpy as np
715
+ >>>
716
+ >>> chart_data = pd.DataFrame(
717
+ ... np.random.randn(20, 3), columns=["col1", "col2", "col3"]
718
+ ... )
719
+ >>>
720
+ >>> st.line_chart(
721
+ ... chart_data,
722
+ ... x="col1",
723
+ ... y=["col2", "col3"],
724
+ ... color=["#FF0000", "#0000FF"], # Optional
725
+ ... )
726
+
727
+ .. output::
728
+ https://doc-line-chart2.streamlit.app/
729
+ height: 440px
730
+
731
+ """
732
+
733
+ chart, add_rows_metadata = generate_chart(
734
+ chart_type=ChartType.LINE,
735
+ data=data,
736
+ x_from_user=x,
737
+ y_from_user=y,
738
+ x_axis_label=x_label,
739
+ y_axis_label=y_label,
740
+ color_from_user=color,
741
+ size_from_user=None,
742
+ width=width,
743
+ height=height,
744
+ )
745
+ return cast(
746
+ "DeltaGenerator",
747
+ self._altair_chart(
748
+ chart,
749
+ use_container_width=use_container_width,
750
+ theme="streamlit",
751
+ add_rows_metadata=add_rows_metadata,
752
+ ),
753
+ )
754
+
755
+ @gather_metrics("area_chart")
756
+ def area_chart(
757
+ self,
758
+ data: Data = None,
759
+ *,
760
+ x: str | None = None,
761
+ y: str | Sequence[str] | None = None,
762
+ x_label: str | None = None,
763
+ y_label: str | None = None,
764
+ color: str | Color | list[Color] | None = None,
765
+ stack: bool | ChartStackType | None = None,
766
+ width: int | None = None,
767
+ height: int | None = None,
768
+ use_container_width: bool = True,
769
+ ) -> DeltaGenerator:
770
+ """Display an area chart.
771
+
772
+ This is syntax-sugar around ``st.altair_chart``. The main difference
773
+ is this command uses the data's own column and indices to figure out
774
+ the chart's Altair spec. As a result this is easier to use for many
775
+ "just plot this" scenarios, while being less customizable.
776
+
777
+ If ``st.area_chart`` does not guess the data specification
778
+ correctly, try specifying your desired chart using ``st.altair_chart``.
779
+
780
+ Parameters
781
+ ----------
782
+ data : Anything supported by st.dataframe
783
+ Data to be plotted.
784
+
785
+ x : str or None
786
+ Column name or key associated to the x-axis data. If ``x`` is
787
+ ``None`` (default), Streamlit uses the data index for the x-axis
788
+ values.
789
+
790
+ y : str, Sequence of str, or None
791
+ Column name(s) or key(s) associated to the y-axis data. If this is
792
+ ``None`` (default), Streamlit draws the data of all remaining
793
+ columns as data series. If this is a ``Sequence`` of strings,
794
+ Streamlit draws several series on the same chart by melting your
795
+ wide-format table into a long-format table behind the scenes.
796
+
797
+ x_label : str or None
798
+ The label for the x-axis. If this is ``None`` (default), Streamlit
799
+ will use the column name specified in ``x`` if available, or else
800
+ no label will be displayed.
801
+
802
+ y_label : str or None
803
+ The label for the y-axis. If this is ``None`` (default), Streamlit
804
+ will use the column name(s) specified in ``y`` if available, or
805
+ else no label will be displayed.
806
+
807
+ color : str, tuple, Sequence of str, Sequence of tuple, or None
808
+ The color to use for different series in this chart.
809
+
810
+ For an area chart with just 1 series, this can be:
811
+
812
+ - None, to use the default color.
813
+ - A hex string like "#ffaa00" or "#ffaa0088".
814
+ - An RGB or RGBA tuple with the red, green, blue, and alpha
815
+ components specified as ints from 0 to 255 or floats from 0.0 to
816
+ 1.0.
817
+
818
+ For an area chart with multiple series, where the dataframe is in
819
+ long format (that is, y is None or just one column), this can be:
820
+
821
+ - None, to use the default colors.
822
+ - The name of a column in the dataset. Data points will be grouped
823
+ into series of the same color based on the value of this column.
824
+ In addition, if the values in this column match one of the color
825
+ formats above (hex string or color tuple), then that color will
826
+ be used.
827
+
828
+ For example: if the dataset has 1000 rows, but this column only
829
+ contains the values "adult", "child", and "baby", then those 1000
830
+ datapoints will be grouped into three series whose colors will be
831
+ automatically selected from the default palette.
832
+
833
+ But, if for the same 1000-row dataset, this column contained
834
+ the values "#ffaa00", "#f0f", "#0000ff", then then those 1000
835
+ datapoints would still be grouped into 3 series, but their
836
+ colors would be "#ffaa00", "#f0f", "#0000ff" this time around.
837
+
838
+ For an area chart with multiple series, where the dataframe is in
839
+ wide format (that is, y is a Sequence of columns), this can be:
840
+
841
+ - None, to use the default colors.
842
+ - A list of string colors or color tuples to be used for each of
843
+ the series in the chart. This list should have the same length
844
+ as the number of y values (e.g. ``color=["#fd0", "#f0f", "#04f"]``
845
+ for three lines).
846
+
847
+ stack : bool, "normalize", "center", or None
848
+ Whether to stack the areas. If this is ``None`` (default),
849
+ Streamlit uses Vega's default. Other values can be as follows:
850
+
851
+ - ``True``: The areas form a non-overlapping, additive stack within
852
+ the chart.
853
+ - ``False``: The areas overlap each other without stacking.
854
+ - ``"normalize"``: The areas are stacked and the total height is
855
+ normalized to 100% of the height of the chart.
856
+ - ``"center"``: The areas are stacked and shifted to center their
857
+ baseline, which creates a steamgraph.
858
+
859
+ width : int or None
860
+ Desired width of the chart expressed in pixels. If ``width`` is
861
+ ``None`` (default), Streamlit sets the width of the chart to fit
862
+ its contents according to the plotting library, up to the width of
863
+ the parent container. If ``width`` is greater than the width of the
864
+ parent container, Streamlit sets the chart width to match the width
865
+ of the parent container.
866
+
867
+ To use ``width``, you must set ``use_container_width=False``.
868
+
869
+ height : int or None
870
+ Desired height of the chart expressed in pixels. If ``height`` is
871
+ ``None`` (default), Streamlit sets the height of the chart to fit
872
+ its contents according to the plotting library.
873
+
874
+ use_container_width : bool
875
+ Whether to override ``width`` with the width of the parent
876
+ container. If ``use_container_width`` is ``True`` (default),
877
+ Streamlit sets the width of the chart to match the width of the
878
+ parent container. If ``use_container_width`` is ``False``,
879
+ Streamlit sets the chart's width according to ``width``.
880
+
881
+ Examples
882
+ --------
883
+ >>> import streamlit as st
884
+ >>> import pandas as pd
885
+ >>> import numpy as np
886
+ >>>
887
+ >>> chart_data = pd.DataFrame(np.random.randn(20, 3), columns=["a", "b", "c"])
888
+ >>>
889
+ >>> st.area_chart(chart_data)
890
+
891
+ .. output::
892
+ https://doc-area-chart.streamlit.app/
893
+ height: 440px
894
+
895
+ You can also choose different columns to use for x and y, as well as set
896
+ the color dynamically based on a 3rd column (assuming your dataframe is in
897
+ long format):
898
+
899
+ >>> import streamlit as st
900
+ >>> import pandas as pd
901
+ >>> import numpy as np
902
+ >>>
903
+ >>> chart_data = pd.DataFrame(
904
+ ... {
905
+ ... "col1": np.random.randn(20),
906
+ ... "col2": np.random.randn(20),
907
+ ... "col3": np.random.choice(["A", "B", "C"], 20),
908
+ ... }
909
+ ... )
910
+ >>>
911
+ >>> st.area_chart(chart_data, x="col1", y="col2", color="col3")
912
+
913
+ .. output::
914
+ https://doc-area-chart1.streamlit.app/
915
+ height: 440px
916
+
917
+ If your dataframe is in wide format, you can group multiple
918
+ columns under the y argument to show multiple series with different
919
+ colors:
920
+
921
+ >>> import streamlit as st
922
+ >>> import pandas as pd
923
+ >>> import numpy as np
924
+ >>>
925
+ >>> chart_data = pd.DataFrame(
926
+ ... np.random.randn(20, 3), columns=["col1", "col2", "col3"]
927
+ ... )
928
+ >>>
929
+ >>> st.area_chart(
930
+ ... chart_data,
931
+ ... x="col1",
932
+ ... y=["col2", "col3"],
933
+ ... color=["#FF0000", "#0000FF"], # Optional
934
+ ... )
935
+
936
+ .. output::
937
+ https://doc-area-chart2.streamlit.app/
938
+ height: 440px
939
+
940
+ You can adjust the stacking behavior by setting ``stack``. Create a
941
+ steamgraph:
942
+
943
+ >>> import streamlit as st
944
+ >>> from vega_datasets import data
945
+ >>>
946
+ >>> source = data.unemployment_across_industries()
947
+ >>>
948
+ >>> st.area_chart(source, x="date", y="count", color="series", stack="center")
949
+
950
+ .. output::
951
+ https://doc-area-chart-steamgraph.streamlit.app/
952
+ height: 440px
953
+
954
+ """
955
+
956
+ # Check that the stack parameter is valid, raise more informative error message if not
957
+ maybe_raise_stack_warning(
958
+ stack,
959
+ "st.area_chart",
960
+ "https://docs.streamlit.io/develop/api-reference/charts/st.area_chart",
961
+ )
962
+
963
+ # st.area_chart's stack=False option translates to a "layered" area chart for
964
+ # vega. We reserve stack=False for
965
+ # grouped/non-stacked bar charts, so we need to translate False to "layered"
966
+ # here. The default stack type was changed in vega-lite 5.14.1:
967
+ # https://github.com/vega/vega-lite/issues/9337
968
+ # To get the old behavior, we also need to set stack to layered as the
969
+ # default (if stack is None)
970
+ if stack is False or stack is None:
971
+ stack = "layered"
972
+
973
+ chart, add_rows_metadata = generate_chart(
974
+ chart_type=ChartType.AREA,
975
+ data=data,
976
+ x_from_user=x,
977
+ y_from_user=y,
978
+ x_axis_label=x_label,
979
+ y_axis_label=y_label,
980
+ color_from_user=color,
981
+ size_from_user=None,
982
+ width=width,
983
+ height=height,
984
+ stack=stack,
985
+ )
986
+ return cast(
987
+ "DeltaGenerator",
988
+ self._altair_chart(
989
+ chart,
990
+ use_container_width=use_container_width,
991
+ theme="streamlit",
992
+ add_rows_metadata=add_rows_metadata,
993
+ ),
994
+ )
995
+
996
+ @gather_metrics("bar_chart")
997
+ def bar_chart(
998
+ self,
999
+ data: Data = None,
1000
+ *,
1001
+ x: str | None = None,
1002
+ y: str | Sequence[str] | None = None,
1003
+ x_label: str | None = None,
1004
+ y_label: str | None = None,
1005
+ color: str | Color | list[Color] | None = None,
1006
+ horizontal: bool = False,
1007
+ stack: bool | ChartStackType | None = None,
1008
+ width: int | None = None,
1009
+ height: int | None = None,
1010
+ use_container_width: bool = True,
1011
+ ) -> DeltaGenerator:
1012
+ """Display a bar chart.
1013
+
1014
+ This is syntax-sugar around ``st.altair_chart``. The main difference
1015
+ is this command uses the data's own column and indices to figure out
1016
+ the chart's Altair spec. As a result this is easier to use for many
1017
+ "just plot this" scenarios, while being less customizable.
1018
+
1019
+ If ``st.bar_chart`` does not guess the data specification
1020
+ correctly, try specifying your desired chart using ``st.altair_chart``.
1021
+
1022
+ Parameters
1023
+ ----------
1024
+ data : Anything supported by st.dataframe
1025
+ Data to be plotted.
1026
+
1027
+ x : str or None
1028
+ Column name or key associated to the x-axis data. If ``x`` is
1029
+ ``None`` (default), Streamlit uses the data index for the x-axis
1030
+ values.
1031
+
1032
+ y : str, Sequence of str, or None
1033
+ Column name(s) or key(s) associated to the y-axis data. If this is
1034
+ ``None`` (default), Streamlit draws the data of all remaining
1035
+ columns as data series. If this is a ``Sequence`` of strings,
1036
+ Streamlit draws several series on the same chart by melting your
1037
+ wide-format table into a long-format table behind the scenes.
1038
+
1039
+ x_label : str or None
1040
+ The label for the x-axis. If this is ``None`` (default), Streamlit
1041
+ will use the column name specified in ``x`` if available, or else
1042
+ no label will be displayed.
1043
+
1044
+ y_label : str or None
1045
+ The label for the y-axis. If this is ``None`` (default), Streamlit
1046
+ will use the column name(s) specified in ``y`` if available, or
1047
+ else no label will be displayed.
1048
+
1049
+ color : str, tuple, Sequence of str, Sequence of tuple, or None
1050
+ The color to use for different series in this chart.
1051
+
1052
+ For a bar chart with just one series, this can be:
1053
+
1054
+ - None, to use the default color.
1055
+ - A hex string like "#ffaa00" or "#ffaa0088".
1056
+ - An RGB or RGBA tuple with the red, green, blue, and alpha
1057
+ components specified as ints from 0 to 255 or floats from 0.0 to
1058
+ 1.0.
1059
+
1060
+ For a bar chart with multiple series, where the dataframe is in
1061
+ long format (that is, y is None or just one column), this can be:
1062
+
1063
+ - None, to use the default colors.
1064
+ - The name of a column in the dataset. Data points will be grouped
1065
+ into series of the same color based on the value of this column.
1066
+ In addition, if the values in this column match one of the color
1067
+ formats above (hex string or color tuple), then that color will
1068
+ be used.
1069
+
1070
+ For example: if the dataset has 1000 rows, but this column only
1071
+ contains the values "adult", "child", and "baby", then those 1000
1072
+ datapoints will be grouped into three series whose colors will be
1073
+ automatically selected from the default palette.
1074
+
1075
+ But, if for the same 1000-row dataset, this column contained
1076
+ the values "#ffaa00", "#f0f", "#0000ff", then then those 1000
1077
+ datapoints would still be grouped into 3 series, but their
1078
+ colors would be "#ffaa00", "#f0f", "#0000ff" this time around.
1079
+
1080
+ For a bar chart with multiple series, where the dataframe is in
1081
+ wide format (that is, y is a Sequence of columns), this can be:
1082
+
1083
+ - None, to use the default colors.
1084
+ - A list of string colors or color tuples to be used for each of
1085
+ the series in the chart. This list should have the same length
1086
+ as the number of y values (e.g. ``color=["#fd0", "#f0f", "#04f"]``
1087
+ for three lines).
1088
+
1089
+ horizontal : bool
1090
+ Whether to make the bars horizontal. If this is ``False``
1091
+ (default), the bars display vertically. If this is ``True``,
1092
+ Streamlit swaps the x-axis and y-axis and the bars display
1093
+ horizontally.
1094
+
1095
+ stack : bool, "normalize", "center", "layered", or None
1096
+ Whether to stack the bars. If this is ``None`` (default),
1097
+ Streamlit uses Vega's default. Other values can be as follows:
1098
+
1099
+ - ``True``: The bars form a non-overlapping, additive stack within
1100
+ the chart.
1101
+ - ``False``: The bars display side by side.
1102
+ - ``"layered"``: The bars overlap each other without stacking.
1103
+ - ``"normalize"``: The bars are stacked and the total height is
1104
+ normalized to 100% of the height of the chart.
1105
+ - ``"center"``: The bars are stacked and shifted to center the
1106
+ total height around an axis.
1107
+
1108
+ width : int or None
1109
+ Desired width of the chart expressed in pixels. If ``width`` is
1110
+ ``None`` (default), Streamlit sets the width of the chart to fit
1111
+ its contents according to the plotting library, up to the width of
1112
+ the parent container. If ``width`` is greater than the width of the
1113
+ parent container, Streamlit sets the chart width to match the width
1114
+ of the parent container.
1115
+
1116
+ To use ``width``, you must set ``use_container_width=False``.
1117
+
1118
+ height : int or None
1119
+ Desired height of the chart expressed in pixels. If ``height`` is
1120
+ ``None`` (default), Streamlit sets the height of the chart to fit
1121
+ its contents according to the plotting library.
1122
+
1123
+ use_container_width : bool
1124
+ Whether to override ``width`` with the width of the parent
1125
+ container. If ``use_container_width`` is ``True`` (default),
1126
+ Streamlit sets the width of the chart to match the width of the
1127
+ parent container. If ``use_container_width`` is ``False``,
1128
+ Streamlit sets the chart's width according to ``width``.
1129
+
1130
+ Examples
1131
+ --------
1132
+ >>> import streamlit as st
1133
+ >>> import pandas as pd
1134
+ >>> import numpy as np
1135
+ >>>
1136
+ >>> chart_data = pd.DataFrame(np.random.randn(20, 3), columns=["a", "b", "c"])
1137
+ >>>
1138
+ >>> st.bar_chart(chart_data)
1139
+
1140
+ .. output::
1141
+ https://doc-bar-chart.streamlit.app/
1142
+ height: 440px
1143
+
1144
+ You can also choose different columns to use for x and y, as well as set
1145
+ the color dynamically based on a 3rd column (assuming your dataframe is in
1146
+ long format):
1147
+
1148
+ >>> import streamlit as st
1149
+ >>> import pandas as pd
1150
+ >>> import numpy as np
1151
+ >>>
1152
+ >>> chart_data = pd.DataFrame(
1153
+ ... {
1154
+ ... "col1": list(range(20)) * 3,
1155
+ ... "col2": np.random.randn(60),
1156
+ ... "col3": ["A"] * 20 + ["B"] * 20 + ["C"] * 20,
1157
+ ... }
1158
+ ... )
1159
+ >>>
1160
+ >>> st.bar_chart(chart_data, x="col1", y="col2", color="col3")
1161
+
1162
+ .. output::
1163
+ https://doc-bar-chart1.streamlit.app/
1164
+ height: 440px
1165
+
1166
+ If your dataframe is in wide format, you can group multiple
1167
+ columns under the y argument to show multiple series with different
1168
+ colors:
1169
+
1170
+ >>> import streamlit as st
1171
+ >>> import pandas as pd
1172
+ >>> import numpy as np
1173
+ >>>
1174
+ >>> chart_data = pd.DataFrame(
1175
+ ... {
1176
+ ... "col1": list(range(20)),
1177
+ ... "col2": np.random.randn(20),
1178
+ ... "col3": np.random.randn(20),
1179
+ ... }
1180
+ ... )
1181
+ >>>
1182
+ >>> st.bar_chart(
1183
+ ... chart_data,
1184
+ ... x="col1",
1185
+ ... y=["col2", "col3"],
1186
+ ... color=["#FF0000", "#0000FF"], # Optional
1187
+ ... )
1188
+
1189
+ .. output::
1190
+ https://doc-bar-chart2.streamlit.app/
1191
+ height: 440px
1192
+
1193
+ You can rotate your bar charts to display horizontally.
1194
+
1195
+ >>> import streamlit as st
1196
+ >>> from vega_datasets import data
1197
+ >>>
1198
+ >>> source = data.barley()
1199
+ >>>
1200
+ >>> st.bar_chart(source, x="variety", y="yield", color="site", horizontal=True)
1201
+
1202
+ .. output::
1203
+ https://doc-bar-chart-horizontal.streamlit.app/
1204
+ height: 440px
1205
+
1206
+ You can unstack your bar charts.
1207
+
1208
+ >>> import streamlit as st
1209
+ >>> from vega_datasets import data
1210
+ >>>
1211
+ >>> source = data.barley()
1212
+ >>>
1213
+ >>> st.bar_chart(source, x="year", y="yield", color="site", stack=False)
1214
+
1215
+ .. output::
1216
+ https://doc-bar-chart-unstacked.streamlit.app/
1217
+ height: 440px
1218
+
1219
+ """
1220
+
1221
+ # Check that the stack parameter is valid, raise more informative error message if not
1222
+ maybe_raise_stack_warning(
1223
+ stack,
1224
+ "st.bar_chart",
1225
+ "https://docs.streamlit.io/develop/api-reference/charts/st.bar_chart",
1226
+ )
1227
+
1228
+ # Offset encodings (used for non-stacked/grouped bar charts) are not supported in Altair < 5.0.0
1229
+ if type_util.is_altair_version_less_than("5.0.0") and stack is False:
1230
+ raise StreamlitAPIException(
1231
+ "Streamlit does not support non-stacked (grouped) bar charts with "
1232
+ "Altair 4.x. Please upgrade to Version 5."
1233
+ )
1234
+
1235
+ bar_chart_type = (
1236
+ ChartType.HORIZONTAL_BAR if horizontal else ChartType.VERTICAL_BAR
1237
+ )
1238
+
1239
+ chart, add_rows_metadata = generate_chart(
1240
+ chart_type=bar_chart_type,
1241
+ data=data,
1242
+ x_from_user=x,
1243
+ y_from_user=y,
1244
+ x_axis_label=x_label,
1245
+ y_axis_label=y_label,
1246
+ color_from_user=color,
1247
+ size_from_user=None,
1248
+ width=width,
1249
+ height=height,
1250
+ stack=stack,
1251
+ )
1252
+ return cast(
1253
+ "DeltaGenerator",
1254
+ self._altair_chart(
1255
+ chart,
1256
+ use_container_width=use_container_width,
1257
+ theme="streamlit",
1258
+ add_rows_metadata=add_rows_metadata,
1259
+ ),
1260
+ )
1261
+
1262
+ @gather_metrics("scatter_chart")
1263
+ def scatter_chart(
1264
+ self,
1265
+ data: Data = None,
1266
+ *,
1267
+ x: str | None = None,
1268
+ y: str | Sequence[str] | None = None,
1269
+ x_label: str | None = None,
1270
+ y_label: str | None = None,
1271
+ color: str | Color | list[Color] | None = None,
1272
+ size: str | float | int | None = None,
1273
+ width: int | None = None,
1274
+ height: int | None = None,
1275
+ use_container_width: bool = True,
1276
+ ) -> DeltaGenerator:
1277
+ """Display a scatterplot chart.
1278
+
1279
+ This is syntax-sugar around ``st.altair_chart``. The main difference
1280
+ is this command uses the data's own column and indices to figure out
1281
+ the chart's Altair spec. As a result this is easier to use for many
1282
+ "just plot this" scenarios, while being less customizable.
1283
+
1284
+ If ``st.scatter_chart`` does not guess the data specification correctly,
1285
+ try specifying your desired chart using ``st.altair_chart``.
1286
+
1287
+ Parameters
1288
+ ----------
1289
+ data : Anything supported by st.dataframe
1290
+ Data to be plotted.
1291
+
1292
+ x : str or None
1293
+ Column name or key associated to the x-axis data. If ``x`` is
1294
+ ``None`` (default), Streamlit uses the data index for the x-axis
1295
+ values.
1296
+
1297
+ y : str, Sequence of str, or None
1298
+ Column name(s) or key(s) associated to the y-axis data. If this is
1299
+ ``None`` (default), Streamlit draws the data of all remaining
1300
+ columns as data series. If this is a ``Sequence`` of strings,
1301
+ Streamlit draws several series on the same chart by melting your
1302
+ wide-format table into a long-format table behind the scenes.
1303
+
1304
+ x_label : str or None
1305
+ The label for the x-axis. If this is ``None`` (default), Streamlit
1306
+ will use the column name specified in ``x`` if available, or else
1307
+ no label will be displayed.
1308
+
1309
+ y_label : str or None
1310
+ The label for the y-axis. If this is ``None`` (default), Streamlit
1311
+ will use the column name(s) specified in ``y`` if available, or
1312
+ else no label will be displayed.
1313
+
1314
+ color : str, tuple, Sequence of str, Sequence of tuple, or None
1315
+ The color of the circles representing each datapoint.
1316
+
1317
+ This can be:
1318
+
1319
+ - None, to use the default color.
1320
+ - A hex string like "#ffaa00" or "#ffaa0088".
1321
+ - An RGB or RGBA tuple with the red, green, blue, and alpha
1322
+ components specified as ints from 0 to 255 or floats from 0.0 to
1323
+ 1.0.
1324
+ - The name of a column in the dataset where the color of that
1325
+ datapoint will come from.
1326
+
1327
+ If the values in this column are in one of the color formats
1328
+ above (hex string or color tuple), then that color will be used.
1329
+
1330
+ Otherwise, the color will be automatically picked from the
1331
+ default palette.
1332
+
1333
+ For example: if the dataset has 1000 rows, but this column only
1334
+ contains the values "adult", "child", and "baby", then those 1000
1335
+ datapoints be shown using three colors from the default palette.
1336
+
1337
+ But if this column only contains floats or ints, then those
1338
+ 1000 datapoints will be shown using a colors from a continuous
1339
+ color gradient.
1340
+
1341
+ Finally, if this column only contains the values "#ffaa00",
1342
+ "#f0f", "#0000ff", then then each of those 1000 datapoints will
1343
+ be assigned "#ffaa00", "#f0f", or "#0000ff" as appropriate.
1344
+
1345
+ If the dataframe is in wide format (that is, y is a Sequence of
1346
+ columns), this can also be:
1347
+
1348
+ - A list of string colors or color tuples to be used for each of
1349
+ the series in the chart. This list should have the same length
1350
+ as the number of y values (e.g. ``color=["#fd0", "#f0f", "#04f"]``
1351
+ for three series).
1352
+
1353
+ size : str, float, int, or None
1354
+ The size of the circles representing each point.
1355
+
1356
+ This can be:
1357
+
1358
+ - A number like 100, to specify a single size to use for all
1359
+ datapoints.
1360
+ - The name of the column to use for the size. This allows each
1361
+ datapoint to be represented by a circle of a different size.
1362
+
1363
+ width : int or None
1364
+ Desired width of the chart expressed in pixels. If ``width`` is
1365
+ ``None`` (default), Streamlit sets the width of the chart to fit
1366
+ its contents according to the plotting library, up to the width of
1367
+ the parent container. If ``width`` is greater than the width of the
1368
+ parent container, Streamlit sets the chart width to match the width
1369
+ of the parent container.
1370
+
1371
+ To use ``width``, you must set ``use_container_width=False``.
1372
+
1373
+ height : int or None
1374
+ Desired height of the chart expressed in pixels. If ``height`` is
1375
+ ``None`` (default), Streamlit sets the height of the chart to fit
1376
+ its contents according to the plotting library.
1377
+
1378
+ use_container_width : bool
1379
+ Whether to override ``width`` with the width of the parent
1380
+ container. If ``use_container_width`` is ``True`` (default),
1381
+ Streamlit sets the width of the chart to match the width of the
1382
+ parent container. If ``use_container_width`` is ``False``,
1383
+ Streamlit sets the chart's width according to ``width``.
1384
+
1385
+ Examples
1386
+ --------
1387
+ >>> import streamlit as st
1388
+ >>> import pandas as pd
1389
+ >>> import numpy as np
1390
+ >>>
1391
+ >>> chart_data = pd.DataFrame(np.random.randn(20, 3), columns=["a", "b", "c"])
1392
+ >>>
1393
+ >>> st.scatter_chart(chart_data)
1394
+
1395
+ .. output::
1396
+ https://doc-scatter-chart.streamlit.app/
1397
+ height: 440px
1398
+
1399
+ You can also choose different columns to use for x and y, as well as set
1400
+ the color dynamically based on a 3rd column (assuming your dataframe is in
1401
+ long format):
1402
+
1403
+ >>> import streamlit as st
1404
+ >>> import pandas as pd
1405
+ >>> import numpy as np
1406
+ >>>
1407
+ >>> chart_data = pd.DataFrame(
1408
+ ... np.random.randn(20, 3), columns=["col1", "col2", "col3"]
1409
+ ... )
1410
+ >>> chart_data["col4"] = np.random.choice(["A", "B", "C"], 20)
1411
+ >>>
1412
+ >>> st.scatter_chart(
1413
+ ... chart_data,
1414
+ ... x="col1",
1415
+ ... y="col2",
1416
+ ... color="col4",
1417
+ ... size="col3",
1418
+ ... )
1419
+
1420
+ .. output::
1421
+ https://doc-scatter-chart1.streamlit.app/
1422
+ height: 440px
1423
+
1424
+ Finally, if your dataframe is in wide format, you can group multiple
1425
+ columns under the y argument to show multiple series with different
1426
+ colors:
1427
+
1428
+ >>> import streamlit as st
1429
+ >>> import pandas as pd
1430
+ >>> import numpy as np
1431
+ >>>
1432
+ >>> chart_data = pd.DataFrame(
1433
+ ... np.random.randn(20, 4), columns=["col1", "col2", "col3", "col4"]
1434
+ ... )
1435
+ >>>
1436
+ >>> st.scatter_chart(
1437
+ ... chart_data,
1438
+ ... x="col1",
1439
+ ... y=["col2", "col3"],
1440
+ ... size="col4",
1441
+ ... color=["#FF0000", "#0000FF"], # Optional
1442
+ ... )
1443
+
1444
+ .. output::
1445
+ https://doc-scatter-chart2.streamlit.app/
1446
+ height: 440px
1447
+
1448
+ """
1449
+
1450
+ chart, add_rows_metadata = generate_chart(
1451
+ chart_type=ChartType.SCATTER,
1452
+ data=data,
1453
+ x_from_user=x,
1454
+ y_from_user=y,
1455
+ x_axis_label=x_label,
1456
+ y_axis_label=y_label,
1457
+ color_from_user=color,
1458
+ size_from_user=size,
1459
+ width=width,
1460
+ height=height,
1461
+ )
1462
+ return cast(
1463
+ "DeltaGenerator",
1464
+ self._altair_chart(
1465
+ chart,
1466
+ use_container_width=use_container_width,
1467
+ theme="streamlit",
1468
+ add_rows_metadata=add_rows_metadata,
1469
+ ),
1470
+ )
1471
+
1472
+ # When on_select=Ignore, return DeltaGenerator.
1473
+ @overload
1474
+ def altair_chart(
1475
+ self,
1476
+ altair_chart: AltairChart,
1477
+ *,
1478
+ use_container_width: bool | None = None,
1479
+ theme: Literal["streamlit"] | None = "streamlit",
1480
+ key: Key | None = None,
1481
+ on_select: Literal["ignore"], # No default value here to make it work with mypy
1482
+ selection_mode: str | Iterable[str] | None = None,
1483
+ ) -> DeltaGenerator: ...
1484
+
1485
+ # When on_select=rerun, return VegaLiteState.
1486
+ @overload
1487
+ def altair_chart(
1488
+ self,
1489
+ altair_chart: AltairChart,
1490
+ *,
1491
+ use_container_width: bool | None = None,
1492
+ theme: Literal["streamlit"] | None = "streamlit",
1493
+ key: Key | None = None,
1494
+ on_select: Literal["rerun"] | WidgetCallback = "rerun",
1495
+ selection_mode: str | Iterable[str] | None = None,
1496
+ ) -> VegaLiteState: ...
1497
+
1498
+ @gather_metrics("altair_chart")
1499
+ def altair_chart(
1500
+ self,
1501
+ altair_chart: AltairChart,
1502
+ *,
1503
+ use_container_width: bool | None = None,
1504
+ theme: Literal["streamlit"] | None = "streamlit",
1505
+ key: Key | None = None,
1506
+ on_select: Literal["rerun", "ignore"] | WidgetCallback = "ignore",
1507
+ selection_mode: str | Iterable[str] | None = None,
1508
+ ) -> DeltaGenerator | VegaLiteState:
1509
+ """Display a chart using the Vega-Altair library.
1510
+
1511
+ `Vega-Altair <https://altair-viz.github.io/>`_ is a declarative
1512
+ statistical visualization library for Python, based on Vega and
1513
+ Vega-Lite.
1514
+
1515
+ Parameters
1516
+ ----------
1517
+ altair_chart : altair.Chart
1518
+ The Altair chart object to display. See
1519
+ https://altair-viz.github.io/gallery/ for examples of graph
1520
+ descriptions.
1521
+
1522
+ use_container_width : bool or None
1523
+ Whether to override the chart's native width with the width of
1524
+ the parent container. This can be one of the following:
1525
+
1526
+ - ``None`` (default): Streamlit will use the parent container's
1527
+ width for all charts except those with known incompatibility
1528
+ (``altair.Facet``, ``altair.HConcatChart``, and
1529
+ ``altair.RepeatChart``).
1530
+ - ``True``: Streamlit sets the width of the chart to match the
1531
+ width of the parent container.
1532
+ - ``False``: Streamlit sets the width of the chart to fit its
1533
+ contents according to the plotting library, up to the width of
1534
+ the parent container.
1535
+
1536
+ theme : "streamlit" or None
1537
+ The theme of the chart. If ``theme`` is ``"streamlit"`` (default),
1538
+ Streamlit uses its own design default. If ``theme`` is ``None``,
1539
+ Streamlit falls back to the default behavior of the library.
1540
+
1541
+ key : str
1542
+ An optional string to use for giving this element a stable
1543
+ identity. If ``key`` is ``None`` (default), this element's identity
1544
+ will be determined based on the values of the other parameters.
1545
+
1546
+ Additionally, if selections are activated and ``key`` is provided,
1547
+ Streamlit will register the key in Session State to store the
1548
+ selection state. The selection state is read-only.
1549
+
1550
+ on_select : "ignore", "rerun", or callable
1551
+ How the figure should respond to user selection events. This
1552
+ controls whether or not the figure behaves like an input widget.
1553
+ ``on_select`` can be one of the following:
1554
+
1555
+ - ``"ignore"`` (default): Streamlit will not react to any selection
1556
+ events in the chart. The figure will not behave like an input
1557
+ widget.
1558
+
1559
+ - ``"rerun"``: Streamlit will rerun the app when the user selects
1560
+ data in the chart. In this case, ``st.altair_chart`` will return
1561
+ the selection data as a dictionary.
1562
+
1563
+ - A ``callable``: Streamlit will rerun the app and execute the
1564
+ ``callable`` as a callback function before the rest of the app.
1565
+ In this case, ``st.altair_chart`` will return the selection data
1566
+ as a dictionary.
1567
+
1568
+ To use selection events, the object passed to ``altair_chart`` must
1569
+ include selection paramters. To learn about defining interactions
1570
+ in Altair and how to declare selection-type parameters, see
1571
+ `Interactive Charts \
1572
+ <https://altair-viz.github.io/user_guide/interactions.html>`_
1573
+ in Altair's documentation.
1574
+
1575
+ selection_mode : str or Iterable of str
1576
+ The selection parameters Streamlit should use. If
1577
+ ``selection_mode`` is ``None`` (default), Streamlit will use all
1578
+ selection parameters defined in the chart's Altair spec.
1579
+
1580
+ When Streamlit uses a selection parameter, selections from that
1581
+ parameter will trigger a rerun and be included in the selection
1582
+ state. When Streamlit does not use a selection parameter,
1583
+ selections from that parameter will not trigger a rerun and not be
1584
+ included in the selection state.
1585
+
1586
+ Selection parameters are identified by their ``name`` property.
1587
+
1588
+ Returns
1589
+ -------
1590
+ element or dict
1591
+ If ``on_select`` is ``"ignore"`` (default), this command returns an
1592
+ internal placeholder for the chart element that can be used with
1593
+ the ``.add_rows()`` method. Otherwise, this command returns a
1594
+ dictionary-like object that supports both key and attribute
1595
+ notation. The attributes are described by the ``VegaLiteState``
1596
+ dictionary schema.
1597
+
1598
+ Example
1599
+ -------
1600
+
1601
+ >>> import streamlit as st
1602
+ >>> import pandas as pd
1603
+ >>> import numpy as np
1604
+ >>> import altair as alt
1605
+ >>>
1606
+ >>> chart_data = pd.DataFrame(np.random.randn(20, 3), columns=["a", "b", "c"])
1607
+ >>>
1608
+ >>> c = (
1609
+ ... alt.Chart(chart_data)
1610
+ ... .mark_circle()
1611
+ ... .encode(x="a", y="b", size="c", color="c", tooltip=["a", "b", "c"])
1612
+ ... )
1613
+ >>>
1614
+ >>> st.altair_chart(c)
1615
+
1616
+ .. output::
1617
+ https://doc-vega-lite-chart.streamlit.app/
1618
+ height: 450px
1619
+
1620
+ """
1621
+ return self._altair_chart(
1622
+ altair_chart=altair_chart,
1623
+ use_container_width=use_container_width,
1624
+ theme=theme,
1625
+ key=key,
1626
+ on_select=on_select,
1627
+ selection_mode=selection_mode,
1628
+ )
1629
+
1630
+ # When on_select=Ignore, return DeltaGenerator.
1631
+ @overload
1632
+ def vega_lite_chart(
1633
+ self,
1634
+ data: Data = None,
1635
+ spec: VegaLiteSpec | None = None,
1636
+ *,
1637
+ use_container_width: bool | None = None,
1638
+ theme: Literal["streamlit"] | None = "streamlit",
1639
+ key: Key | None = None,
1640
+ on_select: Literal["ignore"], # No default value here to make it work with mypy
1641
+ selection_mode: str | Iterable[str] | None = None,
1642
+ **kwargs: Any,
1643
+ ) -> DeltaGenerator: ...
1644
+
1645
+ # When on_select=rerun, return VegaLiteState.
1646
+ @overload
1647
+ def vega_lite_chart(
1648
+ self,
1649
+ data: Data = None,
1650
+ spec: VegaLiteSpec | None = None,
1651
+ *,
1652
+ use_container_width: bool | None = None,
1653
+ theme: Literal["streamlit"] | None = "streamlit",
1654
+ key: Key | None = None,
1655
+ on_select: Literal["rerun"] | WidgetCallback = "rerun",
1656
+ selection_mode: str | Iterable[str] | None = None,
1657
+ **kwargs: Any,
1658
+ ) -> VegaLiteState: ...
1659
+
1660
+ @gather_metrics("vega_lite_chart")
1661
+ def vega_lite_chart(
1662
+ self,
1663
+ data: Data = None,
1664
+ spec: VegaLiteSpec | None = None,
1665
+ *,
1666
+ use_container_width: bool | None = None,
1667
+ theme: Literal["streamlit"] | None = "streamlit",
1668
+ key: Key | None = None,
1669
+ on_select: Literal["rerun", "ignore"] | WidgetCallback = "ignore",
1670
+ selection_mode: str | Iterable[str] | None = None,
1671
+ **kwargs: Any,
1672
+ ) -> DeltaGenerator | VegaLiteState:
1673
+ """Display a chart using the Vega-Lite library.
1674
+
1675
+ `Vega-Lite <https://vega.github.io/vega-lite/>`_ is a high-level
1676
+ grammar for defining interactive graphics.
1677
+
1678
+ Parameters
1679
+ ----------
1680
+ data : Anything supported by st.dataframe
1681
+ Either the data to be plotted or a Vega-Lite spec containing the
1682
+ data (which more closely follows the Vega-Lite API).
1683
+
1684
+ spec : dict or None
1685
+ The Vega-Lite spec for the chart. If ``spec`` is ``None`` (default),
1686
+ Streamlit uses the spec passed in ``data``. You cannot pass a spec
1687
+ to both ``data`` and ``spec``. See
1688
+ https://vega.github.io/vega-lite/docs/ for more info.
1689
+
1690
+ use_container_width : bool or None
1691
+ Whether to override the chart's native width with the width of
1692
+ the parent container. This can be one of the following:
1693
+
1694
+ - ``None`` (default): Streamlit will use the parent container's
1695
+ width for all charts except those with known incompatibility
1696
+ (``altair.Facet``, ``altair.HConcatChart``, and
1697
+ ``altair.RepeatChart``).
1698
+ - ``True``: Streamlit sets the width of the chart to match the
1699
+ width of the parent container.
1700
+ - ``False``: Streamlit sets the width of the chart to fit its
1701
+ contents according to the plotting library, up to the width of
1702
+ the parent container.
1703
+
1704
+ theme : "streamlit" or None
1705
+ The theme of the chart. If ``theme`` is ``"streamlit"`` (default),
1706
+ Streamlit uses its own design default. If ``theme`` is ``None``,
1707
+ Streamlit falls back to the default behavior of the library.
1708
+
1709
+ key : str
1710
+ An optional string to use for giving this element a stable
1711
+ identity. If ``key`` is ``None`` (default), this element's identity
1712
+ will be determined based on the values of the other parameters.
1713
+
1714
+ Additionally, if selections are activated and ``key`` is provided,
1715
+ Streamlit will register the key in Session State to store the
1716
+ selection state. The selection state is read-only.
1717
+
1718
+ on_select : "ignore", "rerun", or callable
1719
+ How the figure should respond to user selection events. This
1720
+ controls whether or not the figure behaves like an input widget.
1721
+ ``on_select`` can be one of the following:
1722
+
1723
+ - ``"ignore"`` (default): Streamlit will not react to any selection
1724
+ events in the chart. The figure will not behave like an input
1725
+ widget.
1726
+
1727
+ - ``"rerun"``: Streamlit will rerun the app when the user selects
1728
+ data in the chart. In this case, ``st.vega_lite_chart`` will
1729
+ return the selection data as a dictionary.
1730
+
1731
+ - A ``callable``: Streamlit will rerun the app and execute the
1732
+ ``callable`` as a callback function before the rest of the app.
1733
+ In this case, ``st.vega_lite_chart`` will return the selection data
1734
+ as a dictionary.
1735
+
1736
+ To use selection events, the Vega-Lite spec defined in ``data`` or
1737
+ ``spec`` must include selection parameters from the the charting
1738
+ library. To learn about defining interactions in Vega-Lite, see
1739
+ `Dynamic Behaviors with Parameters \
1740
+ <https://vega.github.io/vega-lite/docs/parameter.html>`_
1741
+ in Vega-Lite's documentation.
1742
+
1743
+ selection_mode : str or Iterable of str
1744
+ The selection parameters Streamlit should use. If
1745
+ ``selection_mode`` is ``None`` (default), Streamlit will use all
1746
+ selection parameters defined in the chart's Vega-Lite spec.
1747
+
1748
+ When Streamlit uses a selection parameter, selections from that
1749
+ parameter will trigger a rerun and be included in the selection
1750
+ state. When Streamlit does not use a selection parameter,
1751
+ selections from that parameter will not trigger a rerun and not be
1752
+ included in the selection state.
1753
+
1754
+ Selection parameters are identified by their ``name`` property.
1755
+
1756
+ **kwargs : any
1757
+ The Vega-Lite spec for the chart as keywords. This is an alternative
1758
+ to ``spec``.
1759
+
1760
+ Returns
1761
+ -------
1762
+ element or dict
1763
+ If ``on_select`` is ``"ignore"`` (default), this command returns an
1764
+ internal placeholder for the chart element that can be used with
1765
+ the ``.add_rows()`` method. Otherwise, this command returns a
1766
+ dictionary-like object that supports both key and attribute
1767
+ notation. The attributes are described by the ``VegaLiteState``
1768
+ dictionary schema.
1769
+
1770
+ Example
1771
+ -------
1772
+ >>> import streamlit as st
1773
+ >>> import pandas as pd
1774
+ >>> import numpy as np
1775
+ >>>
1776
+ >>> chart_data = pd.DataFrame(np.random.randn(200, 3), columns=["a", "b", "c"])
1777
+ >>>
1778
+ >>> st.vega_lite_chart(
1779
+ ... chart_data,
1780
+ ... {
1781
+ ... "mark": {"type": "circle", "tooltip": True},
1782
+ ... "encoding": {
1783
+ ... "x": {"field": "a", "type": "quantitative"},
1784
+ ... "y": {"field": "b", "type": "quantitative"},
1785
+ ... "size": {"field": "c", "type": "quantitative"},
1786
+ ... "color": {"field": "c", "type": "quantitative"},
1787
+ ... },
1788
+ ... },
1789
+ ... )
1790
+
1791
+ .. output::
1792
+ https://doc-vega-lite-chart.streamlit.app/
1793
+ height: 450px
1794
+
1795
+ Examples of Vega-Lite usage without Streamlit can be found at
1796
+ https://vega.github.io/vega-lite/examples/. Most of those can be easily
1797
+ translated to the syntax shown above.
1798
+
1799
+ """
1800
+ return self._vega_lite_chart(
1801
+ data=data,
1802
+ spec=spec,
1803
+ use_container_width=use_container_width,
1804
+ theme=theme,
1805
+ key=key,
1806
+ on_select=on_select,
1807
+ selection_mode=selection_mode,
1808
+ **kwargs,
1809
+ )
1810
+
1811
+ def _altair_chart(
1812
+ self,
1813
+ altair_chart: AltairChart,
1814
+ use_container_width: bool | None = None,
1815
+ theme: Literal["streamlit"] | None = "streamlit",
1816
+ key: Key | None = None,
1817
+ on_select: Literal["rerun", "ignore"] | WidgetCallback = "ignore",
1818
+ selection_mode: str | Iterable[str] | None = None,
1819
+ add_rows_metadata: AddRowsMetadata | None = None,
1820
+ ) -> DeltaGenerator | VegaLiteState:
1821
+ """Internal method to enqueue a vega-lite chart element based on an Altair chart.
1822
+
1823
+ See the `altair_chart` method docstring for more information.
1824
+ """
1825
+
1826
+ if type_util.is_altair_version_less_than("5.0.0") and on_select != "ignore":
1827
+ raise StreamlitAPIException(
1828
+ "Streamlit does not support selections with Altair 4.x. Please upgrade "
1829
+ "to Version 5. "
1830
+ "If you would like to use Altair 4.x with selections, please upvote "
1831
+ "this [Github issue](https://github.com/streamlit/streamlit/issues/8516)."
1832
+ )
1833
+
1834
+ vega_lite_spec = _convert_altair_to_vega_lite_spec(altair_chart)
1835
+ return self._vega_lite_chart(
1836
+ data=None, # The data is already part of the spec
1837
+ spec=vega_lite_spec,
1838
+ use_container_width=use_container_width,
1839
+ theme=theme,
1840
+ key=key,
1841
+ on_select=on_select,
1842
+ selection_mode=selection_mode,
1843
+ add_rows_metadata=add_rows_metadata,
1844
+ )
1845
+
1846
+ def _vega_lite_chart(
1847
+ self,
1848
+ data: Data = None,
1849
+ spec: VegaLiteSpec | None = None,
1850
+ use_container_width: bool | None = None,
1851
+ theme: Literal["streamlit"] | None = "streamlit",
1852
+ key: Key | None = None,
1853
+ on_select: Literal["rerun", "ignore"] | WidgetCallback = "ignore",
1854
+ selection_mode: str | Iterable[str] | None = None,
1855
+ add_rows_metadata: AddRowsMetadata | None = None,
1856
+ **kwargs: Any,
1857
+ ) -> DeltaGenerator | VegaLiteState:
1858
+ """Internal method to enqueue a vega-lite chart element based on a vega-lite spec.
1859
+
1860
+ See the `vega_lite_chart` method docstring for more information.
1861
+ """
1862
+
1863
+ if theme not in ["streamlit", None]:
1864
+ raise StreamlitAPIException(
1865
+ f'You set theme="{theme}" while Streamlit charts only support '
1866
+ "theme=”streamlit” or theme=None to fallback to the default "
1867
+ "library theme."
1868
+ )
1869
+
1870
+ if on_select not in ["ignore", "rerun"] and not callable(on_select):
1871
+ raise StreamlitAPIException(
1872
+ f"You have passed {on_select} to `on_select`. But only 'ignore', "
1873
+ "'rerun', or a callable is supported."
1874
+ )
1875
+
1876
+ key = to_key(key)
1877
+ is_selection_activated = on_select != "ignore"
1878
+
1879
+ if is_selection_activated:
1880
+ # Run some checks that are only relevant when selections are activated
1881
+
1882
+ is_callback = callable(on_select)
1883
+ check_widget_policies(
1884
+ self.dg,
1885
+ key,
1886
+ on_change=cast(WidgetCallback, on_select) if is_callback else None,
1887
+ default_value=None,
1888
+ writes_allowed=False,
1889
+ enable_check_callback_rules=is_callback,
1890
+ )
1891
+
1892
+ # Support passing data inside spec['datasets'] and spec['data'].
1893
+ # (The data gets pulled out of the spec dict later on.)
1894
+ if isinstance(data, dict) and spec is None:
1895
+ spec = data
1896
+ data = None
1897
+
1898
+ if spec is None:
1899
+ spec = {}
1900
+
1901
+ # Set the default value for `use_container_width`.
1902
+ if use_container_width is None:
1903
+ # Some multi-view charts (facet, horizontal concatenation, and repeat;
1904
+ # see https://altair-viz.github.io/user_guide/compound_charts.html)
1905
+ # don't work well with `use_container_width=True`, so we disable it for
1906
+ # those charts (see https://github.com/streamlit/streamlit/issues/9091).
1907
+ # All other charts (including vertical concatenation) default to
1908
+ # `use_container_width=True`.
1909
+ is_facet_chart = "facet" in spec or (
1910
+ "encoding" in spec
1911
+ and (any(x in spec["encoding"] for x in ["row", "column", "facet"]))
1912
+ )
1913
+ use_container_width = not (
1914
+ is_facet_chart or "hconcat" in spec or "repeat" in spec
1915
+ )
1916
+
1917
+ vega_lite_proto = ArrowVegaLiteChartProto()
1918
+
1919
+ spec = _prepare_vega_lite_spec(spec, use_container_width, **kwargs)
1920
+ _marshall_chart_data(vega_lite_proto, spec, data)
1921
+
1922
+ # Prevent the spec from changing across reruns:
1923
+ vega_lite_proto.spec = _stabilize_vega_json_spec(json.dumps(spec))
1924
+ vega_lite_proto.use_container_width = use_container_width
1925
+ vega_lite_proto.theme = theme or ""
1926
+
1927
+ if is_selection_activated:
1928
+ # Load the stabilized spec again as a dict:
1929
+ final_spec = json.loads(vega_lite_proto.spec)
1930
+ # Temporary limitation to disallow multi-view charts (compositions) with selections.
1931
+ _disallow_multi_view_charts(final_spec)
1932
+
1933
+ # Parse and check the specified selection modes
1934
+ parsed_selection_modes = _parse_selection_mode(final_spec, selection_mode)
1935
+ vega_lite_proto.selection_mode.extend(parsed_selection_modes)
1936
+
1937
+ vega_lite_proto.form_id = current_form_id(self.dg)
1938
+
1939
+ ctx = get_script_run_ctx()
1940
+ vega_lite_proto.id = compute_and_register_element_id(
1941
+ "arrow_vega_lite_chart",
1942
+ user_key=key,
1943
+ form_id=vega_lite_proto.form_id,
1944
+ vega_lite_spec=vega_lite_proto.spec,
1945
+ # The data is either in vega_lite_proto.data.data
1946
+ # or in a named dataset in vega_lite_proto.datasets
1947
+ vega_lite_data=vega_lite_proto.data.data,
1948
+ # Its enough to just use the names here since they are expected
1949
+ # to contain hashes based on the dataset data.
1950
+ named_datasets=[dataset.name for dataset in vega_lite_proto.datasets],
1951
+ theme=theme,
1952
+ use_container_width=use_container_width,
1953
+ selection_mode=parsed_selection_modes,
1954
+ )
1955
+
1956
+ serde = VegaLiteStateSerde(parsed_selection_modes)
1957
+
1958
+ widget_state = register_widget(
1959
+ vega_lite_proto.id,
1960
+ on_change_handler=on_select if callable(on_select) else None,
1961
+ deserializer=serde.deserialize,
1962
+ serializer=serde.serialize,
1963
+ ctx=ctx,
1964
+ value_type="string_value",
1965
+ )
1966
+
1967
+ self.dg._enqueue(
1968
+ "arrow_vega_lite_chart",
1969
+ vega_lite_proto,
1970
+ add_rows_metadata=add_rows_metadata,
1971
+ )
1972
+ return cast(VegaLiteState, widget_state.value)
1973
+ # If its not used with selections activated, just return
1974
+ # the delta generator related to this element.
1975
+ return self.dg._enqueue(
1976
+ "arrow_vega_lite_chart",
1977
+ vega_lite_proto,
1978
+ add_rows_metadata=add_rows_metadata,
1979
+ )
1980
+
1981
+ @property
1982
+ def dg(self) -> DeltaGenerator:
1983
+ """Get our DeltaGenerator."""
1984
+ return cast("DeltaGenerator", self)