Repository: mwaskom/seaborn

Issue:
sizes parameter for scatterplot does not accept dict with more than 2 objets
When trying to build a scatterplot with my data, I'd like to pass a dictionary to the sizes parameter, so
that I can have the same legend from one graphic to another.
If I write : 
```
ax = sns.scatterplot(x="pourcents", y="sources",
                                hue="textua_simplifié", size="NOM", palette=couleur, hue_order=["introduction",                                    "péripétie", "chant", "conclusion","autre","dialogue"],
                                sizes={0:20,1:250},
                                data=vieux)
plt.show()
```

I have the following error message : 
`ValueError: Missing sizes for the following levels: {2, 4, 5}`
Which is normal. But if I write instead : 
```
ax = sns.scatterplot(x="pourcents", y="sources",
                                hue="textua_simplifié", size="NOM", palette=couleur, hue_order=["introduction",                                    "péripétie", "chant", "conclusion","autre","dialogue"],
                                sizes={0:20,1:100,2:150,4:200,5:250},
                                data=vieux)
plt.show()
```
I get the following error:
[...]
``` /usr/local/lib/python3.6/site-packages/seaborn/relational.py in size_lookup(self, key)
    281         if self.size_type == "numeric":
    282             min_size, max_size = self.size_range
 --> 283             val = self.size_norm(key)
    284             if np.ma.is_masked(val):
    285                 return 0
TypeError: 'NoneType' object is not callable
```

I'm quite new to Seaborn, but it seems to me that it is not the intended behaviour.


Discussion:

Patch:
diff --git a/seaborn/relational.py b/seaborn/relational.py
index 77bebe30..02dd6e6b 100644
--- a/seaborn/relational.py
+++ b/seaborn/relational.py
@@ -428,6 +428,10 @@ class _RelationalPlotter(object):
                 except TypeError:
                     limits = None
 
+                # enforce numeric data to be treated as categorical -
+                # this ensures no size norm is used for legend (#GH1570)
+                var_type = "categorical"
+
             else:
 
                 # Infer the range of sizes to use


Test patch:
diff --git a/seaborn/tests/test_relational.py b/seaborn/tests/test_relational.py
index 874c1d90..c363d164 100644
--- a/seaborn/tests/test_relational.py
+++ b/seaborn/tests/test_relational.py
@@ -1331,6 +1331,32 @@ class TestScatterPlotter(TestRelationalPlotter):
 
         # --
 
+        ax.clear()
+        sizes_list=[10,100,200]
+        p = rel._ScatterPlotter(x="x", y="y", size="s", sizes=sizes_list,
+                                  data=long_df, legend="full")
+        p.add_legend_data(ax)
+        handles, labels = ax.get_legend_handles_labels()
+        sizes = [h.get_sizes()[0] for h in handles]
+        expected_sizes = [0] + [p.sizes[l] for l in p.size_levels]
+        assert labels == ["s"] + [str(l) for l in p.size_levels]
+        assert sizes == expected_sizes
+
+        # --
+
+        ax.clear()
+        sizes_dict={2:10,4:100,8:200}
+        p = rel._ScatterPlotter(x="x", y="y", size="s", sizes=sizes_dict,
+                                  data=long_df, legend="full")
+        p.add_legend_data(ax)
+        handles, labels = ax.get_legend_handles_labels()
+        sizes = [h.get_sizes()[0] for h in handles]
+        expected_sizes = [0] + [p.sizes[l] for l in p.size_levels]
+        assert labels == ["s"] + [str(l) for l in p.size_levels]
+        assert sizes == expected_sizes
+        
+        # --
+
         x, y = np.random.randn(2, 40)
         z = np.tile(np.arange(20), 2)