{"id":23489,"date":"2023-04-09T13:23:10","date_gmt":"2023-04-09T13:23:10","guid":{"rendered":"https:\/\/www.highcharts.com\/blog\/?p=23489"},"modified":"2026-01-13T11:30:18","modified_gmt":"2026-01-13T11:30:18","slug":"exporting-static-charts-highcharts-python","status":"publish","type":"post","link":"https:\/\/www.highcharts.com\/blog\/integration\/exporting-static-charts-highcharts-python\/","title":{"rendered":"Exporting Static Charts using Highcharts for Python"},"content":{"rendered":"\n<div class=\"wp-block-group has-global-padding is-layout-constrained wp-container-core-group-is-layout-c5bbea69 wp-block-group-is-layout-constrained\">\n<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-355c4241 wp-block-group-is-layout-flex\">\n<p>So you are using <a href=\"https:\/\/www.highcharts.com\" target=\"_blank\" rel=\"noopener\">Highcharts Core<\/a>&nbsp;to render beautiful interactive data visualizations, and you are relying on the <a href=\"https:\/\/github.com\/highcharts-for-python\" target=\"_blank\" rel=\"noopener\">Highcharts for Python<\/a> toolkit to create those visualizations in your Python code. That\u2019s great! But what if you need to programmatically create a data visualization and use that visualization somewhere besides a user\u2019s web browser? Embedding visualizations in a presentation or a document is very, very common.<\/p>\n\n\n\n<p>Well, Highcharts for Python has you covered. You can create static exports of your charts either client-side (in your user\u2019s web browser when viewing the chart) or server-side (programmatically within Python).<\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-355c4241 wp-block-group-is-layout-flex\">\n<h2 class=\"wp-block-heading\">Client-side Export<\/h2>\n\n\n\n<p>Using Highcharts for Python, you can configure client-side export within the <code>Chart<\/code> instance you create for your chart. In particular, you can create an <code>Exporting<\/code> instance and set it to <code>your_chart.options.exporting<\/code>.<br>The <code>Exporting<\/code> class lets you configure how your chart will support exporting from within the user\u2019s browser when the chart is rendered. Here\u2019s a quick example, assuming you have a <code>Chart<\/code> instance called <code>my_chart<\/code>:<\/p>\n\n\n\n<div class=\"hs-code-outer-container\"><div class=\"hs-code-container attention-50-light neutral-800-dark\" tabindex=\"0\" role=\"region\" aria-label=\"Code block\">\n<pre class=\"wp-block-code\"><code># Import the Exporting class\nfrom highcharts_core.options.exporting\nimport Exporting\nexporting_options = Exporting(enabled = True,\n  filename = 'your-exported-chart',\n  show_table = True,\n  table_caption = \"Your Chart's Caption Goes Here\",\n  accessibility = {\n    'enabled': True\n  })\nexporting_options.buttons&#91;'contextButton'].menu_items = &#91;'printChart', 'separator', 'downloadPNG']\nmy_chart.options.exporting = exporting_options<\/code><\/pre>\n\n\n\n<div class=\"wp-block-highsoft-hs-button\"><button type=\"button\" class=\"hc-button hc-button--white hc-button--size-200\" aria-label=\"Copy\" data-copy-code=\"true\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" fill=\"none\" viewBox=\"0 0 24 24\" width=\"16\" height=\"16\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 8V5.2c0-1.12 0-1.68.218-2.108a2 2 0 0 1 .874-.874C9.52 2 10.08 2 11.2 2h7.6c1.12 0 1.68 0 2.108.218a2 2 0 0 1 .874.874C22 3.52 22 4.08 22 5.2v7.6c0 1.12 0 1.68-.218 2.108a2 2 0 0 1-.874.874C20.48 16 19.92 16 18.8 16H16M5.2 22h7.6c1.12 0 1.68 0 2.108-.218a2 2 0 0 0 .874-.874C16 20.48 16 19.92 16 18.8v-7.6c0-1.12 0-1.68-.218-2.108a2 2 0 0 0-.874-.874C14.48 8 13.92 8 12.8 8H5.2c-1.12 0-1.68 0-2.108.218a2 2 0 0 0-.874.874C2 9.52 2 10.08 2 11.2v7.6c0 1.12 0 1.68.218 2.108a2 2 0 0 0 .874.874C3.52 22 4.08 22 5.2 22\"><\/path><\/svg>Copy<\/button><\/div>\n<\/div><\/div>\n\n\n\n<p>And that\u2019s it. With the code above you\u2019ve now configured some basic logic that:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Enables client-side export of the <code>my_chart<\/code> visualization.<br>Gives an exported chart image a default filename of <code>\u201cyour-exported-chart\u201d<\/code> (not including the file\u2019s extension).<\/li>\n\n\n\n<li>Makes sure that the exported or printed version of your chart includes the chart\u2019s underlying data table (thanks to the <code>show_table<\/code> property being set to <code>True<\/code>), and<\/li>\n\n\n\n<li>Gives users the ability to either print the chart or download a PNG version of the chart, but nothing else (by setting the relevant buttons shown in the context menu).<\/li>\n<\/ul>\n\n\n\n<p>Highcharts Core supports client-side export to a number of formats, including:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>PNG<\/li>\n\n\n\n<li>JPEG<\/li>\n\n\n\n<li>SVG<\/li>\n\n\n\n<li>CSV<\/li>\n\n\n\n<li>Excel<\/li>\n<\/ul>\n\n\n\n<p>And you can also configure the client-side export to fall back to server-side export should it fail. For more details on the extensive options, please take a look at the <a href=\"https:\/\/core-docs.highchartspython.com\/en\/latest\/api\/options\/exporting\/index.html\" target=\"_blank\" rel=\"noopener\">API Documentation: options.Exporting<\/a>.<\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-355c4241 wp-block-group-is-layout-flex\">\n<h2 class=\"wp-block-heading\">Programmatic (Server-side) Export<\/h2>\n\n\n\n<p>So now that your users can download a PNG image of your chart, maybe you want to create an image programmatically. <b>Highcharts for Python<\/b> makes that possible through an integration with the <b>Highcharts Export Server<\/b>. It\u2019s actually trivially easy to do since you can do it with just one method call in your Python code:<\/p>\n\n\n\n<div class=\"hs-code-outer-container\"><div class=\"hs-code-container attention-50-light neutral-800-dark\" tabindex=\"0\" role=\"region\" aria-label=\"Code block\">\n<pre class=\"wp-block-code\"><code># Download a PNG version of the chart in memory within your Python code.\nmy_png_image = my_chart.download_chart(format = 'png')\n# Download a PNG version of the chart and save it the file \"\/images\/my-chart-file.png\"\nmy_png_image = my_chart.download_chart(\n  format = 'png',\n  filename = '\/images\/my-chart-file.png'\n)<\/code><\/pre>\n\n\n\n<div class=\"wp-block-highsoft-hs-button\"><button type=\"button\" class=\"hc-button hc-button--white hc-button--size-200\" aria-label=\"Copy\" data-copy-code=\"true\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" fill=\"none\" viewBox=\"0 0 24 24\" width=\"16\" height=\"16\"><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 8V5.2c0-1.12 0-1.68.218-2.108a2 2 0 0 1 .874-.874C9.52 2 10.08 2 11.2 2h7.6c1.12 0 1.68 0 2.108.218a2 2 0 0 1 .874.874C22 3.52 22 4.08 22 5.2v7.6c0 1.12 0 1.68-.218 2.108a2 2 0 0 1-.874.874C20.48 16 19.92 16 18.8 16H16M5.2 22h7.6c1.12 0 1.68 0 2.108-.218a2 2 0 0 0 .874-.874C16 20.48 16 19.92 16 18.8v-7.6c0-1.12 0-1.68-.218-2.108a2 2 0 0 0-.874-.874C14.48 8 13.92 8 12.8 8H5.2c-1.12 0-1.68 0-2.108.218a2 2 0 0 0-.874.874C2 9.52 2 10.08 2 11.2v7.6c0 1.12 0 1.68.218 2.108a2 2 0 0 0 .874.874C3.52 22 4.08 22 5.2 22\"><\/path><\/svg>Copy<\/button><\/div>\n<\/div><\/div>\n\n\n\n<p>The two examples shown above both download a PNG of your chart:<br>The first example keeps that PNG image in your Python code only, storing its binary data in the <code>my_png_image<\/code> variable. The second example not only stores its binary data in the <code>my_png_image<\/code> variable, but it also saves the PNG image to the file <code>\u201c\/images\/my-chart-file.png\u201d<\/code>.<br>The <code>format<\/code> argument is really the one doing the heavy lifting above. In the example above, it tells the method to generate a PNG image, but you can also create <code>\u201cjpeg\u201d<\/code>, <code>\u201cpdf\u201d<\/code>, and <code>\u201csvg\u201d<\/code>.<br>And that\u2019s it! There\u2019s really nothing simpler.<br>Under the hood, this method defaults to calling the Highcharts Export Server that is maintained by Highsoft (creators of Highcharts Core). This publicly-available server is available to all licensees of Highcharts Core, and you are free to use it to generate downloadable versions of your data visualizations. However, it is rate-limited and it does mean transmitting your chart\u2019s data across the wire. There are various situations in which this is inappropriate, which is why Highsoft allows you to configure and deploy your own Highcharts Export Server. And Highcharts for Python supports using your own custom Export Server for your programmatic chart exports.<\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-355c4241 wp-block-group-is-layout-flex\">\n<h2 class=\"wp-block-heading\">Custom Export Server<\/h2>\n\n\n\n<p><i><b>Tip<\/b><br>While deploying your own Highcharts Export Server is beyond the scope of this tutorial, we strongly recommend that you review the <a href=\"https:\/\/www.highcharts.com\/docs\/export-module\/setting-up-the-server\" target=\"_blank\" rel=\"noopener\">Highcharts Export Server documentation<\/a><\/i><\/p>\n\n\n\n<p>If you have your own Highcharts Export Server, you can override Highcharts for Python\u2019s default to have your code rely on your own export server. While you can do this by creating an instance of <code>highcharts_core.headless_export.ExportServer<\/code> with your custom configuration and passing it to the .download_chart() method in the <code>server_instance<\/code> argument, it is far easier to simply set some environment variables wherever your Python code will be running:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>HIGHCHARTS_EXPORT_SERVER_DOMAIN<\/code> is the environment variable that specifies the domain where the Highcharts Export Server exists. If this environment variable is not set, it will default to <code>\"export.highcharts.com\"<\/code>, which is the Highsoft-provided export server.<\/li>\n\n\n\n<li><code>HIGHCHARTS_EXPORT_SERVER_PATH<\/code> is the path at the domain where your Export Server is reachable. If this environment variable is not set, it will default to <code>None<\/code>\u00a0since there is no path when using the Highsoft-provided export server.<\/li>\n\n\n\n<li><code>HIGHCHARTS_EXPORT_SERVER_PORT<\/code> is the port where your Export Server is reachable. If this environment variable is not set, it will default to <code>None<\/code> since there is no need to specify a port when using the Highsoft-provided export server.<\/li>\n<\/ul>\n\n\n\n<p>In addition to the three environment variables above, the <code>.download_chart()<\/code> method also supports three additional arguments which may prove useful:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>auth_user<\/code> which is the user to supply to your custom Export Server using Basic authentication. This defaults to <code>None<\/code> (since the default <code>Highsoft-provided<\/code> Export Server has no authentication).<\/li>\n\n\n\n<li><code>auth_password<\/code> which is the password to supply to your custom Export Server using Basic authentication. This defaults to None (since the default <code>Highsoft-provided<\/code> Export Server has no authentication).<\/li>\n\n\n\n<li><code>timeout<\/code> which is the number of seconds to wait before issuing a timeout error. The timeout check is passed if any bytes have been received on the socket in less than this number of seconds. It defaults to 0.5, but you may want to adjust this when using your own custom Export Server.<\/li>\n<\/ul>\n<\/div>\n\n\n\n<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-355c4241 wp-block-group-is-layout-flex\">\n<h2 class=\"wp-block-heading\">More Resources<\/h2>\n\n\n\n<p>The above tutorial is just a really simple example of how you can create rich visualizations with just a handful of method calls using Highcharts for Python. But the library offers so much more! We recommend you take a look at the following additional resources which you may find useful:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/www.highcharts.com\/blog\/tutorials\/using-highcharts-for-python-basic-tutorial\" target=\"_blank\" rel=\"noopener\">Highcharts for Python: Tutorials<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.highcharts.com\/blog\/tutorials\/templating-and-shared-options-highcharts-python\" target=\"_blank\" rel=\"noopener\">Using Templating and Shared Options in Highcharts for Python <\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.highcharts.com\/blog\/tutorials\/highcharts-python-pandas-pyspark\" target=\"_blank\" rel=\"noopener\">Using Highcharts for Python with Pandas and PySpark <\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/core-docs.highchartspython.com\/en\/latest\/api.html\" target=\"_blank\" rel=\"noopener\">Highcharts for Python: API Reference Documentation<\/a><\/li>\n<\/ul>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>A step-by-step tutorial to learn how to export static charts using Highcharts for Python<\/p>\n","protected":false},"author":273,"featured_media":23583,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"meta_title":"","meta_description":"","hc_selected_options":[],"footnotes":""},"categories":[1105],"tags":[1094,885],"coauthors":[983],"class_list":["post-23489","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-integration","tag-highcharts-core","tag-python"],"_links":{"self":[{"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/posts\/23489","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/users\/273"}],"replies":[{"embeddable":true,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/comments?post=23489"}],"version-history":[{"count":3,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/posts\/23489\/revisions"}],"predecessor-version":[{"id":28638,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/posts\/23489\/revisions\/28638"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/media\/23583"}],"wp:attachment":[{"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/media?parent=23489"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/categories?post=23489"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/tags?post=23489"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/coauthors?post=23489"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}