3

My code result currently, but I want the Pie chart to show up under the Algo Tab

My code

out_algo = widgets.Output()
out_ht = widgets.Output()
outioi_trd = widgets.Output()
out_adv = widgets.Output()
out_fundexp = widgets.Output()
out_stratexp = widgets.Output()

tab = widgets.Tab(children = [out_algo,out_ht,outioi_trd,out_adv,out_fundexp,out_stratexp])
tab.set_title(0,'Algo Trades')
tab.set_title(1,'HT Trades')
tab.set_title(2,'IOI Trades')
tab.set_title(3,'Top 20 ADV Trades')
tab.set_title(4,'Fund Exposure')
tab.set_title(5,'Strategy Exposure')
display(tab)

broker_list_test = broker_list_test.set_index('Broker')
#drop columns not needed
broker_list_test = broker_list_test.drop(['Direction', 'Investment_Team', 'portfolio_name', 'full_name','Desk', 'trader', 'trade_date', 'pct_adv_1m', 'trade_qty', 'price'],axis=1)
#group by broker and USD notional sum
broker_list_test2 = broker_list_test.groupby('Broker')
broker_list_test3 = broker_list_test2.sum() #group by value per broker
broker_list_test3['USD_Notional']=broker_list_test3['USD_Notional'].astype('float')
#IF WE HAVE COMMA USE s.replace(',','.')
label = broker_list_test3.index.tolist() #pull out all index names as pie labels 
data = broker_list_test3.values.tolist() # pie data
data = reduce(lambda x,y: x+y,data) #break list of lists into one list 
data_float=[float(x) for x in data] #convert string to float
sum_algo=0
for x in data_float:
   sum_algo+=x        
with out_algo:
    plt.pie(data_float,labels=label,autopct="%0.f%%",radius=2.4)
    plt.title("Algo Usage Notional Breakdown in USD\n"+'{:,.0f}'.format(sum_algo),position=(0.5,1.5))
    plt.show()

In the above code snippet, If I dont use ipywidgets, I am able to generate the Pie chart fine, but if I want to put this pie chart inside a ipywidget Tab, I dont see any results, do you think there is another way to get around this? I am using Jupyter Notebook

  • Please can you simplify your code example, by creating some example data and just a single output instance? There is a good guide here, http://matthewrocklin.com/blog/work/2018/02/28/minimal-bug-reports – ac24 Feb 10 '20 at 17:25

2 Answers2

2

on plt.show

plt.show(fig) in the answer above from Wayne is now deprecated:

In [1]: import matplotlib.pyplot as plt                                                                                                                                   

In [2]: fig = plt.figure()                                                                                                                                                

In [3]: plt.show(fig)                                                                                                                                                     
<ipython-input-3-d1fd62acb551>:1: MatplotlibDeprecationWarning: Passing the 
block parameter of show() positionally is deprecated since Matplotlib 3.1; the 
parameter will become keyword-only in 3.3.
    plt.show(fig)

plt.show(block=True) (or plt.show(block=False)) is the keyword-only call.

Therefore display(fig) seems to be the only valid option in the near future.


on %matplotlib inline

One could look at other options of matplotlib graphs embedding in notebooks:

  • %matplotlib notebook

    note: display is usually not needed or gives 2 figure outputs

  • %matplotlib widget

    note: requires ipympl, see matplotlib/ipympl on Github

RA Prism
  • 59
  • 6
  • I'm using this with matplotlib 3.5 and my demonstrated code works in JupyterLab and the classic notebook interface without a warning showing. – Wayne Mar 07 '22 at 21:43
  • 1
    With matplotlib version 3.5.1: `?plt.show` gives information that show is automatically called in jupyter backends. `??plt._backend_mod.show` code does not make use of any `args` parameter (widget backend sets `close`, which is not used, and notebook backend sets `block`, which is not used). – RA Prism Apr 26 '22 at 18:26
0

Based on this working code, I'd suggest you assign your plot to a variable, my_plot for instance, and then try plt.show(my_plot) or display(my_plot.figure).

I outlined the approach using a donut plot in a notebook here. You need to run the notebook though to see it rendered. To do that go to here, and press launch binder next to the text 'Start with the donut plot on a tab widget demo as a notebook'. In the process outlined, I had already invoked the plot making earlier in the notebook. And so I mention a couple of ways to add it to the tab above.

Summarizing from there:
With a donut plot defined as donut_plot earlier in a notebook, the following code adds it to the first tab on a simple tab system:

%matplotlib inline
# based on https://stackoverflow.com/a/51060721/8508004
# and https://github.com/jupyter-widgets/ipywidgets/issues/1754
# combined with donut plot from 
# https://github.com/fomightez/donut_plots_with_subgroups/blob/master/demo_basics_from_df.ipynb
import matplotlib.pyplot as plt
import pandas as pd
import ipywidgets as widgets
import numpy as np

out1 = widgets.Output()
out2 = widgets.Output()
data1 = pd.DataFrame(np.random.normal(size = 50))
data2 = pd.DataFrame(np.random.normal(size = 100))

tab = widgets.Tab(children = [out1, out2])
tab.set_title(0, 'First')
tab.set_title(1, 'Second')
display(tab)

with out1:
    #fig1, axes1 = plt.subplots()
    #data1.hist(ax = axes1)
    #plt.show(fig1)
    display(donut_plot.figure)

with out2:
    fig2, axes2 = plt.subplots()
    data2.hist(ax = axes2)
    plt.show(fig2)

UPDATING WITH MORE SELF-CONTAINED EXAMPLE WITH PIE PLOT BELOW:

In response to OP expressing trouble with adding in their pie plot, I added another example in the notebook I linked above. It boils down to below. To make the code block more self-contained than above, I included the dataframe used as well:

%matplotlib inline
# based on https://stackoverflow.com/a/51060721/8508004
# and https://github.com/jupyter-widgets/ipywidgets/issues/1754
# combined with donut plot from 
# https://github.com/fomightez/donut_plots_with_subgroups/blob/master/demo_basics_from_df.ipynb
import pandas as pd
obs = [('A', 1, "frizzled"), 
       ('A', 1, "lethargic"), 
       ('A', 1, "polythene"), 
       ('A', 1, "epic"),
       ('A', 2, "frizzled"), 
       ('A', 2, "lethargic"), 
       ('A', 2, "epic"),
       ('A', 3, "frizzled"), 
       ('A', 3, "lethargic"),
       ('A', 3, "polythene"),
       ('A', 3, "epic"),
       ('A', 3, "bedraggled"),
       ('B', 1, "frizzled"), 
       ('B', 1, "lethargic"),
       ('B', 1, "polythene"),
       ('B', 1, "epic"),
       ('B', 1, "bedraggled"),
       ('B', 1, "moombahcored"),
       ('B', 2, "frizzled"), 
       ('B', 2, "lethargic"),
       ('B', 2, "polythene"),
       ('B', 2, "epic"),
       ('B', 2, "bedraggled"),
       ('C', 1, "frizzled"), 
       ('C', 1, "lethargic"),
       ('C', 1, "polythene"),
       ('C', 1, "epic"),
       ('C', 1, "bedraggled"),
       ('C', 1, "moombahcored"),
       ('C', 1, "zoned"),
       ('C', 1, "erstaz"),
       ('C', 1, "mined"),
       ('C', 1, "liberated"),
       ('C', 2, "frizzled"), 
       ('C', 2, "lethargic"),
       ('C', 2, "polythene"),
       ('C', 2, "epic"),
       ('C', 2, "bedraggled"),
       ('C', 3, "frizzled"), 
       ('C', 3, "lethargic"),
       ('C', 3, "polythene"),
       ('C', 3, "epic"),
       ('C', 3, "bedraggled"),
       ('C', 4, "bedraggled"),
       ('C', 4, "frizzled"), 
       ('C', 4, "lethargic"),
       ('C', 4, "polythene"),
       ('C', 4, "epic"),
       ('C', 5, "frizzled"), 
       ('C', 5, "lethargic"),
       ('C', 5, "polythene"),
       ('C', 5, "epic"),
       ('C', 5, "bedraggled"),
       ('C', 5, "moombahcored")]
labels = ['group', 'subgroup', 'sub-subgroup']
df = pd.DataFrame.from_records(obs, columns=labels)
import matplotlib.pyplot as plt
import pandas as pd
import ipywidgets as widgets
import numpy as np

out1 = widgets.Output()
out2 = widgets.Output()
data1 = pd.DataFrame(np.random.normal(size = 50))
data2 = pd.DataFrame(np.random.normal(size = 100))

tab = widgets.Tab(children = [out1, out2])
tab.set_title(0, 'First')
tab.set_title(1, 'Second')
display(tab)

with out1:
    #fig1, axes1 = plt.subplots()
    #data1.hist(ax = axes1)
    #plt.show(fig1)
    grouped = df.groupby("group")
    grouped.size()
    group_names= grouped.size().index.tolist()
    group_size= grouped.size().tolist()
    my_plot  = plt.pie(group_size, labels=group_names,autopct="%0.f%%",radius=2.4)
    plt.show(my_plot)

with out2:
    fig2, axes2 = plt.subplots()
    data2.hist(ax = axes2)
    plt.show(fig2)

Update:
What if you had more than a few plots to put onto tabs? You may want to make a loop that can handle this without needing to code the with blocks for each by hand.
While I haven't test it yet, I ran across this suggestion.

Wayne
  • 6,607
  • 8
  • 36
  • 93
  • Hi Wayne thank you, does a simple pie chart work? I tried your steps on my existing code but wasnt able to get anything working, so I will perhaps try to write your donut code from scratch and see if i can debug from there – Kaustav Chaudhuri Feb 11 '20 at 05:14
  • @KaustavChaudhuri Folks love to debate the merits of plots. Examples are [here](https://medium.com/@hypsypops/pie-chart-vs-donut-chart-showdown-in-the-ring-5d24fd86a9ce) and [here](https://charting-ahead.corsairs.network/doughnuts-vs-pie-a-visual-primer-629b846aac67). My donut plot is based on matplotlib's pie one Anyway, I have now added a code block that uses `plt.pie()` more like your original code. When doing that I needed to assign the plot to a variable, `my_plot` was used as an example, and use `plt.show(my_plot)` to have it display in the context of the tab. Hopefully, that is mo – Wayne Feb 11 '20 at 19:04
  • In case it helps someone attempting something related with plots, in particular pie plots with titles added, I adapted the code from here where the plot is display on a tab widget to just display multiple titled plots side-by-side on an HBox widget in an answer [here](https://stackoverflow.com/a/72722172/8508004). I explore more using the `with context` manager with plots there & so it may help someone using tab widget, too. That answer also shows how subplots could do the task too since the HBox widget doesn't really show any perceptible UI on the page, unlike the fancy tab widget used here. – Wayne Jun 23 '22 at 16:11