There is a strange behavior when using pandas and seaborn to plot a scatter plot that has only three points: the points don't have the same color. The problem disappears when seaborn is not loaded or when there are more than three points, or when plotting with matplotlib's scatter method directly. See the following example:
from pandas import DataFrame #0.16.0
import matplotlib.pyplot as plt #1.4.3
import seaborn as sns #0.5.1
import numpy as np #1.9.2
df = DataFrame({'x': np.random.uniform(0, 1, 3), 'y': np.random.uniform(0, 1, 3)})
df.plot(kind = 'scatter', x = 'x', y = 'y')
plt.show()
df = DataFrame({'x': np.random.uniform(0, 1, 4), 'y': np.random.uniform(0, 1, 4)})
df.plot(kind = 'scatter', x = 'x', y = 'y')
plt.show()
I've tracked down the bug. The bug is in pandas
technically, not seaborn
as I originally thought, though it involves code from pandas
, seaborn
, and matplotlib
...
In pandas.tools.plotting.ScatterPlot._make_plot
the following code occurs to choose the colours to be used in the scatter plot
if c is None:
c_values = self.plt.rcParams['patch.facecolor']
elif c_is_column:
c_values = self.data[c].values
else:
c_values = c
In your case c
will be equal to None
, which is the default value, and so c_values
will be given by plt.rcParams['patch.facecolor']
.
Now, as part of setting itself up, seaborn modifies plt.rcParams['patch.facecolor']
to (0.5725490196078431, 0.7764705882352941, 1.0)
which is an RGB tuple. If seaborn
is not used then the value is the matplotlib default which is 'b'
(a string indicating the colour "blue").
c_values
is then used later on to actually plot the graph within ax.scatter
scatter = ax.scatter(data[x].values, data[y].values, c=c_values,
label=label, cmap=cmap, **self.kwds)
The issue arises because the keyword argument c
can accept multiple different types of argument, it can accept:-
'b'
in the original matplotlib case); The matplotlib docs specifically state the following, highlighting mine
c can be a single color format string, or a sequence of color specifications of length N, or a sequence of N numbers to be mapped to colors using the cmap and norm specified via kwargs (see below). Note that c should not be a single numeric RGB or RGBA sequence because that is indistinguishable from an array of values to be colormapped. c can be a 2-D array in which the rows are RGB or RGBA, however.
What basically happens is that matplotlib takes the c_values
value (which is a tuple of three numbers) and then maps those colours onto the current colormap (which is set by pandas to be Greys
by default). As such, you get three scatter points with different "greyishness" . When you have more than 3 scatter points, matplotlib assumes that it must be a RGB tuple because the length doesn't match the length of the data arrays (3 != 4) and so uses it as a constant RBG colour.
This has been written up as a bug report on the pandas Github here .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.