Here is the code for creating subplots and the graphs look like what's shown in the attached image. Is there a way to adjust the graphs so they look good and identical in size?
import matplotlib.pyplot as plt
df = pd.read_csv(path)
merged = df[df["test"].isin(['viral_load'])]
g = merged.groupby('id')
fig, axes = plt.subplots(g.ngroups, sharex=True, figsize=(8, 6))
for i, (id, d) in enumerate(g):
ax = d.plot.line(x='months', y='result', ax=axes[i], title=id)
ax.legend().remove()
fig.tight_layout()
Here you can see the result of the above code.
Related
I have a code from a dataframe
Y = df['label']
for col in categorical_cols:
tab = pd.crosstab(df[col],Y)
annot = x.div(x.sum(axis=1).astype('float64'),axis=0)
annot.plot(kind='bar',stacked=True)
plt.title('Distribution of %s'%col)
plt.xlabel('%s'%col,size='x-large')
plt.xticks(rotation=45)
plt.legend()
How can I plot these using different subplots in a single figure because this loops prints the last column's figure. So all figures are same.
Also: How can I produce the same using matplotlib/seaborn using matplotlib which shows me the % or absolute values.
You need to create the different subplots and then pass one axes object to each call of annot.plot via the ax keyword, something like this:
import math
import matplotlib.pyplot as plt
n = len(categorical_cols)
nrows = math.ceil(float(n) / 3.0)
fig, ax = plt.subplots(ncols=3, nrows=nrows, figsize=(9, nrows*3))
ax = ax.flatten()
Y = df['label']
for idx, col in enumerate(categorical_cols):
tab = pd.crosstab(df[col],Y)
annot = x.div(x.sum(axis=1).astype('float64'),axis=0)
annot.plot(kind='bar',stacked=True, ax=ax[idx])
ax[idx].title('Distribution of %s'%col)
ax[idx].set_xlabel('%s'%col,size='x-large')
ax.tick_params('x', labelrotation=45)
plt.legend()
I'm plotting a CSV file from my simulation results. The plot has three graphs in the same figure fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(24, 6)).
However, for comparison purposes I want the y-axis in all graphs starting at zero and the ending at a specific value. I tried the solution mentioned here from the Seaborn author. I don't get any errors, but the solution also does not work for me.
Here's my script:
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
fname = 'results/filename.csv'
def plot_file():
fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(24, 6))
df = pd.read_csv(fname, sep='\t')
profits = \
df.groupby(['providerId', 'periods'], as_index=False)['profits'].sum()
# y-axis needs to start at zero and end at 10
g = sns.lineplot(x='periods',
y='profits',
data=profits,
hue='providerId',
legend='full',
ax=axes[0])
# y-axis need to start at zero and end at one
g = sns.scatterplot(x='periods',
y='price',
hue='providerId',
style='providerId',
data=df,
legend=False,
ax=axes[1])
# y-axis need to start at zero and end at one
g = sns.scatterplot(x='periods',
y='quality',
hue='providerId',
style='providerId',
data=df,
legend=False,
ax=axes[2])
g.set(ylim=(0, None))
plt.show()
print(g) # -> AxesSubplot(0.672059,0.11;0.227941x0.77)
The resulting figure is as follows:
How can I adjust each individual plot?
Based on the way you've written your code, you can refer to each subplot axis with g.axis and use g.axis.set_ylim(low,high). (A difference compared to the linked answer is that your graphs are not being plotted on a seaborn FacetGrid.)
An example using dummy data and different axis ranges to illustrate:
df = pd.DataFrame(np.random.uniform(0,10,(100,2)), columns=['a','b'])
fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(8,4))
g = sns.lineplot(x='a',
y='b',
data=df.sample(10),
ax=axes[0])
g.axes.set_ylim(0,25)
g = sns.scatterplot(x='a',
y='b',
data=df.sample(10),
ax=axes[1])
g.axes.set_ylim(0,3.5)
g = sns.scatterplot(x='a',
y='b',
data=df.sample(10),
ax=axes[2])
g.axes.set_ylim(0,0.3)
plt.tight_layout()
plt.show()
My code is inside a Jupyter Notebook.
I can create a chart using Method 1 below, and have it look exactly as I'd like it to look.
But when I try with Method 2, which uses subplot, I don't know how to make it look the same (setting the figsize, colors, legend off to the right).
How do I use subplot, and have it look the same as Method 1?
Thank you in advance for your help!
# Using Numpy and Pandas
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.style as style
df = pd.DataFrame(np.random.randint(0,100,size=(4, 4)), columns=list('ABCD'))
style.use('fivethirtyeight')
# Colorblind-friendly colors
colors = [[0,0,0], [230/255,159/255,0], [86/255,180/255,233/255], [0,158/255,115/255]]
# Method 1
chart = df.plot(figsize = (10,5), color = colors)
chart.yaxis.label.set_visible(True)
chart.set_ylabel("Bitcoin Price")
chart.set_xlabel("Time")
chart.legend(bbox_to_anchor=(1.05, 1), loc=2)
plt.show()
# Method 2
fig, ax = plt.subplots()
ax.plot(df)
ax.set_ylabel("Bitcoin Price")
ax.set_xlabel("Time")
plt.show()
You just replace char by ax, like this
ax.yaxis.label.set_visible(True)
ax.set_ylabel("Bitcoin Price") ax.set_xlabel("Time") ax.legend(bbox_to_anchor=(1.05, 1), loc=2)
I'm thinking of two ways to get a result that might be useful for you. pd.DataFrame.plot returns an Axes object you can pass all the methods you want, so both examples just replace chart for ax.
Setup
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.style as style
df = pd.DataFrame(np.random.randint(0,100,size=(4, 4)), columns=list('ABCD'))
style.use('fivethirtyeight')
# Colorblind-friendly colors
colors = [[0,0,0], [230/255,159/255,0], [86/255,180/255,233/255], [0,158/255,115/255]]
Iterating over df
colors_gen = (x for x in colors) # we will also be iterating over the colors
fig, ax = plt.subplots(figsize = (10,5))
for i in df: # iterate over columns...
ax.plot(df[i], color=next(colors_gen)) # and plot one at a time
ax.set_ylabel("Bitcoin Price")
ax.set_xlabel("Time")
ax.legend(bbox_to_anchor=(1.05, 1), loc=2)
ax.yaxis.label.set_visible(True)
plt.show()
Use pd.DataFrame.plot but pass ax as an argument
fig, ax = plt.subplots(figsize = (10,5))
df.plot(color=colors, ax=ax)
ax.set_ylabel("Bitcoin Price")
ax.set_xlabel("Time")
ax.legend(bbox_to_anchor=(1.05, 1), loc=2)
ax.yaxis.label.set_visible(True)
plt.show()
I wanted to duplicate the same plot on the same figure with different colors and legends and here is my minimalistic working code.
import matplotlib.pyplot as plt
import numpy as np
def make_layout(data):
fig = plt.figure()
ax = fig.add_subplot(111)
p, = ax.plot(data,'o')
p.set_markerfacecolor('g')
# Presumably lots of complicated settings here
return fig, ax, p
data = data = np.linspace(0,1)
f1, a1, p1 = make_layout(data)
f2, a2, p2 = make_layout(data**2)
p2.set_markerfacecolor('yellow')
Here are the two plots i got in separate figures and they don't look like the same. How can i do that? Thank you for any help.
I wanted to merge them in one same figure. I also wanted to add legends and labels.
Your plotting function needs to accept an Axes object as a parameter. You then create the figure and axes outside of the function:
import matplotlib.pyplot as plt
import numpy as np
def make_layout(data, ax):
p, = ax.plot(data, 'o')
p.set_markerfacecolor('g')
return p
So to plot everything on 1 Axes, you'd do:
data = data = np.linspace(0,1)
fig, ax = plt.subplots(nrows=1, ncols=1)
p1 = make_layout(data, ax)
p2 = make_layout(data**2, ax)
p2.set_markerfacecolor('yellow')
If you want separate axes, you'd do something like this:
data = data = np.linspace(0,1)
fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2)
p1 = make_layout(data, ax1)
p2 = make_layout(data**2, ax2)
p2.set_markerfacecolor('yellow')
Here is what i want to do, histogram plots of all columns of a dataframe but without the grid axes. The below code works, but preferably I'd like a more elegant solution (such as passing an argument to hist)
%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
X = np.asarray([50]*25+[30]*10)
X2 = np.asarray([90]*10+[20]*25)
X3 = np.asarray([10]*15+[70]*20)
df = pd.DataFrame(np.vstack([X, X2, X3]).T)
def plot_hists(df, nbins=10, figsize=(8, 8), disable_axis_labels = True):
plt.close('all')
grid_of_ax_hists = df.hist(bins=nbins, figsize=figsize)
if disable_axis_labels:
for row in grid_of_ax_hists:
for ax in row:
ax.xaxis.set_visible(False)
ax.yaxis.set_visible(False)
plt.show()
df.hist()
plt.subplots()
plot_hists(df, nbins=10, figsize=(8, 8), disable_axis_labels = True)
Even so this thread is kinda old, i'd like to add a working solution because i've just had the same issue.
At least in pandas 0.18
df.hist() takes all possible plotting keywords from pandas.DataFrame.plot
df.hist(grid=False)
works easily.. and there is no need of dealing with matplotlib axes.
You can try:
fig = plt.figure(figsize=figsize)
ax1 = fig.add_subplot(111)
df.hist(bins=nbins, ax=ax1)
ax1.grid(b=False)