diff --git a/Source/Plugins/LfpDisplayNodeAlpha/LfpDisplayCanvas.cpp b/Source/Plugins/LfpDisplayNodeAlpha/LfpDisplayCanvas.cpp
index f02b5662e193b1f8bcc56262d071d7f71ade5d6b..2251ed00ba28dc71e80cf74964d10b32b3805907 100644
--- a/Source/Plugins/LfpDisplayNodeAlpha/LfpDisplayCanvas.cpp
+++ b/Source/Plugins/LfpDisplayNodeAlpha/LfpDisplayCanvas.cpp
@@ -808,6 +808,8 @@ LfpDisplayOptions::LfpDisplayOptions(LfpDisplayCanvas* canvas_, LfpTimescale* ti
     channelZoomSliderLabel->setColour(Label::textColourId, labelColour);
     addAndMakeVisible(channelZoomSliderLabel);
     
+    
+    
     // init channel display skipping options
     channelDisplaySkipOptions.add("All");
     channelDisplaySkipOptions.add("2");
@@ -831,24 +833,45 @@ LfpDisplayOptions::LfpDisplayOptions(LfpDisplayCanvas* canvas_, LfpTimescale* ti
     channelDisplaySkipLabel->setColour(Label::textColourId, labelColour);
     addAndMakeVisible(channelDisplaySkipLabel);
     
+    
+    
     // init stream rate displaying options
-    streamRateDisplayedOptions.add("High");
-    streamRateDisplayedOptions.add("Low");
-    selectedStreamRateDisplayed = 1;
-    selectedChannelDisplaySkipValue = streamRateDisplayedOptions[selectedStreamRateDisplayed - 1];
-    
-    streamRateDisplayedSelection = new ComboBox("Displayed Stream Rate");
-    streamRateDisplayedSelection->addItemList(streamRateDisplayedOptions, 1);
-    streamRateDisplayedSelection->setSelectedId(selectedStreamRateDisplayed, sendNotification);
-    streamRateDisplayedSelection->setEditableText(false);
-    streamRateDisplayedSelection->addListener(this);
-    addAndMakeVisible(streamRateDisplayedSelection);
-    
-    streamRateDisplayedLabel = new Label("Displayed Stream Rate Label", "Display Stream Rate");
-    streamRateDisplayedLabel->setFont(labelFont);
-    streamRateDisplayedLabel->setColour(Label::textColourId, labelColour);
-    addAndMakeVisible(streamRateDisplayedLabel);
+//    streamRateDisplayedOptions.add("High");
+//    streamRateDisplayedOptions.add("Low");
+//    selectedStreamRateDisplayed = 1;
+//    selectedChannelDisplaySkipValue = streamRateDisplayedOptions[selectedStreamRateDisplayed - 1];
+//    
+//    streamRateDisplayedSelection = new ComboBox("Displayed Stream Rate");
+//    streamRateDisplayedSelection->addItemList(streamRateDisplayedOptions, 1);
+//    streamRateDisplayedSelection->setSelectedId(selectedStreamRateDisplayed, sendNotification);
+//    streamRateDisplayedSelection->setEditableText(false);
+//    streamRateDisplayedSelection->addListener(this);
+//    addAndMakeVisible(streamRateDisplayedSelection);
+//    
+//    streamRateDisplayedLabel = new Label("Displayed Stream Rate Label", "Display Stream Rate");
+//    streamRateDisplayedLabel->setFont(labelFont);
+//    streamRateDisplayedLabel->setColour(Label::textColourId, labelColour);
+//    addAndMakeVisible(streamRateDisplayedLabel);
+    
+    
+    
+    // init median offset plotting
+    medianOffsetPlottingLabel = new Label("Median Offset Correction", "Median Offset Correction");
+    medianOffsetPlottingLabel->setFont(labelFont);
+    medianOffsetPlottingLabel->setColour(Label::textColourId, labelColour);
+    addAndMakeVisible(medianOffsetPlottingLabel);
+    
+    medianOffsetPlottingButton = new UtilityButton("0", labelFont);
+    medianOffsetPlottingButton->setRadius(5.0f);
+    medianOffsetPlottingButton->setEnabledState(true);
+    medianOffsetPlottingButton->setCorners(true, true, true, true);
+    medianOffsetPlottingButton->addListener(this);
+    medianOffsetPlottingButton->setClickingTogglesState(true);
+    medianOffsetPlottingButton->setToggleState(false, sendNotification);
+    addAndMakeVisible(medianOffsetPlottingButton);
 
+    
+    
     // init show/hide options button
     showHideOptionsButton = new ShowHideOptionsButton(this);
     showHideOptionsButton->addListener(this);
@@ -1107,7 +1130,7 @@ void LfpDisplayOptions::resized()
                                             20);
     reverseChannelsDisplayLabel->setBounds(reverseChannelsDisplayButton->getRight(),
                                            reverseChannelsDisplayButton->getY(),
-                                           180,
+                                           120,
                                            22);
     
     // Channel Display Skip Selector
@@ -1121,14 +1144,25 @@ void LfpDisplayOptions::resized()
                                        22);
     
     // Stream Rate Displayed Selector
-    streamRateDisplayedSelection->setBounds(reverseChannelsDisplayButton->getX() + 130,
-                                            channelDisplaySkipSelection->getY(),
-                                            60,
-                                            25);
-    streamRateDisplayedLabel->setBounds(streamRateDisplayedSelection->getX() - 5,
-                                        reverseChannelsDisplayButton->getY(),
-                                        150,
-                                        22);
+//    streamRateDisplayedSelection->setBounds(reverseChannelsDisplayButton->getX() + 130,
+//                                            channelDisplaySkipSelection->getY(),
+//                                            60,
+//                                            25);
+//    streamRateDisplayedLabel->setBounds(streamRateDisplayedSelection->getX() - 5,
+//                                        reverseChannelsDisplayButton->getY(),
+//                                        150,
+//                                        22);
+    
+    // Median Offset Plotting Button
+    medianOffsetPlottingButton->setBounds(reverseChannelsDisplayLabel->getRight() + 5,
+                                          reverseChannelsDisplayButton->getY(),
+                                          20,
+                                          20);
+    medianOffsetPlottingLabel->setBounds(medianOffsetPlottingButton->getRight(),
+                                         medianOffsetPlottingButton->getY(),
+                                         150,
+                                         22);
+    
     
     // Saturation Warning Selection
     saturationWarningSelection->setBounds(250, getHeight()-90, 60, 25);
@@ -1264,9 +1298,15 @@ void LfpDisplayOptions::buttonClicked(Button* b)
         lfpDisplay->setChannelsReversed(b->getToggleState());
         return;
     }
+    if (b == medianOffsetPlottingButton)
+    {
+        lfpDisplay->setMedianOffsetPlotting(b->getToggleState());
+        return;
+    }
     if (b == drawMethodButton)
     {
         lfpDisplay->setDrawMethod(b->getToggleState()); // this should be done the same way as drawClipWarning - or the other way around.
+        
         return;
     }
     if (b == drawClipWarningButton)
@@ -1318,132 +1358,6 @@ void LfpDisplayOptions::comboBoxChanged(ComboBox* cb)
     {
         const int skipAmt = pow(2, cb->getSelectedId() - 1);
         lfpDisplay->setChannelDisplaySkipAmount(skipAmt);
-//        const int skipAmt = pow(2, cb->getSelectedId() - 2);
-//        
-//        if (skipAmt != 0) lfpDisplay->removeAllChildren(); // if show all
-//        
-////        Array<LfpChannelDisplay*> channels;
-////        Array<LfpChannelDisplayInfo*> channelInfo;
-//        
-//        Array<LfpDisplay::LfpChannel> &drawableChannels = lfpDisplay->drawableChannels;
-//        drawableChannels = Array<LfpDisplay::LfpChannel>();
-//        
-//        Array<LfpDisplay::LfpChannel> channelsToDraw;
-//        
-//        // iterate over all channels and select drawable ones
-//        for (size_t i = 0; i < lfpDisplay->channels.size(); i++)
-//        {
-//            if (skipAmt == 0) // no skips, add all channels
-//            {
-//                lfpDisplay->channels[i]->setHidden(false);
-//                lfpDisplay->channelInfo[i]->setHidden(false);
-//                
-//                channelsToDraw.add(LfpDisplay::LfpChannel{
-//                    lfpDisplay->channels[i],
-//                    lfpDisplay->channelInfo[i]
-//                });
-//                
-//                lfpDisplay->addAndMakeVisible(lfpDisplay->channels[i]);
-//                lfpDisplay->addAndMakeVisible(lfpDisplay->channelInfo[i]);
-//            }
-//            else // skip some channels
-//            {
-//                if (i % (skipAmt + 1) == 0) // add these channels
-//                {
-//                    lfpDisplay->channels[i]->setHidden(false);
-//                    lfpDisplay->channelInfo[i]->setHidden(false);
-//                    
-//                    channelsToDraw.add(LfpDisplay::LfpChannel{
-//                        lfpDisplay->channels[i],
-//                        lfpDisplay->channelInfo[i]
-//                    });
-//                    
-//                    lfpDisplay->addAndMakeVisible(lfpDisplay->channels[i]);
-//                    lfpDisplay->addAndMakeVisible(lfpDisplay->channelInfo[i]);
-//                }
-//                else // but not these
-//                {
-//                    lfpDisplay->channels[i]->setHidden(true);
-//                    lfpDisplay->channelInfo[i]->setHidden(true);
-//                    
-//                    lfpDisplay->removeChildComponent(lfpDisplay->channels[i]);
-//                    lfpDisplay->removeChildComponent(lfpDisplay->channelInfo[i]);
-//                }
-//            }
-//        }
-//        
-//        // check if channels should be added to drawableChannels in reverse
-//        if (lfpDisplay->getChannelsReversed())
-//        {
-//            for (int i = channelsToDraw.size() - 1; i >= 0; --i)
-//            {
-//                drawableChannels.add(channelsToDraw[i]);
-//            }
-//        }
-//        else
-//        {
-//            for (int i = 0; i < channelsToDraw.size(); ++i)
-//            {
-//                drawableChannels.add(channelsToDraw[i]);
-//            }
-//        }
-//        
-////        if (lfpDisplay->getChannelsReversed())
-////        {
-////            for (int i = lfpDisplay->getNumChannels() - 1; i >= 0; --i)
-////            {
-//////                channels.add(lfpDisplay->channels[i]);
-//////                channelInfo.add(lfpDisplay->channelInfo[i]);
-////                drawableChannels.add(LfpDisplay::LfpChannel{lfpDisplay->channels[i], lfpDisplay->channelInfo[i]});
-////            }
-////            std::cout << "Size of drawableChannels array: " << drawableChannels.size() << std::endl;
-////        }
-////        else
-////        {
-//////            channel.addArray(lfpDisplay->channels);
-//////            channelInfo.addArray(lfpDisplay->channelInfo);
-////            for (size_t i = 0; i < lfpDisplay->getNumChannels(); ++i)
-////            {
-////                drawableChannels.add(LfpDisplay::LfpChannel{lfpDisplay->channels[i], lfpDisplay->channelInfo[i]});
-////            }
-////        }
-////        
-//////        int numVisible = 0;
-////        for (size_t i = 0; i < lfpDisplay->channels.size(); i++)
-////        {
-////            if (skipAmt == 0)
-////            {
-////                channels[i]->setHidden(false);
-////                channelInfo[i]->setHidden(false);
-////                
-////                lfpDisplay->addAndMakeVisible(channels[i]);
-////                lfpDisplay->addAndMakeVisible(channelInfo[i]);
-////                ++numVisible;
-////            }
-////            else
-////            {
-////                bool shouldBeVisible = (i % (skipAmt + 1) == 0);
-////                
-////                channels[i]->setHidden(!shouldBeVisible);
-////                channelInfo[i]->setHidden(!shouldBeVisible);
-////                
-////                if (shouldBeVisible)
-////                {
-////                    lfpDisplay->addAndMakeVisible(channels[i]);
-////                    lfpDisplay->addAndMakeVisible(channelInfo[i]);
-////                    ++numVisible;
-////                }
-//////                else
-//////                {
-//////                    lfpDisplay->removeChildComponent(lfpDisplay->channels[i]);
-//////                    lfpDisplay->removeChildComponent(lfpDisplay->channelInfo[i]);
-//////                }
-////            }
-////        }
-//        
-//        
-////        canvas->resized();
-//        canvas->resizeToChannels();
     }
     else if (cb == timebaseSelection)
     {
@@ -1926,6 +1840,12 @@ LfpDisplay::LfpDisplay(LfpDisplayCanvas* c, Viewport* v)
     , channelsReversed(false)
     , displaySkipAmt(0)
 {
+    perPixelPlotter = new PerPixelBitmapPlotter(this);
+//    histogramPlotter = new HistogramBitmapPlotter(this);
+    
+    plotter = perPixelPlotter;
+    m_MedianOffsetPlottingFlag = false;
+    
     totalHeight = 0;
     colorGrouping=1;
 
@@ -2311,6 +2231,16 @@ void LfpDisplay::setDrawMethod(bool isDrawMethod)
     {
         channels[i]->setDrawMethod(isDrawMethod);
     }
+    
+    if (isDrawMethod)
+    {
+//        plotter = histogramPlotter;
+    }
+    else
+    {
+        plotter = perPixelPlotter;
+    }
+    
     resized();
 
 }
@@ -2411,6 +2341,16 @@ void LfpDisplay::setChannelDisplaySkipAmount(int skipAmt)
         rebuildDrawableChannelsList();
 }
 
+bool LfpDisplay::getMedianOffsetPlotting()
+{
+    return m_MedianOffsetPlottingFlag;
+}
+
+void LfpDisplay::setMedianOffsetPlotting(bool isEnabled)
+{
+    m_MedianOffsetPlottingFlag = isEnabled;
+}
+
 void LfpDisplay::mouseWheelMove(const MouseEvent&  e, const MouseWheelDetails&   wheel)
 {
 
@@ -2658,6 +2598,11 @@ void LfpDisplay::rebuildDrawableChannelsList()
     canvas->resizeToChannels();
 }
 
+LfpBitmapPlotter * const LfpDisplay::getPlotterPtr() const
+{
+    return plotter;
+}
+
 bool LfpDisplay::getSingleChannelState()
 {
     //if (singleChan < 0) return false;
@@ -2907,6 +2852,10 @@ void LfpChannelDisplay::pxPaint()
         fullredraw = false;
     }
     
+    bool drawWithOffsetCorrection = display->getMedianOffsetPlotting();
+    
+    LfpBitmapPlotterInfo plotterInfo; // hold and pass plotting info for each plotting method class
+    
     
     for (int i = ifrom; i < ito ; i += stepSize) // redraw only changed portion
     {
@@ -2967,6 +2916,14 @@ void LfpChannelDisplay::pxPaint()
             double a = (canvas->getYCoordMax(chan, i)/range*channelHeightFloat);
             double b = (canvas->getYCoordMin(chan, i)/range*channelHeightFloat);
             
+            double mean = (canvas->getMean(chan)/range*channelHeightFloat);
+            
+            if (drawWithOffsetCorrection)
+            {
+                a -= mean;
+                b -= mean;
+            }
+            
             double a_raw = canvas->getYCoordMax(chan, i);
             double b_raw = canvas->getYCoordMin(chan, i);
             double from_raw=0; double to_raw=0;
@@ -3086,29 +3043,38 @@ void LfpChannelDisplay::pxPaint()
             else //drawmethod
             { // simple per-pixel min-max drawing, has no anti-aliasing, but runs faster
                 
-                int jfrom=from+getY();
-                int jto=to+getY();
-                
-                //if (yofs<0) {yofs=0;};
-                
-                if (i<0) {i=0;};
-                if (i >= display->lfpChannelBitmap.getWidth()) {i = display->lfpChannelBitmap.getWidth()-1;}; // this shouldnt happen, there must be some bug above - to replicate, run at max refresh rate where draws overlap the right margin by a lot
+                plotterInfo.channelID = chan;
+                plotterInfo.y = getY();
+                plotterInfo.from = from;
+                plotterInfo.to = to;
+                plotterInfo.samp = i;
+                plotterInfo.lineColour = lineColour;
                 
-                if (jfrom<0) {jfrom=0;};
-                if (jto >= display->lfpChannelBitmap.getHeight()) {jto=display->lfpChannelBitmap.getHeight()-1;};
+                // TODO: (kelly) complete transition toward plotter class encapsulation
+                 display->getPlotterPtr()->plot(bdLfpChannelBitmap, plotterInfo); // plotterInfo is prepared above
                 
-                
-                for (int j = jfrom; j <= jto; j += 1)
-                {
-                    
-                    //uint8* const pu8Pixel = bdSharedLfpDisplay.getPixelPointer(	(int)(i),(int)(j));
-                    //*(pu8Pixel)		= 200;
-                    //*(pu8Pixel+1)	= 200;
-                    //*(pu8Pixel+2)	= 200;
-                    
-                    bdLfpChannelBitmap.setPixelColour(i,j,lineColour);
-                    
-                }
+//                int jfrom=from+getY();
+//                int jto=to+getY();
+//                
+//                //if (yofs<0) {yofs=0;};
+//                
+//                if (i<0) {i=0;};
+//                if (i >= display->lfpChannelBitmap.getWidth()) {i = display->lfpChannelBitmap.getWidth()-1;}; // this shouldnt happen, there must be some bug above - to replicate, run at max refresh rate where draws overlap the right margin by a lot
+//                
+//                if (jfrom<0) {jfrom=0;};
+//                if (jto >= display->lfpChannelBitmap.getHeight()) {jto=display->lfpChannelBitmap.getHeight()-1;};
+//                
+//                for (int j = jfrom; j <= jto; j += 1)
+//                {
+//                    
+//                    //uint8* const pu8Pixel = bdSharedLfpDisplay.getPixelPointer(	(int)(i),(int)(j));
+//                    //*(pu8Pixel)		= 200;
+//                    //*(pu8Pixel+1)	= 200;
+//                    //*(pu8Pixel+2)	= 200;
+//                    
+//                    bdLfpChannelBitmap.setPixelColour(i, j, lineColour);
+//                    
+//                }
                 
             }
             
@@ -3584,3 +3550,36 @@ void LfpViewport::visibleAreaChanged(const Rectangle<int>& newVisibleArea)
     canvas->fullredraw = true;
     canvas->refresh();
 }
+
+#pragma mark - PerPixelBitmapPlotter -
+
+PerPixelBitmapPlotter::PerPixelBitmapPlotter(LfpDisplay * lfpDisplay)
+    : LfpBitmapPlotter(lfpDisplay)
+{ }
+
+void PerPixelBitmapPlotter::plot(Image::BitmapData &bitmapData, LfpBitmapPlotterInfo &plotterInfo)
+{
+    int jfrom = plotterInfo.from + plotterInfo.y;
+    int jto = plotterInfo.to + plotterInfo.y;
+    
+    //if (yofs<0) {yofs=0;};
+    
+    if (plotterInfo.samp < 0) {plotterInfo.samp = 0;};
+    if (plotterInfo.samp >= display->lfpChannelBitmap.getWidth()) {plotterInfo.samp = display->lfpChannelBitmap.getWidth()-1;}; // this shouldnt happen, there must be some bug above - to replicate, run at max refresh rate where draws overlap the right margin by a lot
+    
+    if (jfrom<0) {jfrom=0;};
+    if (jto >= display->lfpChannelBitmap.getHeight()) {jto=display->lfpChannelBitmap.getHeight()-1;};
+    
+    
+    for (int j = jfrom; j <= jto; j += 1)
+    {
+        
+        //uint8* const pu8Pixel = bdSharedLfpDisplay.getPixelPointer(	(int)(i),(int)(j));
+        //*(pu8Pixel)		= 200;
+        //*(pu8Pixel+1)	= 200;
+        //*(pu8Pixel+2)	= 200;
+        
+        bitmapData.setPixelColour(plotterInfo.samp,j,plotterInfo.lineColour);
+        
+    }
+}
diff --git a/Source/Plugins/LfpDisplayNodeAlpha/LfpDisplayCanvas.h b/Source/Plugins/LfpDisplayNodeAlpha/LfpDisplayCanvas.h
index 29bee0f037be3d1b36c955c3c0e8b17855e36302..da3627e65fc4f03ff52c9d7da5a1667728502fbe 100644
--- a/Source/Plugins/LfpDisplayNodeAlpha/LfpDisplayCanvas.h
+++ b/Source/Plugins/LfpDisplayNodeAlpha/LfpDisplayCanvas.h
@@ -45,6 +45,8 @@ class LfpChannelDisplayInfo;
 class EventDisplayInterface;
 class LfpViewport;
 class LfpDisplayOptions;
+class LfpBitmapPlotter;
+class PerPixelBitmapPlotter;
 
 #pragma mark - LfpDisplayCanvas -
 //==============================================================================
@@ -337,6 +339,10 @@ private:
     ScopedPointer<ComboBox> streamRateDisplayedSelection;
     StringArray streamRateDisplayedOptions;
     
+    // label and toggle button for the median offset plotting feature
+    ScopedPointer<Label> medianOffsetPlottingLabel;
+    ScopedPointer<UtilityButton> medianOffsetPlottingButton;
+    
     ScopedPointer<Slider> brightnessSliderA;
     ScopedPointer<Slider> brightnessSliderB;
     
@@ -472,6 +478,12 @@ public:
 
     void setEnabledState(bool state, int chan, bool updateSavedChans = true);
     bool getEnabledState(int);
+    
+    /** Returns true if the median offset is enabled for plotting, else false */
+    bool getMedianOffsetPlotting();
+    
+    /** Sets the state for the median offset plotting function */
+    void setMedianOffsetPlotting(bool isEnabled);
 
     /** Returns true if a single channel is focused in viewport */
     bool getSingleChannelState();
@@ -492,6 +504,9 @@ public:
     
     /** Reconstructs the list of drawableChannels based on ordering and filterning parameters */
     void rebuildDrawableChannelsList();
+    
+    /** Returns a const pointer to the internally managed plotter method class */
+    LfpBitmapPlotter * const getPlotterPtr() const;
 
     Colour backgroundColour;
     
@@ -547,11 +562,17 @@ private:
     int colorGrouping;
     
     bool channelsReversed;
+    bool m_MedianOffsetPlottingFlag;
 
     LfpDisplayCanvas* canvas;
     Viewport* viewport;
 
     float range[3];
+    
+    LfpBitmapPlotter * plotter;
+    
+    ScopedPointer<PerPixelBitmapPlotter> perPixelPlotter;
+    //    ScopedPointer<HistogramBitmapPlotter> histogramPlotter;
 
 
 };
@@ -766,6 +787,58 @@ public:
 private:
     LfpDisplayCanvas* canvas;
 };
+
+#pragma mark - LfpBitmapPlotterInfo -
+//==============================================================================
+/**
+    Information struct for plotting method encapsulation classes.
+ */
+struct LfpBitmapPlotterInfo
+{
+    int channelID;
+    int samp;
+    int to;
+    int from;
+    int x;
+    int y;
+    Colour lineColour;
+};
+
+#pragma mark - LfpBitmapPlotter -
+//==============================================================================
+/**
+    Interface class for different plotting methods.
+ */
+class LfpBitmapPlotter
+{
+public:
+    LfpBitmapPlotter(LfpDisplay * lfpDisplay)
+        : display(lfpDisplay)
+    {}
+    virtual ~LfpBitmapPlotter() {}
+    
+    /** Plots one subsample of data from a single channel to the bitmap provided */
+    virtual void plot(Image::BitmapData &bitmapData, LfpBitmapPlotterInfo &plotterInfo) = 0;
+    
+protected:
+    LfpDisplay * display;
+};
+
+#pragma mark - PerPixelBitmapPlotter -
+//==============================================================================
+/**
+    Abstraction of the per-pixel plotting method.
+ */
+class PerPixelBitmapPlotter : public LfpBitmapPlotter
+{
+public:
+    PerPixelBitmapPlotter(LfpDisplay * lfpDisplay);
+    virtual ~PerPixelBitmapPlotter() {}
+    
+    /** Plots one subsample of data from a single channel to the bitmap provided */
+    virtual void plot(Image::BitmapData &bitmapData, LfpBitmapPlotterInfo &plotterInfo) override;
+};
+    
 };
 
 #endif  // __LFPDISPLAYCANVAS_H_Alpha__