Matplotlib: How to plot an empty circle in an scatter plot using pandas plot api? [duplicate] - pandas

This question already has answers here:
How to do a scatter plot with empty circles in Python?
(6 answers)
Closed 4 years ago.
I'm trying to plot a scatter plot with pandas api where each point is an empty circle, just with border color and transparency. I've tried a lot of tweaks in this code:
ax = ddf.plot.scatter(
x='espvida',
y='e_anosestudo',
c=ddf['cor'],
alpha=.2,
marker='o');
The generated plot looks like this:
If you look closely at the points:
you'll see that they have a transparent fill color and a border. I'd like it to have just a transparent border. Hou would I do it?

I can't seem to get it to work with DataFrame.plot.scatter; it doesn't seem to respect the facecolors='none' kwarg, likely because some default color argument is being passed to plt.scatter.
Instead, fall back to matplotlib, specifying facecolors='none' and setting the edgecolors to the column in your df that represents the color.
Sample Data
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
df = pd.DataFrame({'x': np.random.normal(1,1,1000),
'y': np.random.normal(1,1,1000),
'color': list('rgby')*250})
plt.scatter(df.x.values, df.y.values, facecolors='none', edgecolors=df['color'], alpha=0.2, s=100)
plt.show()

From the matplotlib scatter doc:
edgecolors : color or sequence of color, optional, default: 'face'. The edge color of the marker. Possible values:
'face': The edge color will always be the same as the face color.
'none': No patch boundary will be drawn.
A matplotib color.
For non-filled markers, the edgecolors kwarg is ignored and forced to 'face' internally
Try add: edgecolors='none':
ax = ddf.plot.scatter(
x='espvida',
y='e_anosestudo',
c=ddf['cor'],
alpha=.2,
marker='o',
edgecolors='none);

Related

Seaborn white axes for black background presentation [duplicate]

This question already has answers here:
Best way to display Seaborn/Matplotlib plots with a dark iPython Notebook profile
(4 answers)
Closed last year.
I need help with styling the axes of the graph given below. I need to enforce the axes as well as their labels to be white so as the png fits on a black background.
As a sample code I provide the standard:
# loading dataset
data = sns.load_dataset("iris")
# draw lineplot
sns.lineplot(x="sepal_length", y="sepal_width", data=data)
plt.tight_layout()
plt.show()
fig.savefig('MyImage.png', transparent=True)
which will provide
So, essentially, I would like that the 4 axes and the labels become white.
You can use a dark style:
import matplotlib.pyplot as plt
plt.style.use('dark_background')

Use same color for all grouped bars in Seaborn barplot

The following code produces a barchart with differently colored bars for each "hue" value associated with the grouping variable y:
from matplotlib import pyplot as plt
import seaborn as sns
ax = sns.barplot(x=[3, 7, 12, 10], y=list("AABB"), hue=list("XYXY"))
plt.show()
I want to change the colors so that all bars belonging to the same grouping value have the same color. That is, the first two bars where y == "A" should be orange, and the last two bars where y == "B" should be blue.
I've tried the palette argument of `sns.barplot(). However, unless I'm missing something, this allows me to specify the color of each hue level, but not separately for the values of the grouping variable.
I've also had a look at the answer to this related question, which asks something similar about box-whisker plots created by sns.boxplot(). The accepted answer suggests to access the rectangles representing the bars using the artists property of the axes. However, it seems that sns.barplot() doesn't use artists in the same way as sns.boxplot(): ax.artists appears always to be an empty list:
print(ax.artists)
[]
So, what do I have to change so that the top two bars appear in blue, and the bottom two bars appear in orange?
The bars are not in artists but in patches. So you may loop over ax.patches and set the colors to your liking.
from matplotlib import pyplot as plt
import seaborn as sns
ax = sns.barplot(x=[3, 7, 12, 10], y=list("AABB"), hue=list("XYXY"))
for i, bar in enumerate(ax.patches):
bar.set_color("C{}".format(i%2))
plt.show()

Why does the Seaborn color palette not work for Pandas bar plots?

An online Jupyter notebook demonstrating the code and showing the color differences is at:
https://anaconda.org/walter/pandas_seaborn_color/notebook
The colors are wrong when I make bar plots using Pandas dataframe method. Seaborn improves the color palette of matplotlib. All plots from matplotlib automatically use the new Seaborn palette. However, bar plots from Pandas dataframes revert to the non-Seaborn colors. This behavior is not consistent, because line plots from Pandas dataframes do use Seaborn colors. This makes my plots appear to be in different styles, even if I use Pandas for all my plots.
How can I plot using Pandas methods while getting a consistent Seaborn color palette?
I'm running this in python 2.7.11 using a conda environment with just the necessary packages for this code (pandas, matplotlib and seaborn).
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
df = pd.DataFrame({'y':[5,7,3,8]})
# matplotlib figure correctly uses Seaborn color palette
plt.figure()
plt.bar(df.index, df['y'])
plt.show()
# pandas bar plot reverts to default matplotlib color palette
df.plot(kind='bar')
plt.show()
# pandas line plots correctly use seaborn color palette
df.plot()
plt.show()
Credit to #mwaskom for pointing to sns.color_palette(). I was looking for that but somehow I missed it hence the original mess with prop_cycle.
As a workaround you can set the color by hand. Note how the color keyword argument behaves differently if you are plotting one or several columns.
df = pd.DataFrame({'x': [3, 6, 1, 2], 'y':[5, 7, 3, 8]})
df['y'].plot(kind='bar', color=sns.color_palette(n_colors=1))
df.plot(kind='bar', color=sns.color_palette())
My original answer:
prop_cycle = plt.rcParams['axes.prop_cycle']
df['y'].plot(kind='bar', color=next(iter(prop_cycle))['color'])
df.plot(kind='bar', color=[x['color'] for x in prop_cycle])
This was a bug in pandas specifically for bar plots (and boxplots as well I think), which is fixed in pandas master (see the reported issue and the PR to fix it).
This will be in pandas 0.18.0 which will be released in the coming weeks.

Creating a bar plot using Seaborn

I am trying to plot bar chart using seaborn. Sample data:
x=[1,1000,1001]
y=[200,300,400]
cat=['first','second','third']
df = pd.DataFrame(dict(x=x, y=y,cat=cat))
When I use:
sns.factorplot("x","y", data=df,kind="bar",palette="Blues",size=6,aspect=2,legend_out=False);
The figure produced is
When I add the legend
sns.factorplot("x","y", data=df,hue="cat",kind="bar",palette="Blues",size=6,aspect=2,legend_out=False);
The resulting figure looks like this
As you can see, the bar is shifted from the value. I don't know how to get the same layout as I had in the first figure and add the legend.
I am not necessarily tied to seaborn, I like the color palette, but any other approach is fine with me. The only requirement is that the figure looks like the first one and has the legend.
It looks like this issue arises here - from the docs searborn.factorplot
hue : string, optional
Variable name in data for splitting the plot by color. In the case of ``kind=”bar”, this also influences the placement on the x axis.
So, since seaborn uses matplotlib, you can do it like this:
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
x=[1,1000,1001]
y=[200,300,400]
sns.set_context(rc={"figure.figsize": (8, 4)})
nd = np.arange(3)
width=0.8
plt.xticks(nd+width/2., ('1','1000','1001'))
plt.xlim(-0.15,3)
fig = plt.bar(nd, y, color=sns.color_palette("Blues",3))
plt.legend(fig, ['First','Second','Third'], loc = "upper left", title = "cat")
plt.show()
Added #mwaskom's method to get the three sns colors.

Change colour of curve according to its y-value in matplotlib [duplicate]

This question already has answers here:
Having line color vary with data index for line graph in matplotlib?
(4 answers)
Set line colors according to colormap
(1 answer)
Closed 8 years ago.
I'm trying to replicate the style of the attached figure using matplotlib's facilities.
Basically, I want to change the colour of the curve according to its y-value using matplotlib.
The plot you've shown doesn't have the color set by the vertical axis of the plot (which is what I would consider the y-value). Instead, it just has 8 different plots overlain, each with a different color, without stating what the color means.
Here's an example of something that looks like your plot:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
# some fake data:
x = np.linspace(0, 2*np.pi, 1000)
fs = np.arange(1, 5.)
ys = np.sin(x*fs[:, None])
for y, f in zip(ys, fs):
plt.plot(x, y, lw=3, c=cm.hot(f/5))
If you actually want the color of one line to change with respect to its value, you have to kind of hack it, because any given Line2D object can only have one color, as far as I know. One way to do this is to make a scatter plot, where each dot can have any color.
x = np.linspace(0, 2*np.pi, 1000)
y = np.sin(2*x)
plt.scatter(x,y, c=cm.hot(np.abs(y)), edgecolor='none')
Notes:
The color vector should range between 0 and 1, so if y.max() > 1, then normalize by it: c=cm.hot(y/y.max()) and make sure it's all positive.
I used edgecolor='none' because by default the scatter markers have a black outline which makes the it look less like a uniform line.
If your data is spaced too far, you'll have to interpolate the data if you don't want gaps between markers.