Usage & Examples

Basic functionalities

1. Applying the style sheet: lizard_style()

The package includes a built-in style sheet, designed to standardize and enhance the visual appeal of your plots. This style sheet configures various elements, ranging from fonts and font sizes to axis and grid settings, and even the default colors for multiple lines in a plot. Applying this style, which is also possible in the R package with + lizard_style() provides a consistent look, whether you’re using ggplot in R or matplotlib/seaborn in Python.

You can apply the Biolizard-look by placing lizard_style() at the top of your scripts after importing BioLizardStylePython. Please note that lizard_style() serves as a starting template and may not be the ideal style for every plot. You can easily customize individual style settings by placing your overrides after calling the lizard_style() function. Use plt.style.use('default') to return back to the default style.

Here’s a demonstration of how a simple line plot would look before and after applying the lizard_style():

import matplotlib.pyplot as plt
import numpy as np
from BioLizardStylePython import *
np.random.seed(42)

# Function to create random lineplot
def create_line_plot():
    x = np.linspace(0, 10, 10)
    y1 = np.sin(x) + np.random.normal(0, 0.1, size=x.shape)
    y2 = np.cos(x) + np.random.normal(0, 0.1, size=x.shape)
    y3 = x + np.random.normal(0, 0.5, size=x.shape)
    plt.figure()
    plt.plot(x, y1, label='Line 1')
    plt.plot(x, y2, label='Line 2')
    plt.plot(x, y3, label='Line 3')
    plt.title('Random Plot with 3 Lines')
    plt.xlabel('X-axis')
    plt.ylabel('Y-axis')
    plt.legend()
    plt.show()

create_line_plot()
_images/42347cb44762cf256eab64bef7799ac910a925808bcb68d2a0b1da40d9fd6b44.png
lizard_style()
create_line_plot()
_images/653d0c8292a74b3028063a651a157275e08d252d41b88868c5a9895a70c4a05f.png

2. Using the color palettes

There are two discrete colormaps and 4 continuous colormaps available in the BioLizard style packages. Discrete:

  • biolizard_qualitative_pal: Colorblind-safe qualitative color palette starting with Biolizard’s signature green, blue and yellow. This is the default for discrete data.

  • biolizard_paired_pal: Colorblind-safe qualitative color palette inspired by Biolizard’s signature colors, especially suited for levels that are related 2-by-2.

These colormaps are available as matplotlib.colors.ListedColormap objects.

Continuous:

  • biolizard_hues_pal: Designed for discrete data with many levels: Maps each level to an evenly spaced hue on the color wheel, starting with Biolizard’s signature green. DOES NOT generate colorblind-safe palettes.

  • biolizard_sequential_pal: Sequential color palette inspired by Biolizard’s signature green.

  • biolizard_divergent_pal: Divergent color palette inspired by Biolizard’s signature green.

  • l_viridis_pal: Sequential color palette inspired by the viridis color scale, passing through Biolizard’s signature yellow and green. This is the default for continuous data.

These colormaps are available as matplotlib.colors.LinearSegmentedColormap objects and have also been registered with matplotlib and can be used by passsing their name to the palette (seaborn) or cmap (matplotlib) parameters, where available.

Note that you can also access the three base colors using:

  • blz_green (“#01a086”)

  • blz_blue (#1e2237)

  • blz_yellow (#e9b940)

blz_green
'#01a086'

2.1 Discrete data

Following color scales were designed for discrete data:

biolizard_qualitative_pal: Colorblind-safe qualitative color palette starting with Biolizard’s signature green, blue and yellow. This is the default for discrete data.

biolizard_qualitative_pal
from_list
from_list colormap
under
bad
over

biolizard_paired_pal: Colorblind-safe qualitative color palette inspired by Biolizard’s signature colors, especially suited for levels that are related 2-by-2.

biolizard_paired_pal
from_list
from_list colormap
under
bad
over

biolizard_hues_pal: Note that while this is technically a continuous scale, it is designed for discrete data with many levels: Maps each level to an evenly spaced hue on the color wheel, starting with Biolizard’s signature green. DOES NOT generate colorblind-safe palettes.

biolizard_hues_pal
biolizard_hues_pal
biolizard_hues_pal colormap
under
bad
over

Adding the suffix “_r” reverses these palettes:

biolizard_qualitative_pal_r
from_list_r
from_list_r colormap
under
bad
over

Colors can be retrieved from the discrete colorscales by passing a range to the palettes (returns an array of rgba values), or by using the .colors attribute (returns a list of all colors in the palette).

biolizard_qualitative_pal(range(5))
array([[0.00392157, 0.62745098, 0.5254902 , 1.        ],
       [0.11764706, 0.13333333, 0.21568627, 1.        ],
       [0.91372549, 0.7254902 , 0.25098039, 1.        ],
       [0.36470588, 0.49411765, 0.64705882, 1.        ],
       [0.5254902 , 0.00784314, 0.00784314, 1.        ]])
biolizard_qualitative_pal.colors
['#01A086',
 '#1E2237',
 '#E9B940',
 '#5D7EA5',
 '#860202',
 '#89D2C6',
 '#C56F27',
 '#EED8A1',
 '#9CAEC3',
 '#B073DE',
 '#03F2F7',
 '#71BD8B']

Since biolizard_hues_pal is encoded as a continuous color palette, passing a range will lilely NOT yeild the desired effect, as the continuous color scale is represented by a sequence of 255 colors. Passing e.g. range(5) will only retrieve the first 5 of these 255 colors. Instead, use np.linspace to ensure all colors are spaced evenly across the colorscale:

ncolors = 5
rgbacolors = biolizard_hues_pal(np.linspace(0, 1, ncolors))

Then, you can use matplotlib.colors.rgb2hex to obtain hex values if needed:

[matplotlib.colors.rgb2hex(col) for col in rgbacolors]
['#319d74', '#4f93ba', '#b975ad', '#b4805c', '#669855']
2.1.1 Seaborn

Note that biolizard_qualitative_pal is the default colorscale for discrete data:

import seaborn as sns
# Sample data
data = sns.load_dataset("iris")
sns.swarmplot(x="species", y="sepal_length", hue ="species", data=data)
plt.title('A Flower Plot')
plt.show()
_images/33988d2de57151ed11fabe24381ac7c5945e777aa3ca9fb243d689a11494622d.png

Other discrete colormaps can be chosen by specifying a list of colors:

sns.swarmplot(x="species", y="sepal_length", hue ="species", data=data, palette=biolizard_paired_pal.colors)
plt.title('A Flower Plot: manual discrete palette')
plt.show()
/tmp/ipykernel_1937011/3631860700.py:1: UserWarning: The palette list has more values (10) than needed (3), which may not be intended.
  sns.swarmplot(x="species", y="sepal_length", hue ="species", data=data, palette=biolizard_paired_pal.colors)
_images/656e7ad4950170fcc46ac9d75a9a5d785ab45ecb0c4032dab7d950d2ea9962c7.png

Continuous colormaps can be referenced by their name, this ensures that colors are picked across the entire range of the continous scale:

sns.swarmplot(x="species", y="sepal_length", hue ="species", data=data, palette="biolizard_sequential_pal")
plt.title('A Flower Plot: manual continuous palette')
plt.show()
_images/70e3d7bc79756f70cfa8d484472d338ec94f0dfd1ea4e0cadde6a3b0a1be8e38.png
2.1.2 Matplotlib

Colors from the discrete scale can be passed to the color parameter of plt.bar for example:

# Data for the bar plot
categories = ['A'+str(i) for i in range(12)]
values = [4, 7, 1, 8]*3

# Create the bar plot
# .colors returns a list that can be used for the color parameter 
plt.figure(figsize=(8, 6))
bars = plt.bar(categories, values, color=biolizard_paired_pal.colors)

# Add title and labels
plt.title('Example Bar Plot')
plt.xlabel('Categories')
plt.ylabel('Values')

plt.show()
_images/301920f5c4c251a21ec17256326b208644bfff5220f1b84cddd61f43221b7c0d.png

Note that in case the colorscale contains less levels than the data, colors are recycled without warning!

To use a continuous scale, we need to take colors at regular intervals across the colormap:

# take colors at regular intervals across the colormap
colors = biolizard_hues_pal(np.linspace(0, 1, len(categories)))

bars = plt.bar(categories, values, color=colors)

# Add title and labels
plt.title('Example Bar Plot')
plt.xlabel('Categories')
plt.ylabel('Values')

plt.show()
_images/abc530885446398cb8cbbf48cfd3de54ddc37deef0efaa8663df5b13f49e0a04.png

2.2 Continuous data

Following color scales were designed for continous data:

l_viridis_pal: Sequential color palette inspired by the viridis color scale, passing through Biolizard’s signature yellow and green. This is the default for continuous data.

l_viridis_pal
l_viridis_pal_r_r
l_viridis_pal_r_r colormap
under
bad
over

biolizard_sequential_pal: Sequential color palette inspired by Biolizard’s signature green.

biolizard_sequential_pal
biolizard_sequential_pal
biolizard_sequential_pal colormap
under
bad
over

biolizard_divergent_pal: Divergent color palette inspired by Biolizard’s signature green.

biolizard_divergent_pal
biolizard_divergent_pal
biolizard_divergent_pal colormap
under
bad
over

Adding the suffix “_r” reverses these palettes:

biolizard_divergent_pal_r
biolizard_divergent_pal_r_r
biolizard_divergent_pal_r_r colormap
under
bad
over

Colors can be retrieved from the continuous colorscales by passing an array of the desired length to the palettes, this returns an array of rgba values. Note that internally, each continuous color scale is represented as a sequence of 255 colors. All these colors can be retrieved by passing range(255) to your color scale of choice:

l_viridis_pal(range(255))
array([[0.98047708, 0.74741876, 0.32824584, 1.        ],
       [0.97453872, 0.74675386, 0.3270615 , 1.        ],
       [0.96860339, 0.74608207, 0.3259049 , 1.        ],
       ...,
       [0.10233947, 0.28989547, 0.47624979, 1.        ],
       [0.10272789, 0.28712708, 0.47695401, 1.        ],
       [0.10313784, 0.28434012, 0.47768985, 1.        ]])

When manually selecting colors from the palette, use np.linspace to ensure colors are spaced evenly across the palette:

ncolors = 10
rgbacolors = l_viridis_pal(np.linspace(0, 1, ncolors))

Lastly, you can use matplotlib.colors.rgb2hex to obtain hex values if needed:

[matplotlib.colors.rgb2hex(col) for col in rgbacolors]
['#fabf54',
 '#d0b94e',
 '#a5b24f',
 '#79a957',
 '#519e62',
 '#318f6d',
 '#1f7e74',
 '#196c76',
 '#195b77',
 '#1a487a']
2.2.1 Matplotlib

Note that l_viridis is the default colorscale:

data = np.random.rand(5, 5)  # Example data
plt.imshow(data)
plt.colorbar()
plt.show()
_images/6efd2c97b263d21e1149164ffa7450926dfddbec2bd9c9f401f7f509328910ae.png

The continous palettes have been registered with matplotlotlib and their names can be passed to the cmap parameter to change the continuous scale:

plt.imshow(data, cmap='biolizard_sequential_pal')
plt.colorbar()
plt.show()

plt.imshow(data, cmap='biolizard_divergent_pal')
plt.colorbar()
plt.show()
_images/a9596d80067d4715be2b86148c0ac061970626d19380a278ce348d00a39678e5.png _images/c52289a71773b7dec7edf6b2a1b3ec83d5db09194a1c332ddb708aa91f79dff3.png

The corresponding palettes with suffix ‘_r’ reverse the colors:

plt.imshow(data, cmap='biolizard_divergent_pal_r')
plt.colorbar()
plt.show()
_images/b4289f0135c76bfd74b0ac25537e3b0a5f1e48244865c8f73cf45c41a6e5472d.png
2.2.2 Seaborn

!! default not working for some reason:

data = sns.load_dataset("iris")
sns.swarmplot(x="species", y="sepal_length", hue ="sepal_length", data=data)
plt.title('A Flower Plot')
plt.show()
_images/44be4ceb4382486281fe828c3497312eb97c8bbcdc676b64554d296ee90c856c.png

The names of the palettes can be passed to the palette parameter to change the continuous scale:

data = sns.load_dataset("iris")
sns.swarmplot(x="species", y="sepal_length", hue ="sepal_length", data=data, palette="biolizard_sequential_pal")
plt.title('A Flower Plot')
plt.show()
_images/2b4c5eb82d21eb627f298e2c05d6641a5488e7207e1ab3aead40cd2987387bc4.png

Examples

1. simple boxplot

sns.boxplot(x="species", y="sepal_length", data=data)
plt.title('A Flower Plot')
plt.show()
_images/5d47788bf1943f70f4c6ff477447ae90597780694ae61a51c2db51034d880996.png

A violin plot is similar to a boxplot, but captures more information on the data distribution:

sns.violinplot(x="species", y="sepal_length", data=data)
plt.title('A Flower Plot')
plt.show()
_images/0aef12db26b90dc5cf9c9f0c706c9571e443f3fa474c2fe3aeb2750372b45f81.png

2. Simple density plot

sns.displot(data, x="sepal_length", hue="species", kind="kde", fill=True)
plt.title('A Flower Plot')
plt.show()
_images/002562c6a261c655bba3cdff70617555c2b24c3a00c8210cb3becd170052b89f.png

3. Simple scatterplot

sns.scatterplot(data, x='sepal_length', y='petal_length', hue='petal_length', palette='l_viridis_pal')
plt.title('A Flower Plot')
plt.show()
_images/e6114ae4b247bdb51ad8f37f00440ff36812a3ab1c32f07fd543d518c8996be2.png

We can use lmplot or regplot to add a regression line:

import scipy as sp

g = sns.lmplot(data, x='sepal_length', y='petal_length', line_kws=dict(color=blz_blue))

def annotate(data, **kws):
    r, p = sp.stats.pearsonr(data['sepal_length'], data['petal_length'])
    ax = plt.gca()
    ax.text(.05, .8, '$r^2$={:.2f}, p={:.2g}'.format(r**2, p),
            transform=ax.transAxes)
    
g.map_dataframe(annotate)
plt.title('A Flower Plot')
plt.show()
_images/f40587a724e4f53c549cfa29ad01c85ac13ebff9092d91775f3390cc12b64bc0.png
# specify hue to show the three species
sns.lmplot(data, x='sepal_length', y='petal_length', hue='species')
<seaborn.axisgrid.FacetGrid at 0x784fad25cf50>
_images/4f8407ceb5f357e76a8ae5f73bcb98f5a0b782b0b55b3a49e67d33792153b657.png

Note that using the reversed palette starts picking the colors from the end of the palette. If you want to pick the colors you need, and reverse them afterward (eg yellow-blue-green instead of green-blue-yellow), use the regular palette and reverse the colors after picking them:

my_colors = biolizard_qualitative_pal.colors[0:3]

fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(10,5))

# regular palette
sns.scatterplot(data, x='sepal_length', y='petal_length', hue='species',
           palette=my_colors, ax=axes[0])
axes[0].set_title('Regular palette')

# reversed
my_colors.reverse()
sns.scatterplot(data, x='sepal_length', y='petal_length', hue='species',
           palette=my_colors, ax=axes[1])
axes[1].set_title('Reversed palette')

fig.show()
/tmp/ipykernel_1937011/3460807827.py:16: UserWarning: FigureCanvasAgg is non-interactive, and thus cannot be shown
  fig.show()
_images/f891edf3027b9575252890a07d50a1e002dff950215f98038264cc04068bd852.png

4. Facets

Facetting is a great way to lay out related plots side-by-side, with the axes either on the same scale or on different scales.

g = sns.FacetGrid(data, col="species")
g.map_dataframe(sns.scatterplot, x='sepal_length', y='petal_length')
<seaborn.axisgrid.FacetGrid at 0x784fad10bfe0>
_images/ccb86c22c27e921201d69b0753ca84774e4b4c73394358ad3258794f36e5a6a4.png

5. Treemap plots

Treemap plots can be used as an alternative for bar charts, for example when there are so many categories that a bar chart may not be clear anymore. In this example, more colors are requested than are present in the qualitative color scales. The biolizard_hues_pal palette was developped for situations like this. It maps each level to an evenly spaced hue on the color wheel, starting with Biolizard’s signature green, but it DOES NOT generate colorblind-safe palettes.

import squarify

# Sample data
values = [250, 120, 280, 320, 140, 95, 87, 270, 896, 25, 654, 78, 37]
labels = ['Group'+str(i) for i,_ in enumerate(values)]

# take colors at regular intervals across the colormap
colors = biolizard_hues_pal(np.linspace(0, 1, len(values)))

# Treemap
squarify.plot(sizes = values, label = labels, color = colors,
              text_kwargs={'color':'black'},
              edgecolor="black", linewidth=2)

# Remove the axis:
plt.axis("off")

plt.show()
_images/607155767ca0515ae66ef1fc2f40fd393f0dd0181b9617175ff1a5d6371a2b57.png

6. Fun with maps

This example was taken from: https://matplotlib.org/basemap/stable/users/examples.html.

from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
from datetime import datetime

# miller projection 
map = Basemap(projection='mill',lon_0=0)
# plot coastlines, draw label meridians and parallels.
map.drawcoastlines()
map.drawparallels(np.arange(-90,90,30),labels=[1,0,0,0])
map.drawmeridians(np.arange(map.lonmin,map.lonmax+30,60),labels=[0,0,0,1])
map.drawmapboundary(fill_color=blz_blue)
map.fillcontinents(color=blz_green,lake_color=blz_blue)
# shade the night areas, with alpha transparency so the 
# map shows through. Use current time in UTC.
date = datetime.now()
CS=map.nightshade(date)
plt.title('Day/Night Map for %s (UTC)' % date.strftime("%d %b %Y %H:%M:%S"))
plt.show()
_images/952a8631374d8eb0b3b7c429fe57a460a975639f66cd22eb755e1a8c7e4ed61a.png