diff --git a/modules/gfx/pymod/CMakeLists.txt b/modules/gfx/pymod/CMakeLists.txt
index 253e8e59989fe3961f893cc435779c846256f0b9..210cce509623565695582e20969f818e8f2e042d 100644
--- a/modules/gfx/pymod/CMakeLists.txt
+++ b/modules/gfx/pymod/CMakeLists.txt
@@ -11,6 +11,7 @@ set(OST_GFX_PYMOD_SOURCES
   export_scene_observer.cc
   export_render_options.cc
   export_color.cc
+  export_gradient.cc
   export_color_ops.cc
   export_glwin_base.cc
 )
diff --git a/modules/gfx/pymod/export_gradient.cc b/modules/gfx/pymod/export_gradient.cc
new file mode 100644
index 0000000000000000000000000000000000000000..e24cc9cee5fec611fc536b8c0ab5a4e95c3712a1
--- /dev/null
+++ b/modules/gfx/pymod/export_gradient.cc
@@ -0,0 +1,86 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2011 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+#include <boost/python.hpp>
+#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
+using namespace boost::python;
+
+#include <ost/message.hh>
+#include <ost/gfx/gradient.hh>
+using namespace ost;
+using namespace ost::gfx;
+
+namespace {
+  Gradient* make_gradient(const dict& d)
+  {
+    std::auto_ptr<Gradient> grad(new Gradient);
+    list keys = d.keys();
+    for(int i=0;i<len(keys);++i) {
+      extract<float> fex(keys[i]);
+      if(!fex.check()) {
+        throw std::runtime_error("expected floats as keys");
+      }
+      float mark = fex();
+      Color col;
+      object val = d[keys[i]];
+      extract<Color> cex(val);
+      if(cex.check()) {
+        // use gfx.Color
+        col=cex();
+      } else {
+        // try simple sequence
+        if(len(val)!=3) {
+          throw std::runtime_error("expected values of gfx.Color or float triplets");
+        }
+        try {
+          col=gfx::Color(extract<float>(val[0]),extract<float>(val[1]),extract<float>(val[2]));
+        } catch (...) {
+          throw std::runtime_error("expected values of gfx.Color or float triplets");
+        }
+      }
+      grad->SetColorAt(mark,col);
+    }
+    return grad.release();
+  }
+}
+
+void export_gradient()
+{
+  class_<Gradient>("Gradient", init<>())
+    .def(init<const String&>())
+    .def("__init__", make_constructor(make_gradient))
+    .def("SetColorAt", &Gradient::SetColorAt)
+    .def("GetColorAt", &Gradient::GetColorAt)
+    .def("GetStops", &Gradient::GetStops)
+    .def("GradientToInfo", &Gradient::GradientToInfo)
+    .def("GradientFromInfo", &Gradient::GradientFromInfo).staticmethod("GradientFromInfo")
+  ;
+  implicitly_convertible<String, Gradient>();
+
+  class_<Gradient::StopList>("GradientStopList", init<>())
+    .def(vector_indexing_suite<Gradient::StopList>())
+  ;
+
+  class_<Gradient::Stop>("GradientStop", init<>())
+    .def("GetColor", &Gradient::Stop::GetColor)
+    .add_property("color", &Gradient::Stop::GetColor)
+    .def("GetRel", &Gradient::Stop::GetRel)
+    .add_property("rel", &Gradient::Stop::GetRel)
+  ;
+
+}
diff --git a/modules/gfx/pymod/wrap_gfx.cc b/modules/gfx/pymod/wrap_gfx.cc
index c77b5bc5ce5646080367d8d49105f6666deda768..0198d3a0fb27ae5869ff572b9335e6580737b8e9 100644
--- a/modules/gfx/pymod/wrap_gfx.cc
+++ b/modules/gfx/pymod/wrap_gfx.cc
@@ -25,7 +25,6 @@ using namespace boost::python;
 #endif
 #include <ost/info/info.hh>
 #include <ost/gfx/prim_list.hh>
-#include <ost/gfx/gradient.hh>
 #include <ost/gfx/gfx_test_object.hh>
 #include <boost/python/suite/indexing/vector_indexing_suite.hpp>
 
@@ -37,6 +36,7 @@ extern void export_Surface();
 extern void export_primlist();
 extern void export_primitives();
 extern void export_color();
+extern void export_gradient();
 #if OST_IMG_ENABLED
   extern void export_Map();
 #endif
@@ -54,7 +54,6 @@ using namespace ost::gfx;
 
 BOOST_PYTHON_MODULE(_ost_gfx)
 {
-  export_color();
   export_Scene();
   export_GfxNode();
   export_GfxObj();
@@ -68,6 +67,10 @@ BOOST_PYTHON_MODULE(_ost_gfx)
   export_SceneObserver();
   export_ColorOps();
   export_GLWinBase();
+  export_primitives();
+  export_primlist();
+  export_color();
+  export_gradient();
 
   enum_<RenderMode::Type>("RenderMode")
     .value("SIMPLE",RenderMode::SIMPLE)
@@ -122,25 +125,6 @@ BOOST_PYTHON_MODULE(_ost_gfx)
 
   class_<GfxTestObj, bases<GfxObj>, boost::noncopyable>("GfxTestObj", init<>());
   
-  class_<Gradient>("Gradient", init<>())
-    .def(init<const String&>())
-    .def("SetColorAt", &Gradient::SetColorAt)
-    .def("GetColorAt", &Gradient::GetColorAt)
-    .def("GetStops", &Gradient::GetStops)
-    .def("GradientToInfo", &Gradient::GradientToInfo)
-    .def("GradientFromInfo", &Gradient::GradientFromInfo).staticmethod("GradientFromInfo")
-  ;
-  implicitly_convertible<String, Gradient>();
-
-  class_<StopList>("StopList", init<>())
-    .def(vector_indexing_suite<StopList>())
-  ;
-
-  class_<Stop>("Stop", init<>())
-	.def("GetColor", &Stop::GetColor)
-	.def("GetRel", &Stop::GetRel)
-  ;
-
 #if OST_SHADER_SUPPORT_ENABLED
   class_<Shader, boost::noncopyable>("Shader", no_init)
     .def("Instance",&Shader::Instance,
@@ -151,8 +135,6 @@ BOOST_PYTHON_MODULE(_ost_gfx)
     ;
 #endif
 
-  export_primitives();
-  export_primlist();
 }
 
 
diff --git a/modules/gfx/src/gradient.cc b/modules/gfx/src/gradient.cc
index b2cca70fed271194366f8cc4f3795e1beb0f2bea..3414135afb8cb605ba0a3874d3a91af0748f1e89 100644
--- a/modules/gfx/src/gradient.cc
+++ b/modules/gfx/src/gradient.cc
@@ -76,22 +76,24 @@ Color Gradient::GetColorAt(float t) const
   return stops_[c-1].color*(1.0-tt)+stops_[c].color*tt;
 }
 
-void Gradient::GradientToInfo(info::InfoGroup& group) const{
+void Gradient::GradientToInfo(info::InfoGroup& group) const
+{
   std::ostringstream ss;
 
   ss << stops_.size() << "\n";
 
-  for( std::vector<Stop>::size_type i = 0; i < stops_.size(); i++ ) {
+  for( StopList::size_type i = 0; i < stops_.size(); i++ ) {
     ss << stops_[i].t << "\t" << stops_[i].color.Red() << "\t" << stops_[i].color.Green() << "\t" << stops_[i].color.Blue() << "\t" << stops_[i].color.Alpha() << "\n";
   }
   group.SetTextData(ss.str());
 }
 
-StopList Gradient::GetStops() const{
+Gradient::StopList Gradient::GetStops() const{
 	return stops_;
 }
 
-gfx::Gradient Gradient::GradientFromInfo(const info::InfoGroup& group){
+Gradient Gradient::GradientFromInfo(const info::InfoGroup& group)
+{
   std::istringstream ss(group.GetTextData());
   Gradient grad;
 
@@ -106,4 +108,5 @@ gfx::Gradient Gradient::GradientFromInfo(const info::InfoGroup& group){
 
   return grad;
 }
+
 }}
diff --git a/modules/gfx/src/gradient.hh b/modules/gfx/src/gradient.hh
index bd142489cde82ebf581d386ccd57b28b313551af..0b220faf060cc656cf9a52dbd3bccee98f2d8821 100644
--- a/modules/gfx/src/gradient.hh
+++ b/modules/gfx/src/gradient.hh
@@ -33,33 +33,6 @@
 
 namespace ost { namespace gfx {
 
-
-struct Stop {
-   Stop(): t(0.0) {}
-
-   Stop(float tt, const Color& c): t(tt), color(c) {}
-   float t;
-   Color color;
-
-   Color GetColor(){
-	   return color;
-   }
-
-   float GetRel(){
-	   return t;
-   }
-
-   bool operator==(const Stop& ref) const
-   {
-     return t==ref.t && color==ref.color;
-   }
-
- };
-
-
-typedef std::vector<Stop> StopList;
-
-
 /// \brief color gradient
 /// 
 /// Gradients map a scalar value in the range of 0 to 1 to a color. The 
@@ -68,10 +41,39 @@ typedef std::vector<Stop> StopList;
 /// 
 /// \sa \ref gradient.py "Gradient Example"
 class DLLEXPORT_OST_GFX Gradient {
-
 public:
+  struct Stop {
+    Stop(): t(0.0) {}
+    
+    Stop(float tt, const Color& c): t(tt), color(c) {}
+    float t;
+    Color color;
+    
+    Color GetColor(){
+      return color;
+    }
+    
+    float GetRel(){
+      return t;
+    }
+    
+    bool operator==(const Stop& ref) const
+    {
+      return t==ref.t && color==ref.color;
+    }
+    
+  };
+  
+  typedef std::vector<Stop> StopList;
+  
+public:
+  /*!
+    In python, the gradient can also be initialize with a dictionary, mapping
+    stops to either float triplets or gfx.Color objects
+  */
   Gradient();
 
+  /// \brief initialize with a pre-define gradient name
   Gradient(const String& name);
 
   /// \brief get color
diff --git a/modules/gfx/tests/CMakeLists.txt b/modules/gfx/tests/CMakeLists.txt
index adf0a676991f2bbb7d31c06e8a95c6cf4b8a6683..b5bb03b71e8eb2dbf90fc8886f1cf34157e52670 100644
--- a/modules/gfx/tests/CMakeLists.txt
+++ b/modules/gfx/tests/CMakeLists.txt
@@ -1,8 +1,7 @@
 set(OST_GFX_UNIT_TESTS
   tests.cc
   test_gfx_node.cc
-  test_primlist.py
-  test_color.py
+  test_gfx.py
 )
 if (ENABLE_IMG)
   list(APPEND OST_GFX_UNIT_TESTS test_map_octree.cc)
diff --git a/modules/gfx/tests/test_color.py b/modules/gfx/tests/test_color.py
deleted file mode 100644
index 58a1afa0494cbfe2ece14f5e4811fd8945e56f01..0000000000000000000000000000000000000000
--- a/modules/gfx/tests/test_color.py
+++ /dev/null
@@ -1,35 +0,0 @@
-import unittest
-if __name__== '__main__':
-  import sys
-  sys.path.insert(0,"../../../stage/lib64/openstructure/")
-
-import ost
-#import ost.gfx
-#import ost.geom
-
-class TestColor(unittest.TestCase):
-  def setUp(self):
-    pass
-
-  def test_(self):
-    c=ost.gfx.Color(0.5,0.3,0.2)
-    self.assertAlmostEqual(c.r,0.5)
-    self.assertAlmostEqual(c.g,0.3)
-    self.assertAlmostEqual(c.b,0.2)
-    self.assertAlmostEqual(c.a,1.0)
-    self.assertAlmostEqual(c.red,0.5)
-    self.assertAlmostEqual(c.green,0.3)
-    self.assertAlmostEqual(c.blue,0.2)
-    self.assertAlmostEqual(c.alpha,1.0)
-    self.assertAlmostEqual(c[0],0.5)
-    self.assertAlmostEqual(c[1],0.3)
-    self.assertAlmostEqual(c[2],0.2)
-    self.assertAlmostEqual(c[3],1.0)
-    c.r=0.9
-    self.assertAlmostEqual(c.r,0.9)
-    self.assertAlmostEqual(c.red,0.9)
-    self.assertAlmostEqual(c[0],0.9)
-
-if __name__== '__main__':
-  unittest.main()
-
diff --git a/modules/gfx/tests/test_gfx.py b/modules/gfx/tests/test_gfx.py
new file mode 100644
index 0000000000000000000000000000000000000000..ff0d32d9ad7415c01f54b92683dffa6bad17ad41
--- /dev/null
+++ b/modules/gfx/tests/test_gfx.py
@@ -0,0 +1,63 @@
+import unittest
+if __name__== '__main__':
+  import sys
+  sys.path.insert(0,"../../../stage/lib64/openstructure/")
+
+import ost
+import ost.gfx as gfx
+import ost.geom as geom
+
+def col_delta(c1,c2):
+  return geom.Distance(geom.Vec3(c1[0],c1[1],c1[2]),geom.Vec3(c2[0],c2[1],c2[2]))
+
+class TestGfx(unittest.TestCase):
+  def runTest(self):
+    self.test_gradient()
+    self.test_color()
+    self.test_primlist()
+
+  def test_gradient(self):
+    gs=[gfx.Gradient(),
+        gfx.Gradient({0.0: [1,0,0], 1.0: gfx.Color(0,1,0)})]
+    gs[0].SetColorAt(0.0,gfx.Color(1.0,0.0,0.0))
+    gs[0].SetColorAt(1.0,gfx.Color(0.0,1.0,0.0))
+    for g in gs:
+      self.assertAlmostEqual(col_delta(g.GetColorAt(0.0),gfx.Color(1.0,0,0)),0.0)
+      self.assertAlmostEqual(col_delta(g.GetColorAt(0.5),gfx.Color(0.5,0.5,0)),0.0)
+      self.assertAlmostEqual(col_delta(g.GetColorAt(1.0),gfx.Color(0,1.0,0)),0.0)
+
+  def test_color(self):
+    c=gfx.Color(0.5,0.3,0.2)
+    self.assertAlmostEqual(c.r,0.5)
+    self.assertAlmostEqual(c.g,0.3)
+    self.assertAlmostEqual(c.b,0.2)
+    self.assertAlmostEqual(c.a,1.0)
+    self.assertAlmostEqual(c.red,0.5)
+    self.assertAlmostEqual(c.green,0.3)
+    self.assertAlmostEqual(c.blue,0.2)
+    self.assertAlmostEqual(c.alpha,1.0)
+    self.assertAlmostEqual(c[0],0.5)
+    self.assertAlmostEqual(c[1],0.3)
+    self.assertAlmostEqual(c[2],0.2)
+    self.assertAlmostEqual(c[3],1.0)
+    c.r=0.9
+    self.assertAlmostEqual(c.r,0.9)
+    self.assertAlmostEqual(c.red,0.9)
+    self.assertAlmostEqual(c[0],0.9)
+
+  def test_primlist(self):
+    pl=gfx.PrimList("foo")
+    pl.AddPoint([0,0,0])
+    pl.AddPoint(geom.Vec3(1,2,3),color=gfx.RED)
+    pl.AddLine([0,0,0],[1,2,3])
+    pl.AddLine(geom.Vec3(0,0,0),geom.Vec3(1,2,3),color=gfx.BLUE)
+    pl.AddSphere([0,0,0],radius=2.0)
+    pl.AddSphere(geom.Vec3(1,2,3),color=gfx.RED,radius=3.0)
+    pl.AddCyl([0,0,0],[1,2,3],radius=0.5,color=gfx.YELLOW)
+    pl.AddCyl(geom.Vec3(0,0,0),geom.Vec3(1,2,3),radius1=0.5,radius2=0.1,color1=gfx.BLUE,color2=gfx.GREEN)
+    pl.AddText("foo",[0,2,3])
+    pl.AddText("bar",[-2,0,0],color=gfx.WHITE,point_size=8)
+
+if __name__== '__main__':
+  unittest.main()
+
diff --git a/modules/gfx/tests/test_primlist.py b/modules/gfx/tests/test_primlist.py
deleted file mode 100644
index 55660f9554a958c8fbf1ee09cf8fb5a2e868f462..0000000000000000000000000000000000000000
--- a/modules/gfx/tests/test_primlist.py
+++ /dev/null
@@ -1,29 +0,0 @@
-import unittest
-if __name__== '__main__':
-  import sys
-  sys.path.insert(0,"../../../stage/lib64/openstructure/")
-
-import ost
-import ost.gfx
-import ost.geom
-
-class TestPrimList(unittest.TestCase):
-  def setUp(self):
-    pass
-
-  def test_(self):
-    pl=ost.gfx.PrimList("foo")
-    pl.AddPoint([0,0,0])
-    pl.AddPoint(ost.geom.Vec3(1,2,3),color=ost.gfx.RED)
-    pl.AddLine([0,0,0],[1,2,3])
-    pl.AddLine(ost.geom.Vec3(0,0,0),ost.geom.Vec3(1,2,3),color=ost.gfx.BLUE)
-    pl.AddSphere([0,0,0],radius=2.0)
-    pl.AddSphere(ost.geom.Vec3(1,2,3),color=ost.gfx.RED,radius=3.0)
-    pl.AddCyl([0,0,0],[1,2,3],radius=0.5,color=ost.gfx.YELLOW)
-    pl.AddCyl(ost.geom.Vec3(0,0,0),ost.geom.Vec3(1,2,3),radius1=0.5,radius2=0.1,color1=ost.gfx.BLUE,color2=ost.gfx.GREEN)
-    pl.AddText("foo",[0,2,3])
-    pl.AddText("bar",[-2,0,0],color=gfx.WHITE,point_size=8)
-
-if __name__== '__main__':
-  unittest.main()
-
diff --git a/modules/gui/pymod/scene/gradient_editor_widget.py b/modules/gui/pymod/scene/gradient_editor_widget.py
index 3c5b8629433707548bab7453d7592df57a1e6aab..34c11a24ac0d70b2a2026308365ad8f351a64005 100644
--- a/modules/gui/pymod/scene/gradient_editor_widget.py
+++ b/modules/gui/pymod/scene/gradient_editor_widget.py
@@ -176,7 +176,7 @@ class GradientEdit(QtGui.QWidget):
       QtGui.QMessageBox.question(self, "Information", "Please keep in mind, at least two stops are needed for a gradient!")
 
   def AddStop(self, pos, color=None):
-    stop = GradientStop(pos, self.border_offset_, self, color)
+    stop = MyGradientStop(pos, self.border_offset_, self, color)
     QtCore.QObject.connect(stop, QtCore.SIGNAL("gradientChanged"), self.UpdateGradient)
     QtCore.QObject.connect(stop, QtCore.SIGNAL("colorChanged"), self.UpdateGradient)
     QtCore.QObject.connect(stop, QtCore.SIGNAL("colorChanged"), self.parent().Update)
@@ -231,7 +231,7 @@ class GradientEdit(QtGui.QWidget):
       self.width_ = event.size().width()
     
 #Gradient Stop  
-class GradientStop(ColorSelectWidget):
+class MyGradientStop(ColorSelectWidget):
   def __init__(self, pos, offset, parent, color=None):
     #Defaults
     self.length_ = 20