{"action":"created","issue":{"url":"https://api.github.com/repos/statsmodels/statsmodels/issues/2190","labels_url":"https://api.github.com/repos/statsmodels/statsmodels/issues/2190/labels{/name}","comments_url":"https://api.github.com/repos/statsmodels/statsmodels/issues/2190/comments","events_url":"https://api.github.com/repos/statsmodels/statsmodels/issues/2190/events","html_url":"https://github.com/statsmodels/statsmodels/issues/2190","id":54706652,"number":2190,"title":"mosaicplot should handle crosstab and frequency-count DataFrames","user":{"login":"kousu","id":987487,"avatar_url":"https://avatars.githubusercontent.com/u/987487?v=3","gravatar_id":"","url":"https://api.github.com/users/kousu","html_url":"https://github.com/kousu","followers_url":"https://api.github.com/users/kousu/followers","following_url":"https://api.github.com/users/kousu/following{/other_user}","gists_url":"https://api.github.com/users/kousu/gists{/gist_id}","starred_url":"https://api.github.com/users/kousu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kousu/subscriptions","organizations_url":"https://api.github.com/users/kousu/orgs","repos_url":"https://api.github.com/users/kousu/repos","events_url":"https://api.github.com/users/kousu/events{/privacy}","received_events_url":"https://api.github.com/users/kousu/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/statsmodels/statsmodels/labels/comp-graphics","name":"comp-graphics","color":"ededed"},{"url":"https://api.github.com/repos/statsmodels/statsmodels/labels/type-refactor","name":"type-refactor","color":"fbca04"}],"state":"open","locked":false,"assignee":null,"milestone":{"url":"https://api.github.com/repos/statsmodels/statsmodels/milestones/9","labels_url":"https://api.github.com/repos/statsmodels/statsmodels/milestones/9/labels","id":930392,"number":9,"title":"0.8","description":"","creator":{"login":"josef-pkt","id":440735,"avatar_url":"https://avatars.githubusercontent.com/u/440735?v=3","gravatar_id":"","url":"https://api.github.com/users/josef-pkt","html_url":"https://github.com/josef-pkt","followers_url":"https://api.github.com/users/josef-pkt/followers","following_url":"https://api.github.com/users/josef-pkt/following{/other_user}","gists_url":"https://api.github.com/users/josef-pkt/gists{/gist_id}","starred_url":"https://api.github.com/users/josef-pkt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/josef-pkt/subscriptions","organizations_url":"https://api.github.com/users/josef-pkt/orgs","repos_url":"https://api.github.com/users/josef-pkt/repos","events_url":"https://api.github.com/users/josef-pkt/events{/privacy}","received_events_url":"https://api.github.com/users/josef-pkt/received_events","type":"User","site_admin":false},"open_issues":15,"closed_issues":0,"state":"open","created_at":"2015-01-11T13:17:39Z","updated_at":"2015-01-20T16:41:23Z","due_on":null,"closed_at":null},"comments":5,"created_at":"2015-01-18T19:19:18Z","updated_at":"2015-01-20T20:17:39Z","closed_at":null,"body":"I have this dataset, in frequency-count form:\r\n`speeddatting.csv`\r\n```\r\nDecisionM,IntelligentM,freq\r\n0, 5, 9\r\n0, 6, 21\r\n0, 7, 35\r\n0, 8, 35\r\n0, 9, 14\r\n0, 10, 10\r\n1, 5, 11\r\n1, 6, 12\r\n1, 7, 30\r\n1, 8, 48 \r\n1, 9, 27\r\n1, 10, 16\r\n```\r\n\r\nI want to make a mosaic plot of it. This should be easy; the data is already counted for us. For reference, I am looking for this:\r\n![expected output](http://i.imgur.com/SXqbmMr.png)\r\n\r\n\r\nBut this does not work:\r\n``` \r\nimport pandas\r\nimport statsmodels\r\nimport matplotlib.pyplot as plt\r\nfrom statsmodels.graphics.mosaicplot import mosaic\r\n\r\nD = pandas.read_csv(\"speeddating.csv\")\r\nprint(D)\r\n```\r\n\r\n`mosaic()` ignores the `freq` column (I guess I never told it to look there, so fair enough), decides there are equal amounts (i.e. 1) of each case, and I see\r\n![fail#1](http://i.imgur.com/Ts8zORP.png)\r\n\r\nThe docs for `mosaic()` don't give any insight (and by the way, currently the \"Using a DataFrame as source,\" section isn't being parsed as code by your Sphinx run: http://statsmodels.sourceforge.net/devel/generated/statsmodels.graphics.mosaicplot.mosaic.html).\r\n\r\nI tried reformatting\r\n```\r\nG = {(I,d) : D.loc[(D.DecisionM == d) & (D.IntelligentM==I), \"freq\"].iloc[0] for d in [0,1] for I in range(5,10)}\r\n\r\nmosaic(G)\r\nplt.show()\r\n```\r\nBut this is awkward to write and comes out wrong because dictionaries are unordered (I see that I could fix that with the `index` parameter, but how to use that is unclear to me and just makes the code above even more awkard).\r\n![fail#2](http://i.imgur.com/3pFUtVH.png)\r\n\r\nThe way I got that first (correct) image was computationally expensive: I rewrote the DataFrame in the form `mosaic()` wants and let it crunch it up again:\r\n```\r\nimport itertools\r\nflatten = lambda L: list(itertools.chain.from_iterable(L))\r\n\r\nG2 = flatten([[(I,d)]*D.loc[(D.DecisionM == d) & (D.IntelligentM==I), \"freq\"].iloc[0] for d in [0,1] for I in range(5,10)])\r\nG2 = pandas.DataFrame(G2)\r\nG2.columns = [\"IntelligentM\", \"DecisionM\"]\r\nprint(G2)\r\n\r\nmosaic(G2,[\"IntelligentM\", \"DecisionM\"])\r\nplt.show()\r\n```\r\nTo be clear, G2 looks like:\r\n```\r\n     IntelligentM  DecisionM\r\n0               5          0\r\n1               5          0\r\n2               5          0\r\n3               5          0\r\n4               5          0\r\n5               5          0\r\n6               5          0\r\n7               5          0\r\n8               5          0\r\n9               6          0\r\n10              6          0\r\n11              6          0\r\n12              6          0\r\n13              6          0\r\n14              6          0\r\n15              6          0\r\n16              6          0\r\n17              6          0\r\n18              6          0\r\n19              6          0\r\n20              6          0\r\n21              6          0\r\n22              6          0\r\n23              6          0\r\n24              6          0\r\n25              6          0\r\n26              6          0\r\n27              6          0\r\n28              6          0\r\n29              6          0\r\n..            ...        ...\r\n212             8          1\r\n213             8          1\r\n214             8          1\r\n215             9          1\r\n216             9          1\r\n217             9          1\r\n218             9          1\r\n219             9          1\r\n220             9          1\r\n221             9          1\r\n222             9          1\r\n223             9          1\r\n224             9          1\r\n225             9          1\r\n226             9          1\r\n227             9          1\r\n228             9          1\r\n229             9          1\r\n230             9          1\r\n231             9          1\r\n232             9          1\r\n233             9          1\r\n234             9          1\r\n235             9          1\r\n236             9          1\r\n237             9          1\r\n238             9          1\r\n239             9          1\r\n240             9          1\r\n241             9          1\r\n\r\n[242 rows x 2 columns]\r\n```\r\nThis is even more verbose than the last because `mosaic()` demands labelled columns. It's also slow. I want to avoid having to do this, but it's the only way I've found so far.\r\n\r\nFurther, sometimes contingency data comes in crosstab form; in fact I can generate it from the above:\r\n```\r\nIn [4]: pandas.crosstab(G2.IntelligentM, G2.DecisionM)\r\nOut[4]: \r\nDecisionM      0   1\r\nIntelligentM        \r\n5              9  11\r\n6             21  12\r\n7             35  30\r\n8             35  48\r\n9             14  27\r\n```\r\n\r\nBut `mosaic()` fails badly on this:\r\n```\r\nIn [7]: mosaic(pandas.crosstab(G2.IntelligentM, G2.DecisionM),[\"IntelligentM\",\"DecisionM\"])\r\n...\r\nKeyError: \"['IntelligentM' 'DecisionM'] not in index\"\r\n```\r\n\r\nCan mosaic() gain a `freq=` param that shortcircuits `[_normalize_dataframe()](https://github.com/statsmodels/statsmodels/blob/b235b7bff9890f4b6280f3c0f4a57c605f3b81e0/statsmodels/graphics/mosaicplot.py#L322)` and something similar to handle crosstabs? Or maybe it would be better--if less elegant--to be split to mosaic_contigency(), mosaic_items(), mosaic_crosstab().\r\ncontingency mode would operate on dicts `{(var1, var2): count}`, item mode would operate on tables `(var1, var2, count)` and crosstab mode would operate on matrices `[var1, var2]: count`.\r\n\r\nI'm on statsmodels 0.6.1 on Python3."},"comment":{"url":"https://api.github.com/repos/statsmodels/statsmodels/issues/comments/70724886","html_url":"https://github.com/statsmodels/statsmodels/issues/2190#issuecomment-70724886","issue_url":"https://api.github.com/repos/statsmodels/statsmodels/issues/2190","id":70724886,"user":{"login":"kousu","id":987487,"avatar_url":"https://avatars.githubusercontent.com/u/987487?v=3","gravatar_id":"","url":"https://api.github.com/users/kousu","html_url":"https://github.com/kousu","followers_url":"https://api.github.com/users/kousu/followers","following_url":"https://api.github.com/users/kousu/following{/other_user}","gists_url":"https://api.github.com/users/kousu/gists{/gist_id}","starred_url":"https://api.github.com/users/kousu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kousu/subscriptions","organizations_url":"https://api.github.com/users/kousu/orgs","repos_url":"https://api.github.com/users/kousu/repos","events_url":"https://api.github.com/users/kousu/events{/privacy}","received_events_url":"https://api.github.com/users/kousu/received_events","type":"User","site_admin":false},"created_at":"2015-01-20T20:17:39Z","updated_at":"2015-01-20T20:17:39Z","body":"For future reference, for someone trying to work this out in the future, I just noticed there's a bug in my expected plot: it's missing category 10. I don't know why that happened."}}