Data Visualization with Python

Sachin Joshi

Research Computing

Data Visualization

  • Trying to understand data by placing it in a visual context
  • Helps discover patterns, trends and correaltions that might not be otherwise detected
  • Python offers multiple graphing libraries with lots of different features
  • Create interactive, live or highly customized plots with Python

Plotting Libraries

  • Matplotlib:low level, most popular, provides lots of freedom
  • Pandas Visualization:easy to use interface, built on Matplotlib
  • Seaborn:based on Matplotlib, provides a high-level interace for drawing attractive and informative stastical graphics
  • ggplot:based on R's ggplot2, plots quickly with minimal code
  • Plotly:can create interactive, publication-quality graphs online

Modules

  • A file containing Python definitions and statements
  • Python module is a normal python file which can store function, variable and classes
  • Also include runnable code
  • Module helps us to organize related codes - makes the code easier to understand and run
  • A Python object with arbitarily named attributes that you can bind and reference
  • Popular modules
    • math
    • numpy
    • scipy
    • matplotlib
    • pandas

Creating Modules

  • Create a new file called mymodule.py and write the following code
In [4]:
intro = "This is a dummy module!!"

def print_func(name):
   print("Hello : ", name)
   return

The import Statement

  • This module defines a global variable intro and a function _printfunc
  • To use this module in a program, you need to import the module
In [5]:
import mymodule
In [6]:
mymodule.intro
Out[6]:
'This is a dummy module!!'
In [7]:
mymodule.print_func("Sachin")
Hello :  Sachin

The from...import Statement

  • Import specific attributes from a module into the current namespace
  • from fib import fibonacci
In [8]:
from mymodule import print_func
print_func("Sachin")
Hello :  Sachin
In [9]:
from mymodule import intro
print(intro)
This is a dummy module!!

The from...import * Statement

  • Imports all names from a module into the current namespace
  • from modname import *
In [11]:
from mymodule import *
print(intro)
print_func("Sachin")
This is a dummy module!!
Hello :  Sachin

Abbreviating the module

  • You can also abbreviate the module name by adding as to the import
In [12]:
import mymodule as my
my.intro
Out[12]:
'This is a dummy module!!'

NumPy

  • NumPy is the fundamental package for scientific computing with Python.
  • It contains among other things
    • a powerful N-dimensional array object
    • sophisticated (broadcasting) functions
    • tools for integrating C/C++ and Fortran code
    • useful linear algebra, Fourier transform, and random number capabilities
  • NumPy can also be used as an efficient multi-dimensional container of generic data.
  • Numpy arrays are a great alternative to Python Lists
  • NumPy’s main object is the homogeneous multidimensional array.
  • NumPy’s array class is called ndarray. It is also known by the alias array
  • The more important attributes of an ndarray object are:
    • ndarray.ndim: the number of axes (dimensions) of the array.
    • ndarray.shape: the dimensions of the array.
    • ndarray.size: the total number of elements of the array.
    • ndarray.dtype: an object describing the type of the elements in the array.
    • ndarray.itemsize: the size in bytes of each element of the array.
    • ndarray.data: the buffer containing the actual elements of the array.
  • To use Numpy, you need to import the numpy module
    • convention: import as np and then use the dot notation
In [13]:
import numpy as np

Numpy Arrays

  • create an array from a regular Python list or tuple using the array function
In [14]:
a = np.array([2,3,4])
print(a, a.dtype)
[2 3 4] int32
  • array transforms sequences of sequences into two-dimensional arrays, sequences of sequences of sequences into three-dimensional arrays
In [15]:
b = np.array([(1.2, 3.5, 5.1),(4.1,6.1,0.5)])
print(b, b.dtype)
[[1.2 3.5 5.1]
 [4.1 6.1 0.5]] float64
In [16]:
b[0]
Out[16]:
array([1.2, 3.5, 5.1])
In [17]:
b[1]
Out[17]:
array([4.1, 6.1, 0.5])
In [18]:
b[0][0]
Out[18]:
1.2
  • The type of the array can also be explicitly specified at creation time
In [19]:
c = np.array( [ [1,2], [3,4] ], dtype=complex )
c
Out[19]:
array([[1.+0.j, 2.+0.j],
       [3.+0.j, 4.+0.j]])
  • The function zeros creates an array full of zeros,
  • the function ones creates an array full of ones, and
  • the function empty creates an array whose initial content is random and depends on the state of the memory.
In [20]:
print('Zeros: ',np.zeros( (3,4) ))
print('Ones', np.ones( (2,4), dtype=np.float64 ))
print('Empty', np.empty( (2,3) ))
Zeros:  [[0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]]
Ones [[1. 1. 1. 1.]
 [1. 1. 1. 1.]]
Empty [[1.2 3.5 5.1]
 [4.1 6.1 0.5]]
  • The reshape function can be used to convert an array into a matrix
In [21]:
a = np.arange(15).reshape(3, 5)
a
Out[21]:
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
In [22]:
print("array dimensions: ", a.shape)
print("number of dimensions: ", a.ndim)
print("element types: ", a.dtype.name)
print("size of elements: ", a.itemsize)
print("total number of elements: ",a.size)
print("type of object:",type(a))
array dimensions:  (3, 5)
number of dimensions:  2
element types:  int32
size of elements:  4
total number of elements:  15
type of object: <class 'numpy.ndarray'>

Matplotlib

  • Most popular python plotting library
  • low-level library with a Matlab like interface
  • offers lots of freedom
  • need to write more code

Installing Matplotlib

  • python -m pip install -U pip
  • pip install matplotlib
  • conda install matplotlib

Pyplot

  • matplotlib.pyplot is a collection of command style functions that make matplotlib work like MATLAB
  • creates a figure, creates a plotting area in a figure, plots some lines in a plotting area, decorates the plot with labels, etc
  • supports a very wide variety of graphs and plots namely - histogram, bar charts, power spectra, error charts etc

Importing Matplotlib

  • import matplotlib.pyplot as plt
  • from matplotlib import pyplot as plt
In [23]:
import matplotlib.pyplot as plt
In [24]:
from matplotlib import pyplot as plt

Plotting a Line Chart

  • Line chart/Line graph displays information as a series of data points called 'markers'
  • 'Markers' are connected by staright line segments
  • Use the plot method - plt.plot(x, y)
In [84]:
import matplotlib.pyplot as plt

val = [1, 2, 3, 4, 5]
sq = [1, 4, 9, 16, 25]
cu = [1, 8, 27, 64, 125]

plt.plot(val, sq, label = 'Square Values', linewidth = 2, linestyle = '--')
plt.plot(val, cu, label = 'Cube Values', linewidth = 4)

plt.xlabel('Values')
plt.ylabel('Square and Cube')
plt.title('Simple Graph')
plt.legend()
plt.show()

Plotting a Bar Graph

  • Bar chart/Bar graph presents categorical data with rectangular bars with heights
  • Heights or lengths are proportional to the value they represent
  • Can be plotted vertically or horizontally
  • Bar graphs are good if you want to present the data of different groups that are being compared to each other
  • matplotlib.pyplot.bar(x, height, width = 0.8, align = 'center')
In [64]:
import matplotlib.pyplot as plt

boys = ['John', 'Ric', 'Tim', 'Tom', 'Brat']
height = [7, 6.5, 5.7, 5.10, 6.1]

girls = ['Beth', 'Rose', 'Jill', 'Becky', 'Tina', 'Lizz']
ht_g = [5, 5.5, 6.3, 5.11, 6, 5.7]

plt.bar(boys, height, width = 0.5)
plt.bar(girls, ht_g, color = 'c', width = 0.5)

plt.xlabel('Boys & Girls')
plt.ylabel('Height')

plt.title('Height Distribution')

plt.legend(['Boys', 'Girls'])
plt.show()

Plotting a Histogram

  • Accurate graphical representation of distribution of numerical data
  • Estimate of probabilty distribution of continous variable
  • Kind of a bar graph
  • Represent the data given in form of some groups

Constructing a Histogram

  • "bin" the range of values - divide the entire range of values into a series of intervals
  • count how many values fall into each interval
  • X- axis represent bin ranges
  • Y-axis talk about frequency
In [65]:
from matplotlib import pyplot as py

population_ages = [5, 6, 7, 8, 8, 9, 10, 15, 12, 16, 19, 14, 11, 15, 22, 25, 28, 29, 45, 41, 44, 32, 36, 39, 38, 55, 56, 50, 51, 54, 57, 55, 61, 64, 65, 61, 69, 66, 70, 71, 74, 74, 78, 79]

bins = [0, 20, 40, 60, 80]

plt.hist(population_ages, bins, histtype='bar', rwidth=0.8)

plt.xlabel('Age')
plt.ylabel('No. of People')
plt.title('Histogram showing number of people within a specific age group')
plt.legend(['Population Density'])

plt.show()

Plotting a Scatter Plot

  • Used to represnt the correaltion between two or more variables
  • Helps to identify outliers if any
  • Outlier is a data point that differs significantly from other observations
  • matplotlib.pyplot.scatter(x, y)
In [66]:
from matplotlib import pyplot as py

countries = ['USA', 'India', 'England', 'Australia', 'China']
pop = [20, 60, 25, 30, 70]

plt.scatter(countries, pop, s = 150, color = 'k', marker = '*')
plt.xlabel('Countries')
plt.ylabel('Pop Size')
plt.legend(['Size'])
plt.show();

Plotting a Stack Plot

  • Idea is to show "parts to the whole" over time
  • basically like a pie-chart, only over time
  • generated by plotting different datasets vertically on top of one another rather than overlapping
  • matplotlib.pyplot.stackplot(x, *args, colors=None)
In [69]:
from matplotlib import pyplot as plt

days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']

sleeping = [7, 6, 5, 5, 8]
eating =   [4, 3, 4, 2, 3]
working =  [8, 7, 8, 7, 6]
playing =  [5, 8, 7, 10, 7]

plt.stackplot(days, sleeping, eating, working, playing, 
              colors = ['r', 'b', 'c', 'm'], 
              labels = ['Sleeping', 'Eating', 'Working', 'Playing'])

plt.legend()
plt.title('My Weekly Routine')
plt.xlabel('Days')
plt.ylabel('Activities')
plt.show()

Plotting a Pie Chart

  • A circular statistical graphic divided into slices to illustrate numerical proportion
  • The arc length of each slice (central angle and area) ~ to the quantity is represents
  • Good to show proportional data of different categories
  • Figures are usually in percentages
In [71]:
from matplotlib import pyplot as py

days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']

sleeping = [7, 6, 5, 5, 8]
eating =   [4, 3, 4, 2, 3]
working =  [8, 7, 8, 7, 6]
playing =  [5, 8, 7, 10, 7]

friday = [8, 3, 6, 7]
activities = ['sleeping', 'eating', 'working', 'playing']

plt.pie(friday, labels = activities, 
        colors = ['r', 'b', 'c', 'm'], 
        startangle = 90, 
        shadow = True,
        explode = (0.1, 0, 0, 0), # pulls out the specific slice of pie
        autopct = '%1.1f%%') # adds % to the pie

plt.title("Friday's Routine", color = 'red')
plt.show()

Loading data from file using Numpy

In [26]:
from matplotlib import pyplot as py
import numpy as np

col1, col2 = np.loadtxt('C:/Users/saj415/Documents/example.txt', delimiter = ',', unpack = True)
plt.plot(col1, col2, label = 'Loaded from Text File!')
plt.legend()
plt.xlabel('Col1')
plt.ylabel('Col2')
plt.title('Loading Data from Text File')
plt.show()

Basic Customization and Rotating Labels

In [2]:
from matplotlib import pyplot as plt
import numpy as np

fig = plt.figure();
ax1 = plt.subplot2grid((1, 1), (0, 0)) # (1, 1) -> shape of grid, (0, 0) -> starting point

names = np.array(['Tony Stark', 'Bruce Banner', 'Peter Parker', 'Doctor Strange', 'Steve Rogers', 'Bucky Barnes'])
rating = np.array([98, 95, 90, 88, 94, 92])

ax1.plot(names, rating)

plt.xlabel('Avenger')
plt.ylabel('Rating')
plt.title('Avengers Rating')
plt.show()

Rotate the Labels

In [3]:
from matplotlib import pyplot as plt
import numpy as np

fig = plt.figure();
ax1 = plt.subplot2grid((1, 1), (0, 0))

names = np.array(['Tony Stark', 'Bruce Banner', 'Peter Parker', 'Doctor Strange', 'Steve Rogers', 'Bucky Barnes'])
rating = np.array([98, 95, 90, 88, 94, 92])

ax1.plot(names, rating)

#rotate the labels
for label in ax1.xaxis.get_ticklabels():
    label.set_rotation(45)

plt.xlabel('Avenger')
plt.ylabel('Rating')
plt.title('Avengers Rating')
plt.subplots_adjust(left = 0.09, bottom = 0.20, right = 0.94, top = 0.95, wspace = 0.2, hspace = 0) #wspace & hspace -> padding b/w plots
plt.show()

Add grid to the plot

In [4]:
from matplotlib import pyplot as plt
import numpy as np

fig = plt.figure();
ax1 = plt.subplot2grid((1, 1), (0, 0))

names = np.array(['Tony Stark', 'Bruce Banner', 'Peter Parker', 'Doctor Strange', 'Steve Rogers', 'Bucky Barnes'])
rating = np.array([98, 95, 90, 88, 94, 92])

ax1.plot(names, rating)

# rotate the labels
for label in ax1.xaxis.get_ticklabels():
    label.set_rotation(45)

# add grid to the plot
ax1.grid(True, color = 'r', linestyle = '-', linewidth = 0.5)      
    
plt.xlabel('Avenger')
plt.ylabel('Rating')
plt.title('Avengers Rating')
plt.subplots_adjust(left = 0.09, bottom = 0.20, right = 0.94, top = 0.95, wspace = 0.2, hspace = 0)
plt.show()

More customization and Fills

In [11]:
from matplotlib import pyplot as plt
import numpy as np

fig = plt.figure();
ax1 = plt.subplot2grid((1, 1), (0, 0))

names = np.array(['Tony Stark', 'Bruce Banner', 'Peter Parker', 'Doctor Strange', 'Steve Rogers', 'Bucky Barnes'])
rating = np.array([98, 95, 90, 88, 94, 92])

ax1.plot(names, rating)

# fills
ax1.fill_between(names, rating, 92, where = (rating >= rating[5]), facecolor = 'g', alpha = 0.3)
ax1.fill_between(names, rating, 92, where = (rating < rating[5]), facecolor = 'r', alpha = 0.3)

# rotate the labels
for label in ax1.xaxis.get_ticklabels():
    label.set_rotation(45)

# add grid to the plot
ax1.grid(True, color = 'r', linestyle = '-', linewidth = 0.5)

# more customization
ax1.xaxis.label.set_color('r')
ax1.yaxis.label.set_color('b')
ax1.set_yticks([88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100])
    
plt.xlabel('Avenger')
plt.ylabel('Rating')
plt.title('Avengers Rating')
plt.subplots_adjust(left = 0.09, bottom = 0.20, right = 0.94, top = 0.95, wspace = 0.2, hspace = 0)
plt.show()

Style, Adding a style to graph, customizing style, creating a new style

  • Cascading style sheets with HTML
  • a sheet where you can specify the style you want, what kind of modifications to the graph you want to make
  • load that style into your graph and apply the changes
In [74]:
from matplotlib import style
style.use('fivethirtyeight')
print(plt.style.available)
print(plt.__file__)

ax1 = plt.subplot2grid((1, 1), (0, 0))

no = [1, 2, 3, 4, 5, 6]
sq = [1, 4, 9, 16, 25, 36]
cu = [1, 8, 27, 64, 125, 216]
mu2 = [2, 4, 6, 8, 10, 12]
mu10 = [10, 20, 30, 40, 50, 60]

ax1.xaxis.label.set_color('r')
ax1.yaxis.label.set_color('b')

plt.plot(no, sq, label = 'Square')
plt.plot(no, cu, label = 'Cube')
plt.plot(no, mu2, label = 'Multiple of 2')
plt.plot(no, mu10, label = 'Multiple of 10')

plt.xlabel('Number')
plt.ylabel('Square, Cube, 2X, 10X')
plt.legend()
plt.title('Adding Style to Graph')
plt.show()
['bmh', 'classic', 'dark_background', 'fast', 'fivethirtyeight', 'ggplot', 'grayscale', 'seaborn-bright', 'seaborn-colorblind', 'seaborn-dark-palette', 'seaborn-dark', 'seaborn-darkgrid', 'seaborn-deep', 'seaborn-muted', 'seaborn-notebook', 'seaborn-paper', 'seaborn-pastel', 'seaborn-poster', 'seaborn-talk', 'seaborn-ticks', 'seaborn-white', 'seaborn-whitegrid', 'seaborn', 'Solarize_Light2', 'tableau-colorblind10', '_classic_test']
C:\Users\saj415\AppData\Local\Continuum\anaconda3\lib\site-packages\matplotlib\pyplot.py

Plotting a Live Graph

  • Graphs that can update their plots live as the data-sources updates
  • Used for graphing live stock pricing data, sensor connected to the computer
  • matplotlib.animation allows us to animate the figure after it has been shown
In [75]:
from matplotlib import animation as animat
from matplotlib import style

style.use('fivethirtyeight')
fig = plt.figure();
ax1 = fig.add_subplot(1, 1, 1) # 1*1 and plot no. 1

def animate(i):
    xs, ys = np.loadtxt('C:/Users/saj415/Documents/example.txt', delimiter = ',', unpack = True)
    ax1.clear()
    ax1.plot(xs, ys)

ani = animat.FuncAnimation(fig, animate, interval = 1000) #1000 ms -> every sec. update
plt.show()

Subplots with matplotlib

  • matplotlib.subplot() function can be called to plot two or more plots in one figure
  • helpful to compare different views of data side by side
  • these subplots might be insets, grids of plots or other complicated layouts
In [12]:
import random
from matplotlib import pyplot as plt

fig = plt.figure()

def create_plots():
    xs = []
    ys = []
    
    for i in range(10):
        x = i
        y = random.randrange(10)
        
        xs.append(x)
        ys.append(y)
    return xs, ys


# add_subplot syntax:
ax1 = fig.add_subplot(221)
ax2 = fig.add_subplot(222)
ax3 = fig.add_subplot(212)


x, y = create_plots()
ax1.plot(x, y)

x, y = create_plots()
ax2.plot(x, y)

x, y = create_plots()
ax3.plot(x, y)

plt.show()

Subplot2grid

In [47]:
import random
from matplotlib import pyplot as plt
from matplotlib import style
import matplotlib.ticker as mticker

style.use('fivethirtyeight')
fig = plt.figure()

def create_plots():
    xs = []
    ys = []
    
    for i in range(10):
        x = i
        y = random.randrange(10)
        
        xs.append(x)
        ys.append(y)
    return xs, ys


ax1 = plt.subplot2grid((6, 1), (0, 0), rowspan = 1, colspan = 1)
plt.title('SubPlots', color = 'c')
plt.ylabel('Plot 1')
ax2 = plt.subplot2grid((6, 1), (1, 0), rowspan = 4, colspan = 1, sharex = ax1)
plt.ylabel('Plot 2', color = 'b')
ax3 = plt.subplot2grid((6, 1), (5, 0), rowspan = 1, colspan = 1, sharex = ax1)
plt.xlabel('X', color = 'm')
plt.ylabel('Plot 3')

# add_subplot syntax:
# ax1 = fig.add_subplot(221)
# ax2 = fig.add_subplot(222)
# ax3 = fig.add_subplot(212)


x, y = create_plots()
ax1.plot(x, y, color = 'r', label = 'Plot 1')
ax1.yaxis.set_major_locator(mticker.MaxNLocator(nbins = 3,  prune = 'lower'))

x, y = create_plots()
ax2.plot(x, y, color = 'b', label = 'Plot 2')

x, y = create_plots()
ax3.plot(x, y, color = 'c', label = 'Plot 3')

plt.setp(ax1.get_xticklabels(), visible = False)
plt.setp(ax2.get_xticklabels(), visible = False)

ax1.legend()
leg = ax1.legend(loc = 9, ncol = 2, prop = {'size': 11})
leg.get_frame().set_alpha(0.4)

ax2.legend()
leg = ax2.legend(loc = 9, ncol = 2, prop = {'size': 11})
leg.get_frame().set_alpha(0.4)

ax3.legend()
leg = ax3.legend(loc = 9, ncol = 1, prop = {'size': 11})
leg.get_frame().set_alpha(0.4)

plt.show()

3D Plots in Python

  • 2D plot can only show the relationships between a single pair of axes x-y
  • a 3D plot on the other hand allows us to explore relationships of 3 pairs of axes: x-y, x-z, and y-z
  • 3D plotting in Matplotlib starts by enabling the utility toolkit
  • enable this toolkit by importing the mplot3d library
  • 3D plots can be created by passing the keyword projection="3d" to any of the regular axes creation functions in Matplotlib
In [51]:
from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt

fig = plt.figure()
ax1 = fig.add_subplot(111, projection = '3d')

x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y = [2, 1, 4, 5, 7, 8, 9, 3, 1, 5]
z = [1, 2, 6, 3, 2, 7, 3, 3, 7, 2]

ax1.plot(x, y, z)

ax1.set_xlabel('X Axis')
ax1.set_ylabel('Y Axis')
ax1.set_zlabel('Z Axis')

plt.show()

Plotting a 3D Scatter Plot

In [57]:
from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt

fig = plt.figure()
ax1 = fig.add_subplot(111, projection = '3d')

x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y = [2, 1, 4, 5, 7, 8, 9, 3, 1, 5]
z = [1, 2, 6, 3, 2, 7, 3, 3, 7, 2]

# ax1.plot(x, y, z)

x1 = [-1, -2, -3, -4, -5, -6, -7, -8, -9, -10]
y1 = [-2, -1, -4, -5, -7, -8, -9, -3, -1, -5]
z1 = [-1, -2, -6, -3, -2, -7, -3, -3, -7, -2]

ax1.scatter(x1, y1, z1, marker = 'v')
ax1.scatter(x, y, z, marker = '*')

ax1.set_xlabel('X Axis')
ax1.set_ylabel('Y Axis')
ax1.set_zlabel('Z Axis')

plt.show()

Plotting 3d Bar charts

In [60]:
from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure()
ax1 = fig.add_subplot(111, projection = '3d')

x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y = [2, 1, 4, 5, 7, 8, 9, 3, 1, 5]
z = [1, 2, 6, 3, 2, 7, 3, 3, 7, 2]

# ax1.plot(x, y, z)

x1 = [-1, -2, -3, -4, -5, -6, -7, -8, -9, -10]
y1 = [-2, -1, -4, -5, -7, -8, -9, -3, -1, -5]
z1 = [-1, -2, -6, -3, -2, -7, -3, -3, -7, -2]

# ax1.scatter(x1, y1, z1, marker = 'v')
# ax1.scatter(x, y, z, marker = '*')

x3 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y3 = [2, 1, 4, 5, 7, 8, 9, 3, 1, 5]
z3 = np.zeros(10) # do not want bars floating in air, z axis is the one that goes up

dx = np.ones(10) # how far back is the x gonna go
dy = np.ones(10)
dz = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

ax1.bar3d(x3, y3, z3, dx, dy, dz)

ax1.set_xlabel('X Axis')
ax1.set_ylabel('Y Axis')
ax1.set_zlabel('Z Axis')

plt.show()

Further Reading: Python Books

  • Think Python 2e - Allen B. Downey
  • Automate the Boring Stuff with Python - Al Sweigart
  • Python for Data Analysis: Data Wrangling with Pandas, NumPy, and IPython - Wes McKinney
  • Think Stats - Allen B. Downey
  • Think Bayes: Bayesian Statistics in Python - Allen B. Downey
  • Python Data Science Handbook - Jake VanderPlas