{"id":24338,"date":"2023-10-18T19:07:45","date_gmt":"2023-10-18T19:07:45","guid":{"rendered":"https:\/\/www.highcharts.com\/blog\/?p=24338"},"modified":"2026-01-13T11:37:19","modified_gmt":"2026-01-13T11:37:19","slug":"working-series-highcharts-python","status":"publish","type":"post","link":"https:\/\/www.highcharts.com\/blog\/integration\/working-series-highcharts-python\/","title":{"rendered":"Working with Series in Highcharts for Python"},"content":{"rendered":"<p><b>Highcharts for Python<\/b> (and Highcharts (JS), of course) are both built around the concept of <a href=\"https:\/\/core-docs.highchartspython.com\/en\/latest\/glossary.html#term-Series\" target=\"_blank\" rel=\"noopener\">data series<\/a>. A data series can be thought of as a set of data points that describe the same \u201cthing\u201d, and which represent how the data can be organized. Think:<\/p>\n<ul>\n<li>a single line on a line chart<\/li>\n<li>a set of columns all the same color on a column chart<\/li>\n<li>all of a pie or donut chart<\/li>\n<\/ul>\n<p>As a result, when you constructing your chart in <b>Highcharts for Python<\/b>, what you are really doing is constructing one or more <a href=\"https:\/\/core-docs.highchartspython.com\/en\/latest\/glossary.html#term-Series\" target=\"_blank\" rel=\"noopener\">series<\/a> that are then placed on a shared canvas, with shared axes, a shared legend, etc.<\/p>\n<p>Diagram showing the conceptual components of a Highcharts chart<br \/>\nThis tutorial is designed to help you understand how to manage series in your Highcharts visualizations using <b>Highcharts for Python<\/b>.<\/p>\n<h2>How Series are Organized<\/h2>\n<p>As the diagram above shows, Highcharts visualizations are configured within a <code>Chart<\/code> object, which has the <code>.options<\/code> property where the chart\u2019s configuration \u201clives\u201d, represented as a <code>HighchartsOptions<\/code> instance.<\/p>\n<p>The <code>HighchartsOptions<\/code> configuration allows you to define all details of what gets displayed on the chart, how that content behaves, etc. The configuration options available in <code>HighchartsOptions<\/code> can be thought of as chart-level configurations: They configure or define things that apply to everything shown on the chart: the axes to display, the legend, the title, the settings shared across all of the series on the chart, etc.<\/p>\n<p>But within the <code>HighchartsOptions<\/code> you will find the <code>.series<\/code> property. This is where you define the specific <a href=\"https:\/\/core-docs.highchartspython.com\/en\/latest\/glossary.html#term-Series\" target=\"_blank\" rel=\"noopener\">series<\/a> to render on your chart.<\/p>\n<p>This property gets one or more series instances, all of which are descended from <code>SeriesBase<\/code>. They descend from this single base series class because many of their properties are shared across all types of series. For example, whether the series is to render as a line or as a bar, all series will have an .id option.<\/p>\n<p>All visualizations supported by Highcharts have a corresponding series type, which means they all have their corresponding series class. To see this mapping, take a look at our <a href=\"https:\/\/core-docs.highchartspython.com\/en\/latest\/visualizations.html\" target=\"_blank\" rel=\"noopener\">Supported Visualizations<\/a>.<\/p>\n<p>Each series type has its set of shared properties that derive from <code>SeriesBase<\/code> will have options to configure the gauge\u2019s dial (<code>.dial<\/code>), overshot-handling (<code>.overshoot<\/code>), and pivot point (<code>.pivot<\/code>) &#8211; settings which would be completely irrelevant for a <code>LineSeries<\/code>, which does not have a dial, does not have a concept of overshooting the bounds of the dial, and does not have any pivot points.<\/p>\n<p>And all series (technically, almost all) have a <code>.data<\/code> property, which contains the data that should be visualized in the series.<br \/>\nSo as you can see, series are pretty fundamental to your Highcharts visualizations: They are what actually gets visualized.<\/p>\n<p>So how do we start creating series using <b>Highcharts for Python<\/b>?<\/p>\n<h2>Creating Series in Highcharts for Python<\/h2>\n<p>Of course, you can always construct your series using direct instantiation:<\/p>\n<pre>from highcharts_core.chart import Chart\r\nfrom highcharts_core.options import HighchartsOptions\r\nfrom highcharts_core.options.series.area import LineSeries\r\n\r\nmy_line_series = LineSeries(data = my_data, id = 'my_series_id123')\r\nmy_options = HighchartsOptions(series = [my_line_series])\r\nmy_chart = Chart(options = my_options)<\/pre>\n<p>And there may be situations where there is the best way for you to construct your series, depending on how you are managing your full Highcharts for Python application.<\/p>\n<p>But there are much simpler \/ faster ways to rapidly create your chart\/series:<\/p>\n<h3>Assembling a Chart with Series at Once<\/h3>\n<pre>my_chart = Chart(data = my_iterable, series_type = 'line')<\/pre>\n<p>This will create a <code>Chart<\/code> instance with one <a href=\"https:\/\/core-docs.highchartspython.com\/en\/latest\/glossary.html#term-Series\" target=\"_blank\" rel=\"noopener\">series<\/a> of type <code>line<\/code> (represented as a LineSeries instance).<\/p>\n<p>Depending on how we\u2019ve wrangled our data, we can similarly produce a chart from a <code>pandas.DataFrame<\/code>, <code>numpy.ndarray<\/code>, or Python <code>dict<\/code>:<\/p>\n<pre># From a Pandas DataFrame\r\n\r\nmy_chart = Chart.from_pandas(df, series_type = 'line')\r\n\r\n# From a Numpy ndarray\r\n\r\nmy_chart = Chart.from_array(data = as_ndarray, series_type = 'line')\r\n\r\n# From a Python dict\r\n\r\nmy_chart = Chart(data = as_dict, series_type = 'line')<\/pre>\n<p>All of these lines of code are equivalent, and should produce an identical <code>my_chart<\/code>.<\/p>\n<h3>Assembling Series Alone<\/h3>\n<p>You can create series similarly:<\/p>\n<pre>from highcharts_core.options.series.area import LineSeries\r\n\r\nmy_line_series = LineSeries(data = my_iterable)<\/pre>\n<p>This will create a <code>LineSeries<\/code> instance.<\/p>\n<p>Depending on how we\u2019ve wrangled our data, we can similarly produce one or more series from a <code>pandas.DataFrame<\/code>, <code>numpy.ndarray<\/code>, or Python <code>dict<\/code>:<\/p>\n<pre># From a Pandas DataFrame\r\n\r\nmy_series = LineSeries.from_pandas(df)\r\n\r\n# From a Numpy ndarray\r\n\r\nmy_series = LineSeries.from_array(data = as_ndarray)\r\n\r\n# From a CSV file\r\n\r\nmy_series = LineSeries.from_csv('my-data.csv')\r\n\r\n# From a Python iterable\r\n\r\nmy_series = LineSeries.from_array(data = as_iterable)<\/pre>\n<p>All of these lines of code are equivalent, and should produce an identical <code>my_series<\/code>. Depending on the arguments you supply to the helper methods, they may either produce one series instance or a list of series instances.<\/p>\n<h3>Adding Series to a Chart<\/h3>\n<p>If you have created series on their own, you can add them to an existing <code>Chart<\/code> very easily:<\/p>\n<pre># EXAMPLE 1.\r\n# Adding one series\r\n\r\nmy_chart.add_series(my_series)\r\n\r\n# EXAMPLE 2.\r\n# Adding multiple series if they are in one iterable\r\n\r\nmy_chart.add_series(my_list_of_series)\r\n\r\n# EXAMPLE 3.\r\n# Adding multiple individual series\r\n\r\nmy_chart.add_series(series1, series2, series3)<\/pre>\n<p>Or you can also create a new chart from a list of series:<\/p>\n<pre># EXAMPLE 1.\r\n# With one series\r\n\r\nmy_chart = Chart.from_series(my-series)\r\n\r\n# EXAMPLE 2.\r\n# With multiple series if they are in one iterable\r\n\r\nmy_chart = Chart.from_series(my_list_of_series)\r\n\r\n# EXAMPLE 3.\r\n# Adding multiple individual series\r\n\r\nmy_chart = Chart.from_series(series1, series2, series3)<\/pre>\n<p><i><b>Tip<\/b><\/p>\n<p>The same <code>.add_series<\/code> and <code>.from_series<\/code> helper methods are also available on the <code>HighchartsOptions<\/code> class.<\/i><\/p>\n<p>So now that we\u2019ve created a chart and a bunch of series, what else can we do?<\/p>\n<p><i><b>Tip<\/b><\/p>\n<p>We recommend reviewing the API Reference to really explore the options available for different series types.<\/i><\/p>\n<h3>Updating Data Points<\/h3>\n<p>However, the most important configuration you will do is to manage the data points you wish to display in your series. You can do this by:<\/p>\n<ol>\n<li>\nPassing data directly to the <code>.data<\/code> property:<\/p>\n<pre>my_series.data = updated_data<\/pre>\n<\/li>\n<li>\nUsing any of the helper methods provided on the series instance:<\/p>\n<pre># EXAMPLE 1.\r\n# Updating data points from a new Pandas DataFrame\r\n\r\nmy_series.load_from_pandas(df)\r\n\r\n# EXAMPLE 2.\r\n# Updating data points from a new numpy.ndarray\r\n\r\nmy_series.load_from_array(as_ndarray)\r\n\r\n# EXAMPLE 3.\r\n# Updating data points from a new iterable.\r\n\r\nmy_series.load_from_array(as_iterable)\r\n\r\n# EXAMPLE 4.\r\n# Updating data points from a CSV file.\r\n\r\nmy_series.load_from_csv('my-updated-csv-file.csv')<\/pre>\n<\/li>\n<\/ol>\n<h3>Updating Data Point Properties<\/h3>\n<p>In addition, all series instances make it easy to propagate information throughout your underlying data. When you try to set a property on your series object, <b>Highcharts for Python<\/b> will first see if it is a valid property on the series itself. But if it is not, then it will check whether it is a supported property on that series\u2019 data.<br \/>\nSo as an example, if we want to give our series an ID, we can simply call:<\/p>\n<pre>my_series.id = 'my-updated-id-value'<\/pre>\n<p>However, if we want to set a <code>BulletSeries<\/code> data points\u2019 <code>.target<\/code> value, we can simply reference it on the series. For example, if our <code>BulletSeries<\/code> contains three data points, we can set their targets easily using the series:<\/p>\n<pre>my_bullet_series.target = [1, 2, 3]<\/pre>\n<p>By passing an iterable (or a <code>numpy.ndarray<\/code>), all of your data points will get updated with the appropriate value. This makes it very easy to execute your data point configurations by operating on the series, rather than working with individual data points &#8211; though if you want to work with individual data points, you can do so as well.<\/p>\n<h3>Converting Series Types<\/h3>\n<p>Every series type has its own type-specific set of configuration options. However, there may be times when you want to change how your data is to be visualized \/ rendered. <b>Highcharts for Python<\/b> provides a useful helper method for that, too. For example, if we want to convert our <code>LineSeries<\/code> to a <code>BarSeries<\/code>, we can do that by calling the <code>.convert_to<\/code> method:<\/p>\n<pre># EXAMPLE 1\r\n# Indicating the target type with a string label\r\n\r\nmy_series.convert_to(series_type = 'bar')\r\n\r\n# EXAMPLE 2\r\n# Indicating the target type with a SeriesBase class\r\n\r\nmy_series.convert_to(series_type = BarSeries)<\/pre>\n<p>So now that we\u2019ve constructed, configured, and adjusted our series, we can also render them easily.<\/p>\n<h2>Rendering Series<\/h2>\n<p>Series can be rendered within the chart that they are a part of, simply by following the process to render the chart:<\/p>\n<h3>Rendering a Series within a Chart<\/h3>\n<ol>\n<li>When in Jupyter Notebook\/Lab, just execute the .display() method.\n<pre>my_chart.display()<\/pre>\n<\/li>\n<li>When rendering within a web application, or saving to a file for rendering in a separate application, you can serialize your chart to <a href=\"https:\/\/core-docs.highchartspython.com\/en\/latest\/glossary.html#term-JavaScript-Object-Literal-Notation\" target=\"_blank\" rel=\"noopener\">JavaScript object literal notation<\/a>:\n<pre>as_js_literal = my_chart.to_js_literal()<\/pre>\n<p>which will produce the JavaScript code to render your complete chart.\n<\/li>\n<\/ol>\n<h3>Rendering a Series Alone<\/h3>\n<p>The exact same helper methods are available on your series as well. So if you have assembled your series as <code>my_series<\/code>, you can take a shortcut to visualize it by calling:<\/p>\n<pre>my_series.display()<\/pre>\n<p>which will assemble a generic <code>Chart<\/code> instance, include your series, and render it in Jupyter Notebook\/Lab.<\/p>\n<p>You can also produce a <code>Chart<\/code> instance containing your series in a single method call as well:<\/p>\n<pre>my_chart = my_series.to_chart()<\/pre>\n<p>And similarly:<\/p>\n<pre>series_as_js_literal = my_series.to_js_literal()<\/pre>\n<p>will produce the JS literal representation of your series, for use in a JavaScript application.<\/p>\n<p>Given all of this flexibliity, we hope you have a great time assembling high-end visualizations and exploring <b>Highcharts for Python<\/b>!<\/p>\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\/inspirations\/data-visualization-library-by-highcharts\/\">Data visualization library by Highcharts<\/a><\/li>\n<li style=\"margin-left: 20px; margin-bottom: 20px;\"><a href=\"https:\/\/www.highcharts.com\/blog\/inspirations\/javascript-graph-visualization-library-by-highcharts\/\">JavaScript graph visualization library by Highcharts<\/a><\/li>\n<li style=\"margin-left: 20px; margin-bottom: 20px;\"><a href=\"https:\/\/www.highcharts.com\/blog\/inspirations\/javascript-library-by-highcharts\/\">JavaScript library by Highcharts<\/a><\/li>\n<li style=\"margin-left: 20px; margin-bottom: 20px;\"><a href=\"https:\/\/www.highcharts.com\/blog\/inspirations\/javascript-map-library-by-highcharts\/\">JavaScript map library by Highcharts<\/a><\/li>\n<li style=\"margin-left: 20px; margin-bottom: 20px;\"><a href=\"https:\/\/www.highcharts.com\/blog\/inspirations\/map-library-by-highcharts\/\">Map library by Highcharts<\/a><\/li>\n<li style=\"margin-left: 20px; margin-bottom: 20px;\"><a href=\"https:\/\/www.highcharts.com\/blog\/inspirations\/data-visualization-framework-by-highcharts\/\">Data visualization framework by Highcharts<\/a><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Highcharts for Python (and Highcharts (JS), of course) are both built around the concept of data series. A data series can be thought of as a set of data points that describe the same \u201cthing\u201d, and which represent how the data can be organized. Think: a single line on a line chart a set of [&hellip;]<\/p>\n","protected":false},"author":273,"featured_media":24346,"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,699],"class_list":["post-24338","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\/24338","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=24338"}],"version-history":[{"count":3,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/posts\/24338\/revisions"}],"predecessor-version":[{"id":26048,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/posts\/24338\/revisions\/26048"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/media\/24346"}],"wp:attachment":[{"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/media?parent=24338"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/categories?post=24338"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/tags?post=24338"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/coauthors?post=24338"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}