{"action":"created","comment":{"url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/pulls/comments/172649023","pull_request_review_id":101696689,"id":172649023,"diff_hunk":"@@ -0,0 +1,169 @@\n+# yellowbrick.classifier.class_balance_heat_map\n+# Class balance visualizer for showing per-class support.\n+#\n+# Author:   Rebecca Bilbro <rbilbro@districtdatalabs.com>\n+# Author:   Benjamin Bengfort <bbengfort@districtdatalabs.com>\n+# Author:   Neal Humphrey\n+# Author:   Larry Gray\n+# Created:  Sun March 4 20:45:00 2018 -0400\n+#\n+# Copyright (C) 2017 District Data Labs\n+# For license information, see LICENSE.txt\n+#\n+# ID: class_balance_heat_map.py [5388065] lwgray@gmail.com $\n+\n+\"\"\"\n+Class balance heat map visualizer for showing per-class support.\n+\"\"\"\n+\n+##########################################################################\n+## Imports\n+##########################################################################\n+\n+from matplotlib import cm\n+import matplotlib.pyplot as plt\n+import numpy as np\n+\n+from .base import ClassificationScoreVisualizer\n+\n+from sklearn.model_selection import train_test_split\n+from sklearn.utils.multiclass import unique_labels\n+\n+\n+##########################################################################\n+## Class Balance Heat Map Chart\n+##########################################################################\n+\n+class ClassBalanceHeatMap(ClassificationScoreVisualizer):\n+    \"\"\"\n+    Class balance heat map that shows the support for each class in the\n+    fitted classification model displayed as a stacked bar.  Each bar is\n+    segmented to show the distribution of predicted classes for each\n+    class. It is initialized with a fitted model and generates a\n+    class balance heat map chart on draw.\n+\n+    Parameters\n+    ----------\n+    ax: axes\n+        the axis to plot the figure on.\n+    model: estimator\n+        Scikit-Learn estimator object. Should be an instance of a classifier,\n+        else ``__init__()`` will raise an exception.\n+    classes: list\n+        A list of class names for the legend. If classes is None and a y value\n+        is passed to fit then the classes are selected from the target vector.\n+    kwargs: dict\n+        Keyword arguments passed to the super class. Here, used\n+        to colorize the bars in the histogram.\n+    Notes\n+    -----\n+    These parameters can be influenced later on in the visualization\n+    process, but can and should be set as early as possible.\n+    \"\"\"\n+\n+    def score(self, X, y=None, **kwargs):\n+        \"\"\"\n+        Generates a 2D array where each row is the count of the\n+        predicted classes and each column is the true class\n+\n+        Parameters\n+        ----------\n+        X : ndarray or DataFrame of shape n x m\n+            A matrix of n instances with m features\n+        y : ndarray or Series of length n\n+            An array or series of target or class values\n+\n+        Returns\n+        -------\n+\n+        ax : the axis with the plotted figure\n+        \"\"\"\n+\n+        y_pred = self.predict(X)\n+        self.indices = unique_labels(y, y_pred)\n+        self.classes_ = self.classes_ if self.classes_ is not None else self.indices\n+        self.scores = np.array([","path":"yellowbrick/classifier/class_balance_heat_map.py","position":85,"original_position":85,"commit_id":"e9e72915a11e00203571dfb23b4b0c41049fb260","original_commit_id":"e9e72915a11e00203571dfb23b4b0c41049fb260","user":{"login":"bbengfort","id":745966,"avatar_url":"https://avatars0.githubusercontent.com/u/745966?v=4","gravatar_id":"","url":"https://api.github.com/users/bbengfort","html_url":"https://github.com/bbengfort","followers_url":"https://api.github.com/users/bbengfort/followers","following_url":"https://api.github.com/users/bbengfort/following{/other_user}","gists_url":"https://api.github.com/users/bbengfort/gists{/gist_id}","starred_url":"https://api.github.com/users/bbengfort/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bbengfort/subscriptions","organizations_url":"https://api.github.com/users/bbengfort/orgs","repos_url":"https://api.github.com/users/bbengfort/repos","events_url":"https://api.github.com/users/bbengfort/events{/privacy}","received_events_url":"https://api.github.com/users/bbengfort/received_events","type":"User","site_admin":false},"body":"Following the comment above, I'd say it is valid to store this as `self.scores_` -- many of the `*CV` estimators do something like this, though they compute the scores on fit. I think we can get away with that here. \r\n\r\nThat also reminds me, there are several other visualizers that are not consistent with this behavior and need to be updated. @ndanielsen, @rebeccabilbro  - do you think we should make this an issue to deal with it in the future?","created_at":"2018-03-06T20:27:34Z","updated_at":"2018-03-06T20:35:43Z","html_url":"https://github.com/DistrictDataLabs/yellowbrick/pull/321#discussion_r172649023","pull_request_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/pulls/321","author_association":"OWNER","_links":{"self":{"href":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/pulls/comments/172649023"},"html":{"href":"https://github.com/DistrictDataLabs/yellowbrick/pull/321#discussion_r172649023"},"pull_request":{"href":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/pulls/321"}}},"pull_request":{"url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/pulls/321","id":172900800,"html_url":"https://github.com/DistrictDataLabs/yellowbrick/pull/321","diff_url":"https://github.com/DistrictDataLabs/yellowbrick/pull/321.diff","patch_url":"https://github.com/DistrictDataLabs/yellowbrick/pull/321.patch","issue_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/issues/321","number":321,"state":"open","locked":false,"title":"Class Balance Heat Map Visualizer","user":{"login":"lwgray","id":1000117,"avatar_url":"https://avatars2.githubusercontent.com/u/1000117?v=4","gravatar_id":"","url":"https://api.github.com/users/lwgray","html_url":"https://github.com/lwgray","followers_url":"https://api.github.com/users/lwgray/followers","following_url":"https://api.github.com/users/lwgray/following{/other_user}","gists_url":"https://api.github.com/users/lwgray/gists{/gist_id}","starred_url":"https://api.github.com/users/lwgray/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lwgray/subscriptions","organizations_url":"https://api.github.com/users/lwgray/orgs","repos_url":"https://api.github.com/users/lwgray/repos","events_url":"https://api.github.com/users/lwgray/events{/privacy}","received_events_url":"https://api.github.com/users/lwgray/received_events","type":"User","site_admin":false},"body":"In this PR I've implemented a ClassBalanceHeatMap visualizer based on @bbengfort  prototype code .  I was asked by @rebeccabilbro to take a crack at this implementation.  \r\n\r\nThis visualizer is a heatmap implementation of the class balance visualizer.  It is being added because the heatmap provides a way to quickly understand how good your classifier is at predicting the right classes.\r\n\r\nTake for instance,  the sklearn digits data set (see below) with 10 classes.  The heatmap displays data as a stacked bar chart.  On the X axis are the different classes. The Y axis is a count of how many times your model predicted a certain class.  For example... The second bar shows the total number of instances where a Class 1 prediction was assigned.  Additionally, each bar is color coded  to show the number of predicted class.  In the case of the second bar, it shows three colors with the following counts, Class 1(Purple, 50), Class 8 (Red, 3), Class 9(Grey, 1).  This means that of the total number of \"Class 1\" predictions, 92.5% were actually \"Class 1\", 5.5% were \"Class 8\" and 2% were \"Class 9\"\r\n\r\n![heatmap](https://user-images.githubusercontent.com/1000117/36981588-8e540cec-205b-11e8-8219-c5f6b94ff5ca.png)\r\n\r\n### HELP\r\n\r\n#### Major Issue\r\nIf I build the visualizer in a python notebook as seen [here](https://github.com/lwgray/ddl/blob/master/yellowbrick/heatmap.ipynb) it works.  \r\n\r\nHowever, if I write the visualizer into yellowbrick/classifier/class_balance_heat_map.py (in this pull request) I receive a RuntimeError: Invalid DISPLAY variable.  I can provide the traceback if required.\r\n\r\n#### To Do\r\n\r\n- [ ] Correct RuntimeError\r\n- [ ] Fix axis labels\r\n- [ ] Fix axis ticks\r\n- [ ] Draw box around legend\r\n- [ ] Get rid of grid lines in Figure\r\n- [ ] Test\r\n- [ ] Documentation \r\n\r\n\r\n\r\n","created_at":"2018-03-05T15:34:08Z","updated_at":"2018-03-06T20:35:43Z","closed_at":null,"merged_at":null,"merge_commit_sha":"8a848697192672ffe100053f8bcbea26b6df5ae5","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":545742505,"url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/labels/review","name":"review","color":"eeeeee","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/pulls/321/commits","review_comments_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/pulls/321/comments","review_comment_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/pulls/comments{/number}","comments_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/issues/321/comments","statuses_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/statuses/e9e72915a11e00203571dfb23b4b0c41049fb260","head":{"label":"lwgray:develop","ref":"develop","sha":"e9e72915a11e00203571dfb23b4b0c41049fb260","user":{"login":"lwgray","id":1000117,"avatar_url":"https://avatars2.githubusercontent.com/u/1000117?v=4","gravatar_id":"","url":"https://api.github.com/users/lwgray","html_url":"https://github.com/lwgray","followers_url":"https://api.github.com/users/lwgray/followers","following_url":"https://api.github.com/users/lwgray/following{/other_user}","gists_url":"https://api.github.com/users/lwgray/gists{/gist_id}","starred_url":"https://api.github.com/users/lwgray/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lwgray/subscriptions","organizations_url":"https://api.github.com/users/lwgray/orgs","repos_url":"https://api.github.com/users/lwgray/repos","events_url":"https://api.github.com/users/lwgray/events{/privacy}","received_events_url":"https://api.github.com/users/lwgray/received_events","type":"User","site_admin":false},"repo":{"id":123778249,"name":"yellowbrick","full_name":"lwgray/yellowbrick","owner":{"login":"lwgray","id":1000117,"avatar_url":"https://avatars2.githubusercontent.com/u/1000117?v=4","gravatar_id":"","url":"https://api.github.com/users/lwgray","html_url":"https://github.com/lwgray","followers_url":"https://api.github.com/users/lwgray/followers","following_url":"https://api.github.com/users/lwgray/following{/other_user}","gists_url":"https://api.github.com/users/lwgray/gists{/gist_id}","starred_url":"https://api.github.com/users/lwgray/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lwgray/subscriptions","organizations_url":"https://api.github.com/users/lwgray/orgs","repos_url":"https://api.github.com/users/lwgray/repos","events_url":"https://api.github.com/users/lwgray/events{/privacy}","received_events_url":"https://api.github.com/users/lwgray/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/lwgray/yellowbrick","description":"Visual analysis and diagnostic tools to facilitate machine learning model selection.","fork":true,"url":"https://api.github.com/repos/lwgray/yellowbrick","forks_url":"https://api.github.com/repos/lwgray/yellowbrick/forks","keys_url":"https://api.github.com/repos/lwgray/yellowbrick/keys{/key_id}","collaborators_url":"https://api.github.com/repos/lwgray/yellowbrick/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/lwgray/yellowbrick/teams","hooks_url":"https://api.github.com/repos/lwgray/yellowbrick/hooks","issue_events_url":"https://api.github.com/repos/lwgray/yellowbrick/issues/events{/number}","events_url":"https://api.github.com/repos/lwgray/yellowbrick/events","assignees_url":"https://api.github.com/repos/lwgray/yellowbrick/assignees{/user}","branches_url":"https://api.github.com/repos/lwgray/yellowbrick/branches{/branch}","tags_url":"https://api.github.com/repos/lwgray/yellowbrick/tags","blobs_url":"https://api.github.com/repos/lwgray/yellowbrick/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/lwgray/yellowbrick/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/lwgray/yellowbrick/git/refs{/sha}","trees_url":"https://api.github.com/repos/lwgray/yellowbrick/git/trees{/sha}","statuses_url":"https://api.github.com/repos/lwgray/yellowbrick/statuses/{sha}","languages_url":"https://api.github.com/repos/lwgray/yellowbrick/languages","stargazers_url":"https://api.github.com/repos/lwgray/yellowbrick/stargazers","contributors_url":"https://api.github.com/repos/lwgray/yellowbrick/contributors","subscribers_url":"https://api.github.com/repos/lwgray/yellowbrick/subscribers","subscription_url":"https://api.github.com/repos/lwgray/yellowbrick/subscription","commits_url":"https://api.github.com/repos/lwgray/yellowbrick/commits{/sha}","git_commits_url":"https://api.github.com/repos/lwgray/yellowbrick/git/commits{/sha}","comments_url":"https://api.github.com/repos/lwgray/yellowbrick/comments{/number}","issue_comment_url":"https://api.github.com/repos/lwgray/yellowbrick/issues/comments{/number}","contents_url":"https://api.github.com/repos/lwgray/yellowbrick/contents/{+path}","compare_url":"https://api.github.com/repos/lwgray/yellowbrick/compare/{base}...{head}","merges_url":"https://api.github.com/repos/lwgray/yellowbrick/merges","archive_url":"https://api.github.com/repos/lwgray/yellowbrick/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/lwgray/yellowbrick/downloads","issues_url":"https://api.github.com/repos/lwgray/yellowbrick/issues{/number}","pulls_url":"https://api.github.com/repos/lwgray/yellowbrick/pulls{/number}","milestones_url":"https://api.github.com/repos/lwgray/yellowbrick/milestones{/number}","notifications_url":"https://api.github.com/repos/lwgray/yellowbrick/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/lwgray/yellowbrick/labels{/name}","releases_url":"https://api.github.com/repos/lwgray/yellowbrick/releases{/id}","deployments_url":"https://api.github.com/repos/lwgray/yellowbrick/deployments","created_at":"2018-03-04T10:31:15Z","updated_at":"2018-03-04T10:31:18Z","pushed_at":"2018-03-05T12:12:20Z","git_url":"git://github.com/lwgray/yellowbrick.git","ssh_url":"git@github.com:lwgray/yellowbrick.git","clone_url":"https://github.com/lwgray/yellowbrick.git","svn_url":"https://github.com/lwgray/yellowbrick","homepage":"http://www.scikit-yb.org/","size":28157,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"forks":0,"open_issues":0,"watchers":0,"default_branch":"develop"}},"base":{"label":"DistrictDataLabs:develop","ref":"develop","sha":"55baffa537093da058e164466cc790d4ab21ef99","user":{"login":"DistrictDataLabs","id":7107115,"avatar_url":"https://avatars2.githubusercontent.com/u/7107115?v=4","gravatar_id":"","url":"https://api.github.com/users/DistrictDataLabs","html_url":"https://github.com/DistrictDataLabs","followers_url":"https://api.github.com/users/DistrictDataLabs/followers","following_url":"https://api.github.com/users/DistrictDataLabs/following{/other_user}","gists_url":"https://api.github.com/users/DistrictDataLabs/gists{/gist_id}","starred_url":"https://api.github.com/users/DistrictDataLabs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DistrictDataLabs/subscriptions","organizations_url":"https://api.github.com/users/DistrictDataLabs/orgs","repos_url":"https://api.github.com/users/DistrictDataLabs/repos","events_url":"https://api.github.com/users/DistrictDataLabs/events{/privacy}","received_events_url":"https://api.github.com/users/DistrictDataLabs/received_events","type":"Organization","site_admin":false},"repo":{"id":59121694,"name":"yellowbrick","full_name":"DistrictDataLabs/yellowbrick","owner":{"login":"DistrictDataLabs","id":7107115,"avatar_url":"https://avatars2.githubusercontent.com/u/7107115?v=4","gravatar_id":"","url":"https://api.github.com/users/DistrictDataLabs","html_url":"https://github.com/DistrictDataLabs","followers_url":"https://api.github.com/users/DistrictDataLabs/followers","following_url":"https://api.github.com/users/DistrictDataLabs/following{/other_user}","gists_url":"https://api.github.com/users/DistrictDataLabs/gists{/gist_id}","starred_url":"https://api.github.com/users/DistrictDataLabs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DistrictDataLabs/subscriptions","organizations_url":"https://api.github.com/users/DistrictDataLabs/orgs","repos_url":"https://api.github.com/users/DistrictDataLabs/repos","events_url":"https://api.github.com/users/DistrictDataLabs/events{/privacy}","received_events_url":"https://api.github.com/users/DistrictDataLabs/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/DistrictDataLabs/yellowbrick","description":"Visual analysis and diagnostic tools to facilitate machine learning model selection.","fork":false,"url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick","forks_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/forks","keys_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/keys{/key_id}","collaborators_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/teams","hooks_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/hooks","issue_events_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/issues/events{/number}","events_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/events","assignees_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/assignees{/user}","branches_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/branches{/branch}","tags_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/tags","blobs_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/git/refs{/sha}","trees_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/git/trees{/sha}","statuses_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/statuses/{sha}","languages_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/languages","stargazers_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/stargazers","contributors_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/contributors","subscribers_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/subscribers","subscription_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/subscription","commits_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/commits{/sha}","git_commits_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/git/commits{/sha}","comments_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/comments{/number}","issue_comment_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/issues/comments{/number}","contents_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/contents/{+path}","compare_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/compare/{base}...{head}","merges_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/merges","archive_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/downloads","issues_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/issues{/number}","pulls_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/pulls{/number}","milestones_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/milestones{/number}","notifications_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/labels{/name}","releases_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/releases{/id}","deployments_url":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/deployments","created_at":"2016-05-18T14:12:17Z","updated_at":"2018-03-05T16:16:28Z","pushed_at":"2018-03-05T16:54:49Z","git_url":"git://github.com/DistrictDataLabs/yellowbrick.git","ssh_url":"git@github.com:DistrictDataLabs/yellowbrick.git","clone_url":"https://github.com/DistrictDataLabs/yellowbrick.git","svn_url":"https://github.com/DistrictDataLabs/yellowbrick","homepage":"http://www.scikit-yb.org/","size":28159,"stargazers_count":574,"watchers_count":574,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":110,"mirror_url":null,"archived":false,"open_issues_count":91,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"forks":110,"open_issues":91,"watchers":574,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/pulls/321"},"html":{"href":"https://github.com/DistrictDataLabs/yellowbrick/pull/321"},"issue":{"href":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/issues/321"},"comments":{"href":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/issues/321/comments"},"review_comments":{"href":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/pulls/321/comments"},"review_comment":{"href":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/pulls/321/commits"},"statuses":{"href":"https://api.github.com/repos/DistrictDataLabs/yellowbrick/statuses/e9e72915a11e00203571dfb23b4b0c41049fb260"}},"author_association":"NONE"}}
{"actor":{"display_login":"bbengfort"}}