Why are two figures showing up - python

I have the following code
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
info = {"Quiz":[1,2,5,4,3,2,6,5,7],
"Score":[1,6,4,2,8,9,10,5,7]}
df = pd.DataFrame.from_dict(info)
fig, ax = plt.subplots(figsize=(6,4))
sns.catplot(x="Quiz", y = 'Score', data=df, ax=ax)
plt.show()
This is what I am seeing.
Why are there two images showing?

Reading the documentation, catplot doesn't return an ax object.

Related

Matplot legends are printing twice

I am writing a simple code with matplotlib/seaborn to plot the data of a sample csv file. However, when call the sns.histplot() function through a for loop, the legends of each column are displaying twice. Any help would be greatly appreciated:)
Here's the code:
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import matplotlib
sns.set_style('darkgrid')
df = pd.read_csv('dm_office_sales.csv')
df['salary'] = df['salary'] * 3
df['sample salary'] = df['salary'] * 2
x = df['salary']
y = df['sales']
z = df['sample salary']
fig,ax = plt.subplots()
for i in [x,y,z]:
sns.histplot(data = i, bins=50, ax=ax, palette = 'bright',alpha=0.3, label='{}'.format(i.name))
plt.legend(numpoints=1)
plt.suptitle('Sales/Salary Histogram')
plt.show()
Pass just the columns in question in one step, instead of looping.
sns.histplot(data=df[['salary', 'sales', 'sample salary']], ...)
Here's a demo with the tips dataset:
tips = sns.load_dataset('tips')
fig, ax = plt.subplots()
sns.histplot(tips[['total_bill', 'tip']], bins=50,
ax=ax, alpha=0.3, palette='bright')
plt.show()

countplot and pieplot inverting labels colors

I´m plotting a countplot and a pieplot but "male" and "female" are tagged in opposite colors in each of them
import matplotlib.pyplot as plt
import seaborn as sns
fig, ax = plt.subplots(1,figsize=(20,5))
sns.countplot(x="sex",data=insurance_ds) #plotting histogram
plt.title("Male/Female Frequency",fontsize=25)
plt.xlabel("Sex",fontsize=20)
plt.ylabel("Frequency",fontsize=20)
plt.tick_params(labelsize=12)
plt.xticks(rotation=90)
plt.yticks(rotation=45)
fig, ax = plt.subplots(1,figsize=(5,5))
insurance_ds["sex"].value_counts().plot.pie(autopct='%1.1f%%',shadow=True,textprops={'fontsize': 10})
plt.title("Male/Female Frequency",fontsize=25)
If you set your column as a category, it should work too:
import matplotlib.pyplot as plt
import seaborn as sns
insurance_ds = pd.DataFrame({'sex':np.random.choice(['male','female'],1000)})
insurance_ds['sex'] = pd.Categorical(insurance_ds['sex'],categories=['male','female'])
fig, ax = plt.subplots(1,2,figsize=(10,5))
sns.countplot(x="sex",data=insurance_ds,ax=ax[0])
insurance_ds["sex"].value_counts().plot.pie(autopct='%1.1f%%',shadow=True,textprops={'fontsize': 10},ax=ax[1])

How do I format my y-axis to show a comma separator in my Seaborn graph? [duplicate]

import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import seaborn as sns
import pandas as pd
sns.set(style="darkgrid")
fig, ax = plt.subplots(figsize=(8, 5))
palette = sns.color_palette("bright", 6)
g = sns.scatterplot(ax=ax, x="Area", y="Rent/Sqft", hue="Region", marker='o', data=df, s=100, palette= palette)
g.legend(bbox_to_anchor=(1, 1), ncol=1)
g.set(xlim = (50000,250000))
How can I can change the axis format from a number to custom format? For example, 125000 to 125.00K
IIUC you can format the xticks and set these:
In[60]:
#generate some psuedo data
df = pd.DataFrame({'num':[50000, 75000, 100000, 125000], 'Rent/Sqft':np.random.randn(4), 'Region':list('abcd')})
df
Out[60]:
num Rent/Sqft Region
0 50000 0.109196 a
1 75000 0.566553 b
2 100000 -0.274064 c
3 125000 -0.636492 d
In[61]:
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import seaborn as sns
import pandas as pd
sns.set(style="darkgrid")
fig, ax = plt.subplots(figsize=(8, 5))
palette = sns.color_palette("bright", 4)
g = sns.scatterplot(ax=ax, x="num", y="Rent/Sqft", hue="Region", marker='o', data=df, s=100, palette= palette)
g.legend(bbox_to_anchor=(1, 1), ncol=1)
g.set(xlim = (50000,250000))
xlabels = ['{:,.2f}'.format(x) + 'K' for x in g.get_xticks()/1000]
g.set_xticklabels(xlabels)
Out[61]:
The key bit here is this line:
xlabels = ['{:,.2f}'.format(x) + 'K' for x in g.get_xticks()/1000]
g.set_xticklabels(xlabels)
So this divides all the ticks by 1000 and then formats them and sets the xtick labels
UPDATE
Thanks to #ScottBoston who has suggested a better method:
ax.xaxis.set_major_formatter(ticker.FuncFormatter(lambda x, pos: '{:,.2f}'.format(x/1000) + 'K'))
see the docs
The canonical way of formatting the tick labels in the standard units is to use an EngFormatter. There is also an example in the matplotlib docs.
Also see Tick locating and formatting
Here it might look as follows.
import numpy as np; np.random.seed(42)
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import seaborn as sns
import pandas as pd
df = pd.DataFrame({"xaxs" : np.random.randint(50000,250000, size=20),
"yaxs" : np.random.randint(7,15, size=20),
"col" : np.random.choice(list("ABC"), size=20)})
fig, ax = plt.subplots(figsize=(8, 5))
palette = sns.color_palette("bright", 6)
sns.scatterplot(ax=ax, x="xaxs", y="yaxs", hue="col", data=df,
marker='o', s=100, palette="magma")
ax.legend(bbox_to_anchor=(1, 1), ncol=1)
ax.set(xlim = (50000,250000))
ax.xaxis.set_major_formatter(ticker.EngFormatter())
plt.show()
Using Seaborn without importing matplotlib:
import seaborn as sns
sns.set()
chart = sns.relplot(x="x_val", y="y_val", kind="line", data=my_data)
ticks = chart.axes[0][0].get_xticks()
xlabels = ['$' + '{:,.0f}'.format(x) for x in ticks]
chart.set_xticklabels(xlabels)
chart.fig
Thank you to EdChum's answer above for getting me 90% there.
Here's how I'm solving this: (similar to ScottBoston)
from matplotlib.ticker import FuncFormatter
f = lambda x, pos: f'{x/10**3:,.0f}K'
ax.xaxis.set_major_formatter(FuncFormatter(f))
We could used the APIs: ax.get_xticklabels() , get_text() and ax.set_xticklabels do it.
e.g,
xlabels = ['{:.2f}k'.format(float(x.get_text().replace('−', '-')))/1000 for x in g.get_xticklabels()]
g.set_xticklabels(xlabels)

How to remove vertical line from plot?

I'm getting a seemingly random vertical line on my plot and I'm unsure how to remove it. Here's the code to create the plot:
import pandas as pd
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns; sns.set()
fig = plt.figure()
df=pd.read_csv("Resources/outmerge.csv")
print(df.head())
x='month'
y ='Count'
sns.set_style("dark", {'axes.grid' : False})
ax = sns.lineplot('month', 'Count', data=df, marker='o',markersize=8,markers=True, label='2017')
ax = sns.lineplot('month', 'Count2', data=df, marker='^',markersize=8,markers=True, label='2018')
ax.grid(False)
fname='Resources/output.png'
plt.savefig(fname, dpi=300)
plt.show()
And this is the resulting plot. Note the vertical line at x axis: 1. I'm running seaborn 0.9.0.

How do I change the plot size of a regplot in Seaborn?

Something similar to the fig.set_size_inches(18.5, 10.5) of matplotlib.
You can declare fig, ax pair via plt.subplots() first, then set proper size on that figure, and ask sns.regplot to plot on that ax
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
# some artificial data
data = np.random.multivariate_normal([0,0], [[1,-0.5],[-0.5,1]], size=100)
# plot
sns.set_style('ticks')
fig, ax = plt.subplots()
fig.set_size_inches(18.5, 10.5)
sns.regplot(data[:,0], data[:,1], ax=ax)
sns.despine()
Or a little bit shorter:
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
# some artificial data
data = np.random.multivariate_normal([0,0], [[1,-0.5],[-0.5,1]], size=100)
# plot
sns.set_style('ticks')
g = sns.regplot(data[:,0], data[:,1])
g.figure.set_size_inches(18.5, 10.5)
sns.despine()

Categories

Resources