plotly#

As of v0.6, fivecentplots plotly can be used as the plotting engine instead of matplotlib.

Setup#

First-time setup:

plotly is not currently part of the default package requirements for fcp so it is not automatically installed. For inline usage:

[ ]:
pip install plotly

To save and/or show plotly images as .png files automatically with keyword save or show, an additional package install is required:

[ ]:
pip install kaleido

Switching engines:

Since matplotlib is the default plotting engine in fivecentplots, the user must manually invoke the plotly engine. This can be done on a per-plot basis via the engine kwarg or by updating the global kwargs so the change persists within the users current interactive environment

Per-plot:

[ ]:
fcp.plot(df, x='x', y='y', engine='plotly')

Global (i.e., all plots):

[ ]:
fcp.KWARGS['engine'] = 'plotly'

Themes:

Due to differences between plotting libraries, it was found that the default fivecentplots theme files were not ideal in plotly. It is also therefore recommended to update to a plotly-specific theme when using this engine:

[ ]:
fcp.set_theme('gray_plotly')

Maturity:

All plot types except gantt have been ported to plotly with some base level of support. However, feature parity with matplotlib has not yet been achieved. Please open a new support issue if a needed feature is missing.

Some plot examples are demonstrated below, but the demonstration is not exhaustive and many other plot configurations are still available.

Imports#


import fivecentplots as fcp
import pandas as pd
import imageio.v3 as imageio
import cv2
from pathlib import Path
import plotly
plotly.offline.init_notebook_mode()

Engine and themes#


fcp.KWARGS['inline'] = True
fcp.KWARGS['engine'] = 'plotly'

fcp.set_theme('gray_plotly')
Previous theme file found! Renaming to "defaults_old.py" and copying theme "gray_plotly"...done!

Sample data#

Several data sets are used in this tutorial:

x-y data#


df_xy = pd.read_csv(Path(fcp.__file__).parent / 'test_data/fake_data.csv')
df_xy.head(10)

Substrate Target Wavelength Boost Level Temperature [C] Die Voltage I Set I [A]
0 Si 450 0.2 25 (1,1) 0.0 0.0 0.0
1 Si 450 0.2 25 (1,1) 0.1 0.0 0.0
2 Si 450 0.2 25 (1,1) 0.2 0.0 0.0
3 Si 450 0.2 25 (1,1) 0.3 0.0 0.0
4 Si 450 0.2 25 (1,1) 0.4 0.0 0.0
5 Si 450 0.2 25 (1,1) 0.5 0.0 0.0
6 Si 450 0.2 25 (1,1) 0.6 0.0 0.0
7 Si 450 0.2 25 (1,1) 0.7 0.0 0.0
8 Si 450 0.2 25 (1,1) 0.8 0.0 0.0
9 Si 450 0.2 25 (1,1) 0.9 0.0 0.0

Time series data#


ts = pd.read_csv(Path(fcp.__file__).parent / 'test_data/fake_ts.csv')
ts.head()

Date Happiness Quotient
0 1/1/2015 16.088954
1 1/2/2015 18.186724
2 1/3/2015 35.744313
3 1/4/2015 38.134045
4 1/5/2015 46.147279

Bar plot data#


df_bar = pd.read_csv(Path(fcp.__file__).parent / 'test_data/fake_data_bar.csv')
df_bar.head()

Liquid pH Measurement T [C]
0 Lemon juice 2.4 A 25
1 Orange juice 3.5 A 25
2 Battery acid 1.0 A 25
3 Bottled water 6.7 A 25
4 Coke 3.0 A 25

Box plot data#


df_box = pd.read_csv(Path(fcp.__file__).parent / 'test_data/fake_data_box.csv')
df_box.head()

Batch Sample Region Value ID
0 101 1 Alpha123 3.5 ID701223A
1 101 1 Alpha123 0.0 ID7700-1222B
2 101 1 Alpha123 3.3 ID701223A
3 101 1 Alpha123 3.2 ID7700-1222B
4 101 1 Alpha123 4.0 ID701223A

Contour data#


df_contour = pd.read_csv(Path(fcp.__file__).parent / 'test_data/fake_data_contour.csv')
df_contour.head()

Experiment Batch X Y Value
0 Control 101 1 -4 3.5
1 Control 101 1 -2 2.1
2 Control 101 1 0 3.3
3 Control 101 1 2 3.2
4 Control 101 1 4 4.0

Heatmap data#


df_heatmap = pd.read_csv(Path(fcp.__file__).parent / 'test_data/fake_data_heatmap.csv')
df_heatmap.head()

Player Category Average
0 Lebron James Points 27.5
1 Lebron James Assists 9.1
2 Lebron James Rebounds 8.6
3 Lebron James Blocks 0.9
4 James Harden Points 30.4

Histogram data#


df_hist = pd.read_csv(Path(fcp.__file__).parent / 'test_data/fake_data_box.csv')
img_hist = cv2.imread(str(Path(fcp.__file__).parent / 'test_data/imshow_cat_pirate.png'))

Image data#


img_bgr = cv2.imread(str(Path(fcp.__file__).parent / 'test_data/imshow_cat_pirate.png'))
img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)

plot#

No legend#


fcp.plot(df_xy, x='Voltage', y='I [A]', lines=False, ax_size=[400, 400])

Filtered#


fcp.plot(df_xy, x='Voltage', y='I [A]', title='IV Data', lines=False,
         filter='Substrate=="Si" & Target Wavelength==450 & Boost Level==0.2 & Temperature [C]==25')

Legend#


fcp.plot(df_xy, x='Voltage', y='I [A]', legend='Die',
         filter='Substrate=="Si" & Target Wavelength==450 & Boost Level==0.2 & Temperature [C]==25')

Log axis#

Note

symlog and logit not yet supported


fcp.plot(df_xy, x='Voltage', y='I [A]', ax_scale='loglog', legend='Die', xmin=0.9, xmax=2.1, grid_minor=True,
         filter='Substrate=="Si" & Target Wavelength==450 & Boost Level==0.2 & Temperature [C]==25')

Categorical ticks#


fcp.plot(df_xy, x='Die', y='I [A]',
         filter='Substrate=="Si" & Target Wavelength==450 & Boost Level==0.2 & Temperature [C]==25 & Voltage==1.5')

Time series#


fcp.plot(ts, x='Date', y='Happiness Quotient', markers=False, ax_size=[1000, 250])

Secondary axes#


fcp.plot(df_xy, x='Voltage', y=['Voltage', 'I [A]'], twin_x=True, legend='Die',
         grid_major_y2=True, grid_major_y2_style='--', y2max=1.4,
         filter='Substrate=="Si" & Target Wavelength==450 & Boost Level==0.2 & Temperature [C]==25 & Die=="(-1,2)"')

Multiple x & y values#


fcp.plot(df_xy, x=['Boost Level', 'I [A]'], y=['Voltage', 'Temperature [C]'], legend='Die',
         filter='Substrate=="Si" & Target Wavelength==450 & Boost Level==0.2 & Temperature [C]==25')

Grouping#

Row plot#


fcp.plot(df_xy, x='Voltage', y='I [A]', legend='Die', row='Boost Level', ax_size=[225, 225], legend_edge_color='#000000',
         filter='Substrate=="Si" & Target Wavelength==450 & Temperature [C]==25', label_row_fill_color='#000000', ax_edge_width=4,
         label_row_font_color='#ff0000', label_row_edge_color='#0000ff', label_row_edge_width=2, legend_edge_width=3)

Column plot#


fcp.plot(df_xy, x='Voltage', y='I [A]', legend='Die', col='Boost Level', ax_size=[225, 225], legend_edge_color='#000000',
         filter='Substrate=="Si" & Target Wavelength==450 & Temperature [C]==25', label_col_fill_color='#000000', label_col_font_color='#ff0000')

Row x column grid#


fcp.plot(df_xy, x='Voltage', y='I [A]', legend='Die', col='Boost Level', row='Temperature [C]',
         modebar_visible=True, modebar_fill_color='#000000', ax_edge_width=1, ymin=0,
         ax_size=[225, 225], filter='Substrate=="Si" & Target Wavelength==450', label_rc_font_size=13)

Wrap plot#


fcp.plot(df_xy, x='Voltage', y='I [A]', legend='Die', wrap=['Temperature [C]', 'Boost Level'],
         ax_size=[225, 225], filter='Substrate=="Si" & Target Wavelength==450', label_rc_font_size=13)

Horizontal & vertical lines#


fcp.plot(df_xy, x='Voltage', y='I [A]', title='IV Data', lines=False, legend=True,
         filter='Substrate=="Si" & Target Wavelength==450 & Boost Level==0.2 & Temperature [C]==25',
         ax_hlines=[(0, '#FF0000', '--', 3, 1, 'Open', '#555555', 0.25), 1.2],
         ax_vlines=[(0.6, '#0000ff', ':'), (1, '#00FF00')])

Curve fitting#


fcp.plot(df_xy, x='Voltage', y='I [A]', title='IV Data', lines=False,
         filter='Substrate=="Si" & Target Wavelength==450 & Boost Level==0.2 & Temperature [C]==25',
         fit=1, fit_eqn=True, fit_rsq=True, fit_range_x=[1.3, 2])

Stat Lines#


fcp.plot(df_xy, x='Voltage', y=['Boost Level', 'I [A]'], legend=True, stat='median',
         filter='Substrate=="Si" & Target Wavelength==450 & Boost Level==0.2 & Temperature [C]==25')

Confidence intervals#

To demonstrate this feature we will use a special dataset:


df_interval = pd.read_csv(Path(fcp.__file__).parent / 'test_data/fake_data_interval.csv')
df_interval.head()

x y
0 -1.0 -10.715459
1 -1.0 -9.972410
2 -1.0 -30.740532
3 -1.0 -31.368963
4 -1.0 -29.058633

fcp.plot(df_interval, x='x', y='y', lines=False, conf_int=0.95)

Control limits#


fcp.plot(df_interval, x='x', y='y', lines=False, ucl=50, lcl=-50, ucl_fill_color='#FF0000', legend=True)

Reference line#


fcp.plot(df_xy, x='Voltage', y='I [A]', title='IV Data', legend='Die',
         filter='Substrate=="Si" & Target Wavelength==450 & Boost Level==0.2 & Temperature [C]==25',
         ref_line=df_xy['Voltage'], ref_line_legend_text='y=x', xmin=0, ymin=0, xmax=1.6, ymax=1.6)

bar#

Simple#


fcp.bar(df_bar, x='Liquid', y='pH', filter='Measurement=="A" & T [C]==25', horizontal=True)

Legend#


fcp.bar(df_bar, x='Liquid', y='pH', tick_labels_major_x_rotation=90, legend='Measurement')

Stacked#


fcp.bar(df_bar, x='Liquid', y='pH', tick_labels_major_x_rotation=90, stacked=True, legend='Measurement')

Grouping#


fcp.bar(df_bar, x='Liquid', y='pH', tick_labels_major_x_rotation=90, col='Measurement', row='T [C]', ax_hlines=0, ax_size=[300, 300])

boxplot#

Basic#


fcp.boxplot(df_box, y='Value', groups=['Batch', 'Sample'], group_means=True)

Legend#


df_box['Row'] = [int(f) for f in df_box.index / 4]
fcp.boxplot(df_box, y='Value', groups=['Batch', 'Sample'], mean_diamonds=True, conf_coeff=0.95, legend='Row')

Violins#


fcp.boxplot(df_box, y='Value', groups=['Batch', 'Sample'], violin=True)

Grouping#


fcp.boxplot(df_box, y='Value', groups=['Batch', 'Sample'], col='Region', ax_size=[300, 300])

Note

auto-sizing for boxplot is not yet available with plotly

contour#

No fill#


fcp.contour(df_contour, x='X', y='Y', z='Value', filled=False, cbar=False)

Points#


fcp.contour(df_contour, x='X', y='Y', z='Value', filled=False, levels=40, contour_width=2,
            xmin=-4, xmax=5, ymin=-4, ymax=6, cbar=True,
            show_points=True, marker_size=26, marker_fill_color='#00FF00')

Grid with fill#


fcp.contour(df_contour, x='X', y='Y', z='Value', row='Batch', col='Experiment', filled=True,
            cbar=False, xmin=-3, xmax=3, ymin=-3, ymax=3, ax_size=[250,250],
            label_rc_font_size=12, levels=40)

gantt#

Better luck next time…

heatmap#


fcp.heatmap(df_heatmap, x='Category', y='Player', z='Average')

hist#

Basic#


fcp.hist(df_hist, x='Value', horizontal=True, bins=20)

kde#


fcp.hist(df_hist, x='Value', legend='Region', kde=True, kde_width=2)

Image#


fcp.hist(img_rgb, legend='Channel', markers=False, ax_size=[600, 400], line_width=2, colors=fcp.RGB)

imshow#

RGB#


fcp.imshow(img_rgb, ax_size=[600, 300])

Raw / Grayscale#


img_raw = fcp.utilities.img_grayscale(img_rgb)
fcp.imshow(img_raw, ax_size=[600, 600], title='Fake RAW, Fake Pirate', cbar=True, title_edge_width=1, title_edge_color='#ff0000')

Grid#


url = 'https://upload.wikimedia.org/wikipedia/commons/2/28/RGB_illumination.jpg'
img_rgb_sp = imageio.imread(url)
img_raw_sp = fcp.utilities.rgb2bayer(img_rgb_sp)
fcp.imshow(img_raw_sp, cmap='inferno', ax_size=[300, 300], cfa='rggb', wrap='Plane', ax_edge_width=1, ax_edge_color='#555555')

nq#

Basic#


fcp.nq(df_box, x='Value', marker_size=4, line_width=2)

Image#


img_rgb = cv2.imread(str(Path(fcp.__file__).parent / 'test_data/imshow_cat_pirate.png'))
img_cat = fcp.utl.img_grayscale(img_rgb, bit_depth=12)
fcp.nq(img_cat, marker_size=4, line_width=2)

pie#

Basic#


df_pie = df_bar.copy()
df_pie.loc[df_pie.pH < 0, 'pH'] = -df_pie.pH
fcp.pie(df_pie, x='Liquid', y='pH', filter='Measurement=="A" & T [C]==25')

Legend#


fcp.pie(df_pie, x='Liquid', y='pH', filter='Measurement=="A" & T [C]==25', explode=[0.1], legend=True)