{"action":"created","comment":{"url":"https://api.github.com/repos/vispy/vispy/pulls/comments/31879409","id":31879409,"diff_hunk":"@@ -0,0 +1,223 @@\n+# -*- coding: utf-8 -*-\n+# -----------------------------------------------------------------------------\n+# Copyright (c) 2015, Vispy Development Team. All Rights Reserved.\n+# Distributed under the (new) BSD License. See LICENSE.txt for more info.\n+# -----------------------------------------------------------------------------\n+# Author: Siddharth Bhat\n+# -----------------------------------------------------------------------------\n+\n+from . import Visual, TextVisual\n+from .shaders import ModularProgram, Function\n+from ..color import get_colormap\n+\n+import numpy as np\n+\n+VERT_SHADER = \"\"\"\n+attribute vec2 a_position;\n+attribute vec2 a_texcoord;\n+varying vec2 v_texcoord;\n+\n+void main() {\n+    v_texcoord = a_texcoord;\n+    gl_Position = $transform(vec4(a_position, 0, 1));\n+}\n+\"\"\"  # noqa\n+\n+FRAG_SHADER_HORIZONTAL = \"\"\"\n+varying vec2 v_texcoord;\n+\n+void main()\n+{   \n+    vec4 mapped_color = $color_transform(v_texcoord.x);\n+    gl_FragColor = mapped_color;\n+}\n+\"\"\"  # noqa\n+\n+FRAG_SHADER_VERTICAL = \"\"\"\n+varying vec2 v_texcoord;\n+ \n+void main()\n+{      \n+    // we get the texcoords inverted (with respect to the colormap)\n+    // so let's invert it to make sure that the colorbar renders correctly \n+    vec4 mapped_color = $color_transform(1.0 - v_texcoord.y);\n+    gl_FragColor = mapped_color;\n+}\n+\"\"\"  # noqa\n+\n+# TODO:\n+# * assumes horizontal. allow vertical\n+# * draw border around rectangle\n+# * allow border width setting (this will require points in\n+# pixel coordinates, how do I do that?)\n+# * actually obey clim\n+# * write docs for color bar\n+\n+\n+class ColorBarVisual(Visual):\n+    \"\"\"Visual subclass displaying a colorbar\n+\n+    Parameters\n+    ----------\n+\n+    center_pos : tuple (x, y)\n+        Position where the colorbar is to be placed with\n+        respect to the center of the colorbar\n+    halfdim : tuple (half_width, half_height)\n+        Half the dimensions of the colorbar measured\n+        from the center. That way, the total dimensions\n+        of the colorbar is (x - half_width) to (x + half_width)\n+        and (y - half_height) to (y + half_height)\n+    label : string\n+        The label that is to be drawn with the colorbar\n+        that provides information about the colorbar.\n+    cmap : str | ColorMap\n+        either the name of the ColorMap to be used from the standard\n+        set of names (refer to `vispy.color.get_colormap`),\n+        or a custom ColorMap object.\n+\n+        The ColorMap is used to apply a gradient on the colorbar.\n+    clim : tuple (min, max)\n+        the minimum and maximum values of the data that\n+        is given to the colorbar. This is used to draw the scale\n+        on the side of the colorbar.\n+    orientation : {'horizontal', 'vertical'}\n+        the orientation of the colorbar, used for coloring\n+\n+            * 'horizontal': the color is applied from left to right,\n+              with minimum corresponding to left and maximum to right\n+            * 'vertical': the color is applied from bottom to top,\n+              with mimumum corresponding to bottom and maximum to top\n+    \"\"\"\n+\n+    def __init__(self, center_pos, halfdim,\n+                 label,\n+                 cmap,\n+                 clim=(0.0, 1.0),\n+                 orientation=\"horizontal\",\n+                 **kwargs):\n+\n+        super(ColorBarVisual, self).__init__(**kwargs)\n+\n+        self._cmap = get_colormap(cmap)\n+        self._clim = clim\n+\n+        x, y = center_pos\n+        halfw, halfh = halfdim\n+\n+        vertices = np.array([[x - halfw, y - halfh],\n+                            [x + halfw, y - halfh],\n+                            [x + halfw, y + halfh],\n+                             # tri 2\n+                            [x - halfw, y - halfh],\n+                            [x + halfw, y + halfh],\n+                            [x - halfw, y + halfh]],\n+                            dtype=np.float32)\n+\n+        tex_coords = np.array([[0, 0], [1, 0], [1, 1],\n+                              [0, 0], [1, 1], [0, 1]],\n+                              dtype=np.float32)\n+\n+        if orientation == \"horizontal\":\n+            self._program = ModularProgram(VERT_SHADER, FRAG_SHADER_HORIZONTAL)\n+\n+        elif orientation == \"vertical\":\n+            self._program = ModularProgram(VERT_SHADER, FRAG_SHADER_VERTICAL)\n+\n+        else:\n+            raise ValueError(\"orientation must\"\n+                             \" be \\'horizontal\\' or \\'vertical\\'.\"\n+                             \" given: %s\" % orientation)\n+\n+        self._program.frag['color_transform'] = Function(self._cmap.glsl_map)\n+        self._program['a_position'] = vertices.astype(np.float32)\n+        self._program['a_texcoord'] = tex_coords.astype(np.float32)\n+\n+        if orientation == \"horizontal\":\n+            text_x, text_y = x, y + halfh * 1.2\n+            self._label = TextVisual(label, pos=(text_x, text_y),\n+                                     anchor_y=\"top\")\n+\n+            begin_tick_pos = x - halfw, text_y\n+            end_tick_pos = x + halfw, text_y\n+\n+            # TODO, HACK: This should ideally be a single TextVisual\n+            # However, one TextVisual with multiple strings\n+            # does not seem to be working as of now. (See #981)\n+            # https://github.com/vispy/vispy/issues/981\n+            self._ticks = []\n+            self._ticks.append(TextVisual(str(clim[0]),\n+                               pos=begin_tick_pos,\n+                               anchor_y=\"top\"))\n+            self._ticks.append(TextVisual(str(clim[1]),\n+                               pos=end_tick_pos,\n+                               anchor_y=\"top\"))\n+\n+        elif orientation == \"vertical\":","path":"vispy/visuals/colorbar.py","position":156,"original_position":156,"commit_id":"0cfc0c69488e6165c6c83fae8a79cd7223df4986","original_commit_id":"0cfc0c69488e6165c6c83fae8a79cd7223df4986","user":{"login":"Eric89GXL","id":2365790,"avatar_url":"https://avatars.githubusercontent.com/u/2365790?v=3","gravatar_id":"","url":"https://api.github.com/users/Eric89GXL","html_url":"https://github.com/Eric89GXL","followers_url":"https://api.github.com/users/Eric89GXL/followers","following_url":"https://api.github.com/users/Eric89GXL/following{/other_user}","gists_url":"https://api.github.com/users/Eric89GXL/gists{/gist_id}","starred_url":"https://api.github.com/users/Eric89GXL/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Eric89GXL/subscriptions","organizations_url":"https://api.github.com/users/Eric89GXL/orgs","repos_url":"https://api.github.com/users/Eric89GXL/repos","events_url":"https://api.github.com/users/Eric89GXL/events{/privacy}","received_events_url":"https://api.github.com/users/Eric89GXL/received_events","type":"User","site_admin":false},"body":"I think it's okay to have this level of redundancy. But I'd change it to `else:  # orientation == 'vertical':`, that way 1) we save one comparison, 2) it's clear that we know that to be the state at this point, and 3) it's easy to add the next `elif` mode by deleting a few chars.","created_at":"2015-06-07T18:49:35Z","updated_at":"2015-06-07T18:49:35Z","html_url":"https://github.com/vispy/vispy/pull/979#discussion_r31879409","pull_request_url":"https://api.github.com/repos/vispy/vispy/pulls/979","_links":{"self":{"href":"https://api.github.com/repos/vispy/vispy/pulls/comments/31879409"},"html":{"href":"https://github.com/vispy/vispy/pull/979#discussion_r31879409"},"pull_request":{"href":"https://api.github.com/repos/vispy/vispy/pulls/979"}}},"pull_request":{"url":"https://api.github.com/repos/vispy/vispy/pulls/979","id":36962656,"html_url":"https://github.com/vispy/vispy/pull/979","diff_url":"https://github.com/vispy/vispy/pull/979.diff","patch_url":"https://github.com/vispy/vispy/pull/979.patch","issue_url":"https://api.github.com/repos/vispy/vispy/issues/979","number":979,"state":"open","locked":false,"title":"[WIP] ColorBar visual","user":{"login":"bollu","id":1694861,"avatar_url":"https://avatars.githubusercontent.com/u/1694861?v=3","gravatar_id":"","url":"https://api.github.com/users/bollu","html_url":"https://github.com/bollu","followers_url":"https://api.github.com/users/bollu/followers","following_url":"https://api.github.com/users/bollu/following{/other_user}","gists_url":"https://api.github.com/users/bollu/gists{/gist_id}","starred_url":"https://api.github.com/users/bollu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bollu/subscriptions","organizations_url":"https://api.github.com/users/bollu/orgs","repos_url":"https://api.github.com/users/bollu/repos","events_url":"https://api.github.com/users/bollu/events{/privacy}","received_events_url":"https://api.github.com/users/bollu/received_events","type":"User","site_admin":false},"body":"closes #682 \r\n\r\nStarted working on this, learnt a couple of things about vispy's model in the process. I've got the basic structure down.\r\n\r\n- [x] add a ```orientation``` field for ```horizontal``` or ```vertical```\r\n- [x] add a ```label``` field\r\n- [x] ~~add a ```ticks``` field for the colorbar~~\r\n- [ ] add an accompanying node for the SceneGraph\r\n- [ ] draw a customizable border around the colorbar\r\n- [ ] add test cases for the colorbar\r\n- [x] actually respect the ```clim``` parameter (this should be easy, just change the ```texcoords```\r\n- [x] document the example, so that there's proper explanation\r\n- [x] write documentation (docstrings) for the files\r\n- [x] add a license notice for the files\r\n\r\n\r\n***Screenie of colorbar :***\r\n\r\n\r\n![screenshot from 2015-06-04 23 48 12](https://cloud.githubusercontent.com/assets/1694861/7991232/54efccb6-0b14-11e5-9588-ead11449eac4.png)\r\n","created_at":"2015-06-04T18:19:44Z","updated_at":"2015-06-07T18:49:35Z","closed_at":null,"merged_at":null,"merge_commit_sha":"cb5a18766568e510886c9c808f751288adfc4738","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/vispy/vispy/pulls/979/commits","review_comments_url":"https://api.github.com/repos/vispy/vispy/pulls/979/comments","review_comment_url":"https://api.github.com/repos/vispy/vispy/pulls/comments{/number}","comments_url":"https://api.github.com/repos/vispy/vispy/issues/979/comments","statuses_url":"https://api.github.com/repos/vispy/vispy/statuses/0cfc0c69488e6165c6c83fae8a79cd7223df4986","head":{"label":"bollu:colorbar-visual","ref":"colorbar-visual","sha":"0cfc0c69488e6165c6c83fae8a79cd7223df4986","user":{"login":"bollu","id":1694861,"avatar_url":"https://avatars.githubusercontent.com/u/1694861?v=3","gravatar_id":"","url":"https://api.github.com/users/bollu","html_url":"https://github.com/bollu","followers_url":"https://api.github.com/users/bollu/followers","following_url":"https://api.github.com/users/bollu/following{/other_user}","gists_url":"https://api.github.com/users/bollu/gists{/gist_id}","starred_url":"https://api.github.com/users/bollu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bollu/subscriptions","organizations_url":"https://api.github.com/users/bollu/orgs","repos_url":"https://api.github.com/users/bollu/repos","events_url":"https://api.github.com/users/bollu/events{/privacy}","received_events_url":"https://api.github.com/users/bollu/received_events","type":"User","site_admin":false},"repo":{"id":31825193,"name":"vispy","full_name":"bollu/vispy","owner":{"login":"bollu","id":1694861,"avatar_url":"https://avatars.githubusercontent.com/u/1694861?v=3","gravatar_id":"","url":"https://api.github.com/users/bollu","html_url":"https://github.com/bollu","followers_url":"https://api.github.com/users/bollu/followers","following_url":"https://api.github.com/users/bollu/following{/other_user}","gists_url":"https://api.github.com/users/bollu/gists{/gist_id}","starred_url":"https://api.github.com/users/bollu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bollu/subscriptions","organizations_url":"https://api.github.com/users/bollu/orgs","repos_url":"https://api.github.com/users/bollu/repos","events_url":"https://api.github.com/users/bollu/events{/privacy}","received_events_url":"https://api.github.com/users/bollu/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/bollu/vispy","description":"Main repository for Vispy","fork":true,"url":"https://api.github.com/repos/bollu/vispy","forks_url":"https://api.github.com/repos/bollu/vispy/forks","keys_url":"https://api.github.com/repos/bollu/vispy/keys{/key_id}","collaborators_url":"https://api.github.com/repos/bollu/vispy/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/bollu/vispy/teams","hooks_url":"https://api.github.com/repos/bollu/vispy/hooks","issue_events_url":"https://api.github.com/repos/bollu/vispy/issues/events{/number}","events_url":"https://api.github.com/repos/bollu/vispy/events","assignees_url":"https://api.github.com/repos/bollu/vispy/assignees{/user}","branches_url":"https://api.github.com/repos/bollu/vispy/branches{/branch}","tags_url":"https://api.github.com/repos/bollu/vispy/tags","blobs_url":"https://api.github.com/repos/bollu/vispy/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/bollu/vispy/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/bollu/vispy/git/refs{/sha}","trees_url":"https://api.github.com/repos/bollu/vispy/git/trees{/sha}","statuses_url":"https://api.github.com/repos/bollu/vispy/statuses/{sha}","languages_url":"https://api.github.com/repos/bollu/vispy/languages","stargazers_url":"https://api.github.com/repos/bollu/vispy/stargazers","contributors_url":"https://api.github.com/repos/bollu/vispy/contributors","subscribers_url":"https://api.github.com/repos/bollu/vispy/subscribers","subscription_url":"https://api.github.com/repos/bollu/vispy/subscription","commits_url":"https://api.github.com/repos/bollu/vispy/commits{/sha}","git_commits_url":"https://api.github.com/repos/bollu/vispy/git/commits{/sha}","comments_url":"https://api.github.com/repos/bollu/vispy/comments{/number}","issue_comment_url":"https://api.github.com/repos/bollu/vispy/issues/comments{/number}","contents_url":"https://api.github.com/repos/bollu/vispy/contents/{+path}","compare_url":"https://api.github.com/repos/bollu/vispy/compare/{base}...{head}","merges_url":"https://api.github.com/repos/bollu/vispy/merges","archive_url":"https://api.github.com/repos/bollu/vispy/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/bollu/vispy/downloads","issues_url":"https://api.github.com/repos/bollu/vispy/issues{/number}","pulls_url":"https://api.github.com/repos/bollu/vispy/pulls{/number}","milestones_url":"https://api.github.com/repos/bollu/vispy/milestones{/number}","notifications_url":"https://api.github.com/repos/bollu/vispy/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/bollu/vispy/labels{/name}","releases_url":"https://api.github.com/repos/bollu/vispy/releases{/id}","created_at":"2015-03-07T19:53:28Z","updated_at":"2015-03-07T19:53:30Z","pushed_at":"2015-06-07T18:24:33Z","git_url":"git://github.com/bollu/vispy.git","ssh_url":"git@github.com:bollu/vispy.git","clone_url":"https://github.com/bollu/vispy.git","svn_url":"https://github.com/bollu/vispy","homepage":"http://vispy.org","size":8856,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"vispy:master","ref":"master","sha":"bcd2be49c68f37f1aab631c48428b3413908d174","user":{"login":"vispy","id":3934254,"avatar_url":"https://avatars.githubusercontent.com/u/3934254?v=3","gravatar_id":"","url":"https://api.github.com/users/vispy","html_url":"https://github.com/vispy","followers_url":"https://api.github.com/users/vispy/followers","following_url":"https://api.github.com/users/vispy/following{/other_user}","gists_url":"https://api.github.com/users/vispy/gists{/gist_id}","starred_url":"https://api.github.com/users/vispy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vispy/subscriptions","organizations_url":"https://api.github.com/users/vispy/orgs","repos_url":"https://api.github.com/users/vispy/repos","events_url":"https://api.github.com/users/vispy/events{/privacy}","received_events_url":"https://api.github.com/users/vispy/received_events","type":"Organization","site_admin":false},"repo":{"id":8935948,"name":"vispy","full_name":"vispy/vispy","owner":{"login":"vispy","id":3934254,"avatar_url":"https://avatars.githubusercontent.com/u/3934254?v=3","gravatar_id":"","url":"https://api.github.com/users/vispy","html_url":"https://github.com/vispy","followers_url":"https://api.github.com/users/vispy/followers","following_url":"https://api.github.com/users/vispy/following{/other_user}","gists_url":"https://api.github.com/users/vispy/gists{/gist_id}","starred_url":"https://api.github.com/users/vispy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vispy/subscriptions","organizations_url":"https://api.github.com/users/vispy/orgs","repos_url":"https://api.github.com/users/vispy/repos","events_url":"https://api.github.com/users/vispy/events{/privacy}","received_events_url":"https://api.github.com/users/vispy/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/vispy/vispy","description":"Main repository for Vispy","fork":false,"url":"https://api.github.com/repos/vispy/vispy","forks_url":"https://api.github.com/repos/vispy/vispy/forks","keys_url":"https://api.github.com/repos/vispy/vispy/keys{/key_id}","collaborators_url":"https://api.github.com/repos/vispy/vispy/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/vispy/vispy/teams","hooks_url":"https://api.github.com/repos/vispy/vispy/hooks","issue_events_url":"https://api.github.com/repos/vispy/vispy/issues/events{/number}","events_url":"https://api.github.com/repos/vispy/vispy/events","assignees_url":"https://api.github.com/repos/vispy/vispy/assignees{/user}","branches_url":"https://api.github.com/repos/vispy/vispy/branches{/branch}","tags_url":"https://api.github.com/repos/vispy/vispy/tags","blobs_url":"https://api.github.com/repos/vispy/vispy/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/vispy/vispy/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/vispy/vispy/git/refs{/sha}","trees_url":"https://api.github.com/repos/vispy/vispy/git/trees{/sha}","statuses_url":"https://api.github.com/repos/vispy/vispy/statuses/{sha}","languages_url":"https://api.github.com/repos/vispy/vispy/languages","stargazers_url":"https://api.github.com/repos/vispy/vispy/stargazers","contributors_url":"https://api.github.com/repos/vispy/vispy/contributors","subscribers_url":"https://api.github.com/repos/vispy/vispy/subscribers","subscription_url":"https://api.github.com/repos/vispy/vispy/subscription","commits_url":"https://api.github.com/repos/vispy/vispy/commits{/sha}","git_commits_url":"https://api.github.com/repos/vispy/vispy/git/commits{/sha}","comments_url":"https://api.github.com/repos/vispy/vispy/comments{/number}","issue_comment_url":"https://api.github.com/repos/vispy/vispy/issues/comments{/number}","contents_url":"https://api.github.com/repos/vispy/vispy/contents/{+path}","compare_url":"https://api.github.com/repos/vispy/vispy/compare/{base}...{head}","merges_url":"https://api.github.com/repos/vispy/vispy/merges","archive_url":"https://api.github.com/repos/vispy/vispy/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/vispy/vispy/downloads","issues_url":"https://api.github.com/repos/vispy/vispy/issues{/number}","pulls_url":"https://api.github.com/repos/vispy/vispy/pulls{/number}","milestones_url":"https://api.github.com/repos/vispy/vispy/milestones{/number}","notifications_url":"https://api.github.com/repos/vispy/vispy/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/vispy/vispy/labels{/name}","releases_url":"https://api.github.com/repos/vispy/vispy/releases{/id}","created_at":"2013-03-21T18:43:22Z","updated_at":"2015-06-07T00:19:24Z","pushed_at":"2015-06-07T18:45:28Z","git_url":"git://github.com/vispy/vispy.git","ssh_url":"git@github.com:vispy/vispy.git","clone_url":"https://github.com/vispy/vispy.git","svn_url":"https://github.com/vispy/vispy","homepage":"http://vispy.org","size":19330,"stargazers_count":563,"watchers_count":563,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":111,"mirror_url":null,"open_issues_count":149,"forks":111,"open_issues":149,"watchers":563,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/vispy/vispy/pulls/979"},"html":{"href":"https://github.com/vispy/vispy/pull/979"},"issue":{"href":"https://api.github.com/repos/vispy/vispy/issues/979"},"comments":{"href":"https://api.github.com/repos/vispy/vispy/issues/979/comments"},"review_comments":{"href":"https://api.github.com/repos/vispy/vispy/pulls/979/comments"},"review_comment":{"href":"https://api.github.com/repos/vispy/vispy/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/vispy/vispy/pulls/979/commits"},"statuses":{"href":"https://api.github.com/repos/vispy/vispy/statuses/0cfc0c69488e6165c6c83fae8a79cd7223df4986"}}}}