{"id":23471,"date":"2023-04-09T13:20:53","date_gmt":"2023-04-09T13:20:53","guid":{"rendered":"https:\/\/www.highcharts.com\/blog\/?p=23471"},"modified":"2026-01-13T11:30:06","modified_gmt":"2026-01-13T11:30:06","slug":"templating-and-shared-options-highcharts-python","status":"publish","type":"post","link":"https:\/\/www.highcharts.com\/blog\/integration\/templating-and-shared-options-highcharts-python\/","title":{"rendered":"Using Templating and Shared Options in Highcharts for Python"},"content":{"rendered":"<p>When building analytical applications \u2013 or robust dashboards \u2013 your visualization needs are likely to become more complicated. In practice, you will want all of your visualizations to a) be visually consistent, and b) to be implemented with the least amount of code\/effort. Which is why it is a good thing that <a href=\"https:\/\/www.highcharts.com\" target=\"_blank\" rel=\"noopener\">Highcharts Core<\/a>\u00a0and Highcharts for Python have such strong support for templating and the sharing of configuration across individual charts.<\/p>\n<h2>Templating with Highcharts for Python<\/h2>\n<p>The Highcharts for Python (and underlying Highcharts Core) APIs are very robust, which means that there are lots of small \u201cfiddly\u201d options which can be customized, configured, and tweaked to support the look and behavior of data that you want. Tweaking your configuration to get what you need can be a lot of effort, and it can produce configuration sets that are quite extensive. And if elements of it need to be re-used, repeating those long sets of configurations can rapidly clutter up your code and make it unreadable.<\/p>\n<p>Templates to the rescue!<\/p>\n<p>A best practice when working with Highcharts for Python is to store your core (or repeatable) chart configurations in <code>.js<\/code> files, and then to instantiate your <code>Chart<\/code> options from those template files. This pattern can actually work for any Highcharts for Python object, whether that\u2019s your chart, your chart\u2019s <code>.options<\/code>, or even a particular series type.<\/p>\n<p>To see how this works in practice, let\u2019s imagine you have your project files organized as follows:<\/p>\n<pre>my_repository\/\r\n| \u2014 docs\/\r\n| \u2014 my_project\/\r\n| \u2014\u2014 project_resources\/\r\n| \u2014\u2014\u2014 image_files\/\r\n| \u2014\u2014\u2014 data_files\/\r\n| \u2014\u2014\u2014\u2014\u2014 data-file-01.csv\r\n| \u2014\u2014\u2014\u2014\u2014 data-file-02.csv\r\n| \u2014\u2014\u2014\u2014\u2014 data-file-03.csv\r\n| \u2014\u2014\u2014 highcharts_config\/\r\n| \u2014\u2014\u2014\u2014\u2014 shared_options.js\r\n| \u2014\u2014\u2014\u2014\u2014 bar-template.js\r\n| \u2014\u2014\u2014\u2014\u2014 line-template.js\r\n| \u2014\u2014\u2014\u2014\u2014 packed-bubble-template.js\r\n| \u2014\u2014 some_package\/\r\n| \u2014\u2014\u2014\u2014 __init__.py\r\n| \u2014\u2014\u2014\u2014 package_module.py\r\n| \u2014\u2014\u2014\u2014 another_module.py\r\n| \u2014\u2014 __init__.py\r\n| \u2014\u2014 __version__.py\r\n| \u2014\u2014 some_module.py\r\n| \u2014 tests\/\r\n| \u2014 .gitignore\r\n| \u2014 requirements.txt<\/pre>\n<p>In the example above, you can see the <code>highcharts_config\/<\/code> folder which contains a series of <code>.js<\/code> (JavaScript) files. As some of the file names suggest, this folder contains templates for charts that will have a bar series (<code>bar-template.js<\/code>), a line series (<code>line-template.js<\/code>), and a packed-bubble series (<code>packed-bubble-template.js<\/code>).<\/p>\n<p><i><b>Note<\/b><br \/>\nWhile this example assumes one template per series type, you can actually have a template that applies to all series types, or you can have templates that combine series types, or really any combination of templates.<\/i><\/p>\n<p>Let\u2019s take a look at the <code>bar-template.js<\/code> file. You\u2019ll find that it contains a pretty basic JavaScript object literal definition of a set of Highcharts <code>.options<\/code>:<\/p>\n<pre>{\r\n  xAxis: {\r\n    categories: [\r\n      'Jan',\r\n      'Feb',\r\n      'Mar',\r\n      'Apr',\r\n      'May',\r\n      'Jun',\r\n      'Jul',\r\n      'Aug',\r\n      'Sep',\r\n      'Oct',\r\n      'Nov',\r\n      'Dec'\r\n    ]\r\n  },\r\n  legend: {\r\n    align: 'right',\r\n    backgroundColor: '#FFF',\r\n    floating: true,\r\n    padding: 14,\r\n    shadow: true,\r\n    title: {\r\n      text: \"Chart Legend Goes Here\"\r\n    },\r\n    verticalAlign: 'top',\r\n    x: -8,\r\n    y: 36\r\n  },\r\n  plotOptions: {\r\n    bar: {\r\n      borderRadius: 8,\r\n      negativeColor: '#FF0000'\r\n    },\r\n    series: {\r\n      allowPointSelect: true\r\n    }\r\n  },\r\n  title: {\r\n    text: \"My Chart Title\"\r\n  }\r\n}<\/pre>\n<p>As you can see, this set of options is not doing anything fancy. It is just setting some x-axis category labeling, configuring the position and title of the legend, and setting some basic styling properties for a bar series. But if you want all of your bar charts to adhere to this template, you can now apply this template in a couple of different ways:<\/p>\n<pre>from highcharts_core.chart import Chart\r\nfrom highcharts_core.options import HighchartsOptions\r\nfrom highcharts_core.options.series import BarSeries\r\n# Create a HighchartsOptions instance configured from your template.\r\nbar_template_options = HighchartsOptions.from_js_literal(\r\n  '..\/project_resources\/highcharts_config\/bar-template.js'\r\n)\r\n# Create a new Chart instance from your bar_template_options\r\nmy_chart = Chart.from_options(bar_template_options,\r\n  chart_kwargs = {\r\n    'container': 'target_div',\r\n    'variable_name': 'myChart'\r\n  })\r\n# Create a second chart instance by copying the first one\u2019 s options.\r\nmy_other_chart = my_chart.copy()\r\n# Add your data series(from the\u201c my - csv - file.csv\u201d CSV file) to the chart.\r\nmy_chart.add_series(BarSeries.from_csv('my-csv-file.csv',\r\n  property_column_map = {\r\n    'x': 0,\r\n    'y': 3,\r\n    'id': 'id'\r\n  }))\r\n# Add another data series(from a different CSV file) to the chart.\r\nmy_other_chart.add_series(BarSeries.from_csv('my-other-csv-file.csv',\r\n  property_column_map = {\r\n    'x': 0,\r\n    'y': 3,\r\n    'id': 'id'\r\n  }))<\/pre>\n<p>So what\u2019s happening in the code above? First, we import the relevant classes that we need. Easy enough. Next, we instantiate a set of <code>HighchartsOptions<\/code> from our <code>bar-template.js<\/code> file. Next, using that set of options we create a chart instance using the <code>Chart.from_options()<\/code> class method.<\/p>\n<p>If we wanted to, we could do this again and again for however many charts needed to apply our bar chart template. However, we then use another method of applying a template: the <code>.copy()<\/code> method. This method takes the properties from the first chart instance we created and copies it to a new variable named <code>my_other_chart<\/code>. No need to reload the template file or anything else.<\/p>\n<p>Then, with our two chart objects created we simply add a <code>BarSeries<\/code> populated with data from two (different) CSV files. And that\u2019s it! Two richly-configured charts with just four lines of code.<\/p>\n<p><i><b>Tip<\/b><br \/>\nTemplating is particularly powerful when used in combination with Shared Options (see below). The best practice is to use Shared Options for all of the universal\/global settings that apply to all of your charts, and then to use templating for those settings that apply to subsets of your charts. For example, you may have one set of global options configured using Shared Options, and then you may have two different types of Bar Chart templates that you use for different classes of data.<\/i><\/p>\n<h2>Using Shared Options with Highcharts for Python<\/h2>\n<p>Shared Options in <b>Highcharts for Python<\/b> are particularly useful when you want to apply global settings to all of the Highcharts visualizations rendered at the same time. While you could do this using templating as described above, you\u2019ll ultimately produce less code if you use shared options. Then you can make any subset-specific adjustments using templates, and finally you can override the global Shared Options on any of your chart instances if you need to.<\/p>\n<p>So how do Shared Options work in Highcharts for Python? Very similarly to templates. If you recall the file structure outlined above, let\u2019s now look at the file <code>project_resources\/highcharts_config\/shared_options.js<\/code> which\u2026you guessed it! Contains the shared option configuration. This might look something like this:<\/p>\n<pre>{\r\n  chart: {\r\n    backgroundColor: {\r\n      linearGradient: {\r\n        x1: 0,\r\n        x2: 0,\r\n        y1: 1,\r\n        y2: 1\r\n      },\r\n      stops: [\r\n        [0, 'rgb(255, 255, 255)'],\r\n        [1, 'rgb(240, 240, 255)']\r\n      ]\r\n    },\r\n    borderWidth: 2,\r\n    plotBackgroundColor: 'rgba(255, 255, 255, .9)',\r\n    plotBorderWidth: 1\r\n  },\r\n  caption: {\r\n    align: 'center',\r\n    floating: true,\r\n    margin: 20,\r\n    verticalAlign: 'top'\r\n  },\r\n  credits: {\r\n    enabled: true,\r\n    href: 'https:\/\/www.somewhere.com',\r\n    style: {\r\n      color: '#cccccc',\r\n      fontSize: '8px'\r\n    },\r\n    text: 'Highcharts for Python'\r\n  }\r\n}<\/pre>\n<p>As you can see, these global options configure the chart formatting (applying a snazzy gradient background), the chart border, the chart caption styling, and the credits shown for the chart. With this file, we can now create a <code>SharedOptions<\/code> instance:<\/p>\n<pre>from highcharts_core.global_options.shared_options\r\nimport SharedOptions\r\n# Create a new SharedOptions instance\r\nshared_options = SharedOptions.from_js_literal(\r\n  '..\/project_resources\/highcharts_config\/shared_options.js'\r\n)<\/pre>\n<p>Now with that <code>SharedOptions<\/code> instance, we can simply convert it to JS code and deliver it to your front-end (the same as you do with your chart). The process is pretty straightforward:<\/p>\n<pre>from highcharts_core.global_options.shared_options import SharedOptions\r\n# Create your client-side JavaScript code\r\njs_code_snippet = shared_options.to_js_literal()<\/pre>\n<p>The JS code snippet will contain a string of JavaScript that is very similar to the original <code>shared_options.js<\/code> file, with one notable difference: the new JS literal file will execute the JavaScript <code>Highcharts.setOptions()<\/code> method, which configures the global settings that will apply to all charts rendered on the page. The result in this case would be:<\/p>\n<pre>Highcharts.setOptions({\r\n  caption: {\r\n    align: 'center',\r\n    floating: true,\r\n    margin: 20,\r\n    verticalAlign: 'top'\r\n  },\r\n  chart: {\r\n    backgroundColor: {\r\n      linearGradient: {\r\n        x1: 0,\r\n        x2: 0,\r\n        y1: 1,\r\n        y2: 1\r\n      },\r\n      stops: [\r\n        [0, 'rgb(255, 255, 255)'],\r\n        [1, 'rgb(240, 240, 255)']\r\n      ]\r\n    },\r\n    borderWidth: 2,\r\n    plotBackgroundColor: 'rgba(255, 255, 255, .9)',\r\n    plotBorderWidth: 1\r\n  },\r\n  credits: {\r\n    enabled: true,\r\n    href: 'https:\/\/www.somewhere.com',\r\n    style: {\r\n      color: '#cccccc',\r\n      fontSize: '8px'\r\n    },\r\n    text: 'Highcharts for Python'\r\n  }\r\n});<\/pre>\n<p>Which when included in your web-based front-end, will apply those settings to all charts rendered in the same browser context.<\/p>\n<p><i><b>Tip<\/b><br \/>\nYou can also apply shared options when programmatically exporting charts using the <code>.download_chart()<\/code> method. Just pass your <code>SharedOptions<\/code> instance to the method in an argument named <code>global_options<\/code>.<\/i><\/p>\n<h2>More Resources<\/h2>\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<ul>\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<li><a href=\"https:\/\/www.highcharts.com\/blog\/tutorials\/exporting-static-charts-highcharts-python\" target=\"_blank\" rel=\"noopener\">Exporting Static Charts using Highcharts for Python<\/a><\/li>\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<li><a href=\"https:\/\/maps-docs.highchartspython.com\/en\/latest\/\" target=\"_blank\" rel=\"noopener\"> Highcharts for Python: API Reference Documentation<\/a><\/li>\n<\/ul>\n<p>\u00a0<\/p>\n<h2><strong>Related posts<\/strong><\/h2>\n<ul>\n<li style=\"margin-left: 20px; margin-bottom: 20px;\"><a href=\"https:\/\/www.highcharts.com\/blog\/tutorials\/line-chart-vs-bar-chart-choosing-the-right-one-for-your-objectives-and-data\/\">Line chart vs bar chart: choosing the right one for your objectives and data<\/a><\/li>\n<li style=\"margin-left: 20px; margin-bottom: 20px;\"><a href=\"https:\/\/www.highcharts.com\/blog\/tutorials\/pareto-chart-what-is-it-and-what-does-it-suggest\/\">Pareto chart: what is it and what does it suggest<\/a><\/li>\n<li style=\"margin-left: 20px; margin-bottom: 20px;\"><a href=\"https:\/\/www.highcharts.com\/blog\/tutorials\/big-data-visualization-using-highcharts\/\">Big data visualization using Highcharts<\/a><\/li>\n<li style=\"margin-left: 20px; margin-bottom: 20px;\"><a href=\"https:\/\/www.highcharts.com\/blog\/post\/polygon-chart-using-highcharts\/\">Polygon chart using Highcharts<\/a><\/li>\n<li style=\"margin-left: 20px; margin-bottom: 20px;\"><a href=\"https:\/\/www.highcharts.com\/blog\/post\/heat-map-examples-using-highcharts\/\">Heat map examples using Highcharts<\/a><\/li>\n<li style=\"margin-left: 20px; margin-bottom: 20px;\"><a href=\"https:\/\/www.highcharts.com\/blog\/post\/intraday-chart-examples-using-highcharts\/\">Intraday chart examples using Highcharts<\/a><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A step-by-step tutorial to learn how to use templating and shared options in Highcharts for Python<\/p>\n","protected":false},"author":273,"featured_media":23580,"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-23471","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\/23471","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=23471"}],"version-history":[{"count":2,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/posts\/23471\/revisions"}],"predecessor-version":[{"id":26015,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/posts\/23471\/revisions\/26015"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/media\/23580"}],"wp:attachment":[{"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/media?parent=23471"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/categories?post=23471"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/tags?post=23471"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/coauthors?post=23471"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}