Skip to main content

A library for creating scatterplots using visual entropy glyphs.

Project description

vizent


A python library for bivariate glyphs integrated with matplotlib

This library allows the user to create visualizations using Visual Entropy Glyphs[1]. Vizent glyphs are designed to help when you need to add an extra data variable to a scatter plot, a map or a graph. Vizent glyphs are bivariate, that is they allow you to represent two variables at each point on your plot. A central coloured disc is able to represent a continuous variable, an enclosing shape can represent a continuous interval or categorical variable using increasing levels of visual entropy (shape complexity).

Applications for the Vizent glyphs include:

  • when you need represent uncertainty, eg a mean and a standard deviation
  • when you need to represent derivatives, eg a rate and an acceleration
  • any other pair of values at a point on a plot

Vizent supports scatter plots on a plain background, a cartopy map background, or using an image as a background. It is also possible to add further elements to your figure using standard matplotlib calls. See the examples below, or for a detailed tutorial see [medium article, ETA 01/03/2021] and do get in touch if you have suggestions for improvements.

Installation

vizent can be installed using pip

pip install vizent

vizent on PyPI

Dependencies:

  • matplotlib
  • numpy
  • scipy
  • pillow
  • cartopy
    • Cython
    • GEOS
    • Shapely
    • pyshp
    • PROJ.4
    • six

If using Anaconda Python these will likely be included.

Using vizent

vizent_plot()

Produces a scatter plot from the provided points. Each point is displayed as a visual entropy glyph.

Parameters:

  • x_values (list of floats): list of x coordinates
  • y_values (list of floats): list of y coordinates
  • colour_values (list of floats): list of values to be represented using colour
  • shape_values (list of floats): list of values to be represented using shape
  • size_values (list of floats): list of values for diameters of glyphs in points.
  • colormap (colormap or registered colormap name): Optional. Use any matplotlib colormap. See here for full range of options. Alternatively, use "metoffice" to use the MetOffice temperature colour scheme.
  • scale_x (float): Optional. Defines x size (width) of plot window in inches.
  • scale_y (float): Optional. Defines y size (height) of plot window in inches. If neither scale_x nor scale_y is specified, the plot will be scaled automatically. If only one is specified, the other will be adjusted to suit the proportions of the plot.
  • use_image (bool): Optional. If True, plot on an image background. This can be your own image, or certain included image background can be used, see image_type.
  • image_type (str): Optional. Use one of the included image backgrounds. Use "newcastle" for detailed 3D rendering of Newcastle Upon Tyne which will be selected based on the coordinates of your points (use eastings and northings for x and y, note that a limited area is available currently), or "england" for OSM england map (use grid ref for x and y).
  • image_file (str): Optional. The image file to use as image background.
  • use_cartopy (bool): Optional. Plot the points on Cartopy map.
  • extent (list of floats): Optional. If not specified, this will be generated based on the coordinates of your points such that they are all included. This is not needed when using a preset image type.
  • scale_diverges (bool): Optional. If True, diverging sets of glyphs are used for positive and negative values. If not specified, your scale will diverge if both positive and negative values are included for the shape variable.
  • shape (str): Optional. Glyph shape design to use for non-divergent scales. Default is sine. Available designs are:
    • "sine"
    • "saw"
    • "reverse_saw"
    • "square"
    • "triangular"
    • "concave"
    • "star"
  • shape_pos (str): Optional. When using divergent scale, glyph shape design to use for positive values. Default is sawtooth. Available designs as above.
  • shape_neg (str): Optional. When using divergent scale, glyph shape design to use for negative values. Default is sawtooth. Available designs as above.
  • colour_max (float): Optional. Maximum value to use for colour in key.
  • colour_min (float): Optional. Minimum value to use for colour in key.
  • colour_n (int): Optional. Number of colour values to be shown in key.
  • colour_spread (float): Optional. Total range of colour values in key. Only use if not specifying both max and min.
  • shape_max (float): Optional. Maximum value to use for shape in key.
  • shape_min (float): Optional. Minimum value to use for shape in key.
  • shape_n (int): Optional. Number of shape values to be shown in key. If using a diverging scale, this is the number of positive values including zero. Negative values will reflect positive values.
  • shape_spread (float): Optional. Total range of shape values in key. Only use if not specifying max and min.
  • colour_label (str): Optional. Text label for colour values in key.
  • shape_label (str): Optional. Text label for shape values in key.
  • title (str): Optional. Title to display at top.
  • x_label (str): Optional. Label for x axis. Not shown for image plots.
  • y_label (str): Optional. Label for y axis. Not shown for image plots.
  • show_axes (bool): Optional. If axes are not wanted, e.g. for image plots, set to False.
  • save (bool): Optional. If True, save the plot as png.
  • file_name (str): Optional. If save, name of saved file.
  • return_axes (bool): Optional. If True, the function will return fig, ax1. These can be used to add more MatPlotLib elements, such as lines, text boxes.
  • scale_dp (int): Optional. The number of decimal places that scale values should be rounded to.
  • interval_type (str): Optional. This defines how the shape of each glyph is determined:
    • "closest": use the closest scale value
    • "limit": use the highest scale value that the glyph value is greater than or equal to (based on modulus for negative values)
  • show_legend (bool): Optional. Specify whether or not to display the legend to the right of the plot.

Glyph Designs

The available glyph shape designs are shown here in full. Value increases with frequency from left (lowest) to right (highest).

sine

sine glyphs

saw

saw glyphs

reverse_saw

reverse_saw glyphs

square

square glyphs

triangular

triangular glyphs

concave

concave glyphs

star

star glyphs

Examples

Create a basic scatterplot:

from vizent import vizent_plot

x_values = [1,2,3,4,5,6,7]
y_values = [6,3,7,1,4,2,5]
colour_values = [0,3,6,9,12,15,18]
shape_values= [0,1,2,3,4,5,6]
size_values = [30,60,30,45,60,30,45]

vizent_plot(x_values, y_values, colour_values, shape_values, size_values,
            colour_label="colour", shape_label="shape",
            title="A plot with a title", x_label="This is the x axis",
            y_label="This is the y axis")

scatterplot image

Create a map using Cartopy:

from vizent import vizent_plot
import pandas as pd

data = pd.read_csv("englandRegions.csv")
x = data['long'].tolist()
y = data['lat'].tolist()
cases = data['dailyCases'].tolist()
accel = data['accel'].tolist()

size = [30]*len(x)
extent = [-6, 2, 49.9, 56]

vizent_plot(x, y, cases, accel, size, shape_label="Acceleration", 
            colour_label="Daily cases", use_cartopy=True, extent=extent, 
            title='COVID19 daily case count and one day acceleration \n'
            'English regions, 30th October 2020') 

cartopy image

Create a map of england using an image background:

from vizent import vizent_plot
import pandas as pd

data = pd.read_csv("englandRegions.csv")
x = data['long'].tolist()
y = data['lat'].tolist()
cases = data['dailyCases'].tolist()
accel = data['accel'].tolist()

size = [30]*len(x)

vizent_plot(x, y, cases, accel, size, shape_label="Acceleration",
            colour_label="Daily cases", use_image=True,
            image_type="england", title="COVID19 daily case count and one "
            "day acceleration \n English regions, 30th October 2020")

map image

Map © OpenStreetMap contributors

Use detailed background images of Newcastle Upon Tyne:

from vizent import vizent_plot
import pandas as pd

data = pd.read_csv("cleaned_temp_data.csv")
eastings = data['easting'].tolist()
northings = data['northing'].tolist()
average = data['Average of Value'].tolist()
variance = data['Variance of Value'].tolist()

size = [20]*len(eastings)

vizent_plot(eastings, northings, average, variance, size, 
            "metoffice", shape_label="variance", 
            colour_label="temperature", use_image=True, 
            image_type="newcastle", colour_spread=20,
            title="Newcastle Upon Tyne Temperature Data",
            show_axes=False)

newcastle image

Add your own MatPlotLib elements to the plot:

from vizent import vizent_plot
import numpy as np

# Let's take an example of a vizent plot and add to it

x = [0.05,0.35,0.75,0.9,1.35,1.55,1.85]
y = [(1 + np.sin(2 * np.pi * i)) for i in x]
colour_values = [0,3,7,2,-1,10,6]
shape_values = [1,2,3,2.3,0,3,2]
size = [30,30,30,30,30,30,30]

# Assign the output of the function to fig, ax as shown

fig, ax = vizent_plot(x, y, colour_values, shape_values, size, 
                      colormap="rainbow", shape_label="shape", 
                      colour_label="colour", return_axes=True, 
                      title="An example of adding to your plot")

# Let's add a line to the plot

t = np.arange(0.0, 2.0, 0.01)
s = 1 + np.sin(2 * np.pi * t)

# Adjust zorder to control whether line is behind or in front of points, 
# background image etc. In this case, zorder=0 places the line behind the 
# points while zorder=1 would place it in front. If using a background
# image, zorder=0.5 places the line in front of the background image, 
# but behind the points.

ax.plot(t, s, zorder=0)

# Let's also add a text box with some additional information, such as the 
# data source

props = dict(boxstyle='round', facecolor='wheat', alpha=0.5)
text = "Source: Some Official Data Source"

# Text box position can be adjusted

ax.text(0.05, -0.1, text, transform=ax.transAxes, fontsize=14,
        verticalalignment='top', bbox=props)

# And you can adjust the space around the subplot to ensure the text box
# is shown if it is outside of the axes

plt.subplots_adjust(bottom=0.15)

plt.show()
plt.close()  

custom plot example

Release History

  • 1.0 First release 24/02/2021

Meta

Author: Lucy McLaughlin

lucy.mclaughlin@newcastle.ac.uk

vizent on github

vizent on PyPI

Distributed under the MIT license. See LICENSE for more information.

Acknowledgments: The Alan Turing Institute for funding the Newcastle Seedcorn project "Automating visualization", under the EPSRC grant EP/N510129/1 and for Nick Holliman's Turing Fellowship.

[1] "Visual Entropy and the Visualization of Uncertainty", Holliman et al, arXiv:1907.12879

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

vizent-1.0.1.tar.gz (46.3 MB view hashes)

Uploaded Source

Built Distribution

vizent-1.0.1-py3-none-any.whl (46.3 MB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page