Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making a Highcharts plot with Python

I am working with a new Python web framework called justpy which lets you build both the backend and the frontend of a web app using Python only. The framework also integrates with the javascript Highcharts library. Here's how to build a web app that contains a Highcharts plot:

import justpy as jp
import pandas as pd


wm = pd.read_csv('https://elimintz.github.io/women_majors.csv').round(2)
# Create list of majors which start under 20% women students
wm_under_20 = list(wm.loc[0, wm.loc[0] < 20].index)

def women_majors():
    wp = jp.WebPage()
    wm.jp.plot(0, wm_under_20, kind='spline', a=wp, title='The gender gap is transitory - even for extreme cases',
               subtitle='Percentage of Bachelors conferred to women form 1970 to 2011 in the US for extreme cases where the percentage was less than 20% in 1970',
                classes='m-2 p-2 w-3/4')
    return wp

jp.justpy(women_majors)

that will load the webapp on localhost:8000:

enter image description here

I am now trying to figure out how to display the Highcharts plot only, without having to build a web app.

If I modify the above code to this:

import justpy as jp
import pandas as pd


wm = pd.read_csv('https://elimintz.github.io/women_majors.csv').round(2)
# Create list of majors which start under 20% women students
wm_under_20 = list(wm.loc[0, wm.loc[0] < 20].index)

fig = wm.jp.plot(0, wm_under_20, kind='spline', title='The gender gap is transitory - even for extreme cases',
               subtitle='Percentage of Bachelors conferred to women form 1970 to 2011 in the US for extreme cases where the percentage was less than 20% in 1970',
                classes='m-2 p-2 w-3/4')
print(fig)

That will return the following output:

 HighCharts(id: 1, vue_type: chart, chart options: {'series': [{'data': [4.23,...

How can I make an image file out of that HighCharts object (or show the plot in a Jupyter notebook) without having to build a web app?

like image 270
multigoodverse Avatar asked Mar 18 '21 17:03

multigoodverse


1 Answers

There are two ways of doing it. One as an image and the other as an interactive chart/hacky.

Image. You will need to import requests,Image and json. The fig.options generated by justpy will be sent as a payload to the highcharts export server and will return an image.

import requests
from IPython.display import Image
import json

#using the fig output from the justpy.plot extension
#fig = wm.jp.plot(0,  ......

payload = {"async": True,
           "constr": "Chart",
           "infile": fig.options,
           "scale": False,
           "type": "image/png",
           "width": False}

response = requests.post("""https://export.highcharts.com/""" ,json=payload)

Image(url='https://export.highcharts.com/'+response.text)

Jupyter Notebook Interactive/Hacky way of doing it for Jupyter as interactive. I copied the approach here Embedding d3.js

You will need to import 2 things and then use the %%javascript cell magic. These are needed since the charts for Highcharts need Javascript to be rendered.

Cell 1

#import needed
IPython.display import Javascript
import json

Cell 2

#using the fig output from the justpy.plot extension
#fig = wm.jp.plot(0,  ......

#this converts the dict(addict is actually whats used by justpy) into json
Javascript("""
           window.dataForchart={};
           """.format(json.dumps(fig.options)))

Cell 3
this runs the javascript code that renders the chart and displays it in the notebook

%%javascript
require.config({
    packages: [{
        name: 'highcharts',
        main: 'highcharts'
    }],
    paths: {
        'highcharts': 'https://code.highcharts.com'
    }
});
$("#chart1").remove();
element.append(`<div id="chart1"></div>`);
require([
    'highcharts',
    'highcharts/modules/exporting',
    'highcharts/modules/accessibility'
], function (Highcharts){Highcharts.chart("chart1", window.dataForchart)});

Jupyter Lab Interactive/Hacky

Cell 1

from IPython.display import Javascript,HTML
import json
import requests

Cell 2

#loads highcharts into the notebook. Succeeding calls for 
#Highchart will work if you open this notebook.
response = requests.get('https://code.highcharts.com/highcharts.js')
Javascript(response.text)

Cell 3

Javascript("""
           window.dataForchart={};
           """.format(json.dumps(fig.options)))

Cell 4

#the HTML function has to be in the last line of the cell
#for this to work. Also this become the output cell
HTML('<div id="chart123"></div>')

Cell 5

#make sure that the chart id for the divs you make are unique so they
#dont overwrite each other
Javascript('Highcharts.chart("chart123", window.dataForchart);')

The image below is for the Fruit Chart example

fruit_chart

This one is for your specific example your_example

like image 132
fcsr Avatar answered Sep 21 '22 12:09

fcsr