Related
I am trying to create an axis plot. I was trying to loop over it as I am plotting the same variable for two different categories. Currently, I have written code two times but I am looking for a smarter way with looping, if possible. Any other suggestion will also be helpful.
zone = ['AB','CD']
plt.style.use('default')
fig,(ax0,ax1) = plt.subplots(2,1, figsize = (18,18), sharex = False)
i = 0
while i < len(zone):
if zone[i] == zone[0]:
ax0.plot(df0['datetime'], df0['pnl1'], color='k', linewidth=1, label ='PnL1')
ax0.plot(df0['datetime'], df0['pnl2'], color='m', linewidth=1, label ='PnL2')
ax00 = ax0.twinx()
ax00.bar(df0['datetime'], df0['qty'], width = 1/96, color='g', align = 'edge', alpha = 0.5, label ='Qty')
elif zone[i] == zone[1]:
ax1.plot(df0['datetime'], df0['pnl1'], color='k', linewidth=1, label ='PnL1')
ax1.plot(df0['datetime'], df0['pnl2'], color='m', linewidth=1, label ='PnL2')
ax01 = ax1.twinx()
ax01.bar(df0['datetime'], df0['hedge'], width = 1/96, color='g', align = 'edge', alpha = 0.5, label ='Qty')
i = i + 1
I want to check if something like below can be done with axis plots or not.
zone = ['AB','CD']
plt.style.use('default')
fig,(ax0,ax1) = plt.subplots(2,1, figsize = (18,18), sharex = False)
i = 0
while i < len(zone):
ax{''}.format(i).plot(df0['datetime'], df0['pnl1'], color='k', linewidth=1, label ='PnL1')
ax{''}.format(i).plot(df0['datetime'], df0['pnl2'], color='m', linewidth=1, label ='PnL2')
ax0{''}.format(i) = ax{''}.format(i).twinx()
ax0{''}.format(i).bar(df0['datetime'], df0['qty'], width = 1/96, color='g', align = 'edge', alpha = 0.5, label ='Qty')
It did not work for me. Any leads to execute axis plot with loop will be helpful.
Here are some ways:
Simply loop over the list of axes
import matplotlib.pyplot as plt
import numpy as np
fig,axes = plt.subplots(2,1)
x = np.linspace(0,5,21)
for ax in axes:
ax.plot(x,np.sin(x))
plt.show()
Works also with index:
for i in range(len(axes)):
axes[i].plot(x,np.sin(x))
For a grid of plot you can use a similar approach:
import matplotlib.pyplot as plt
import numpy as np
fig,axes = plt.subplots(2,2)
x = np.linspace(0,5,21)
for i in range(len(axes)):
for j in range(len(axes[0])):
axes[i][j].plot(x,np.sin(x))
plt.show()
If you don't like double-loops, you can flatten the array with np.ravel()
fig,axes = plt.subplots(2,2)
x = np.linspace(0,5,21)
for ax in np.ravel(axes):
ax.plot(x,np.sin(x))
plt.show()
In python, how to increase the current y-axis size?
Assuming, in the normal plot it is [0,50000]and [0,20000], but I want it to be [0,50000] and [0,50000]... [0,50000]. All histograms with y axis from 0 to 50000.
fig, axs = plt.subplots(ncols = 2, nrows = 3, figsize = (18, 18))
sns.distplot(df["EXT"], bins = 40, kde = False,
ax = axs[0, 0], color = sns.color_palette()[0]).set_title("Extroversion")
sns.distplot(df["EST"], bins = 40, kde = False,
ax = axs[0, 1], color = sns.color_palette()[1]).set_title("Neuroticism")
sns.distplot(df["AGR"], bins = 40, kde = False,
ax = axs[1, 0], color = sns.color_palette()[2]).set_title("Agreeableness")
sns.distplot(df["CSN"], bins = 40, kde = False,
ax = axs[1, 1], color = sns.color_palette()[3]).set_title("Conscientiousness")
sns.distplot(df["OPN"], bins = 40, kde = False,
ax = axs[2, 0], color = sns.color_palette()[4]).set_title("Openness")
fig.delaxes(axs[2, 1])
for ax in axs.flat:
ax.set(xlabel = None, ylabel = "Count")
plt.show()
plt.ylim(ymin, ymax)
or
ax.set_ylim(ymin, ymax)
in your case probably axs instead of ax
---------------edit--------------
I can't try your code starting from sns.distplot...
I tried the code below, however with minor change at how I created the figure itself. btw either 9,9 or 18,18 won't make any difference, it's just that my screen is not big enough to see all if I use 18,18.
fig = plt.figure(figsize=(9,9))
axs = []
for i in range(1,7):
axs.append(fig.add_subplot(3,2,i))
axs[i-1].set_ylim([0,1000])
With the code above, you will just see this:
I guess that should solve the main problem of your question, if I understand it correctly?
I managed to do
for ax in axs.flat:
ax.set(xlabel = None, ylabel = "Count"),
ax.set_ylim(0, 50000)
def plot_rain(num, show=False):
i = 0
for x in range(num):
ifile = "{:02d}".format(x)
saveimg_name = 'noaa_images/rain/rain.f0{}.png'.format(ifile)
data, _, lats, lons, datetime = collect_data(ifile, RAIN)
lons = np.apply_along_axis(lambda row: row - 360, 1, lons)
# 0.0001, 0.003,0.0005 make no blue background not sure why
cint = np.arange(0.0001, 0.003,0.0005)
fig, ax = plt.subplots()
# Create new figure
mapcrs = ccrs.Mercator(central_longitude=263, min_latitude=23, max_latitude=50, globe=None)
# Set data projection
datacrs = ccrs.PlateCarree()
gs = gridspec.GridSpec(2, 1, height_ratios=[1, .02], bottom=.07,
top=.99, hspace=0.01, wspace=0.01)
# Add the map and set the extent
ax = plt.subplot(gs[0], projection=mapcrs, frameon=False)
ax.set_extent([293, 233 , 23, 55], ccrs.PlateCarree())
ax.set_frame_on(False)
# Add state/country boundaries to plot
ax.add_feature(cfeature.STATES)
ax.add_feature(cfeature.BORDERS)
#Choose colormap https://matplotlib.org/2.0.1/users/colormaps.html
cf = ax.contourf(lons, lats, data, cint, cmap=plt.cm.jet,transform=datacrs, alpha=0.7)
# add color bar and title
# fig.text(.2, .12, "Kg of rainfall per m^2 s",fontweight="bold")
# cb = fig.colorbar(cf, pad=0, aspect=50, orientation='horizontal')
ax.axis('off')
i = i + 1
if show:
plt.show()
else:
plt.savefig(saveimg_name, transparent=True, bbox_inches='tight', pad_inches=0,quality =100,progressive= True)
This above code will generate an image and then I use folium to overlay the image on a map.
Image1 is what it looks like without adding title and color bar.
Here is what it looks like with title and color bar
I use this code
fig.text(.2, .12, "Kg of rainfall per m^2 s",fontweight="bold")
cb = fig.colorbar(cf, pad=0, aspect=50, orientation='horizontal')
After I added title and color bar, the original plots are shrunk. What I want is to add color bar and title without affecting the size of the plot. Thanks for the help!
To avoid resizing of existing axes when adding a colorbar you can give the colorbar its own axes via the cax keyword argument. Here is a minimal example as I cannot reproduce your plot without more data.
fig, ax = plt.subplots()
c = ax.imshow(np.random.random((10, 10)))
cbar_ax = fig.add_axes([0.1, 0.1, 0.05, 0.8])
# new ax with dimensions of the colorbar
cbar = fig.colorbar(c, cax=cbar_ax)
plt.show()
I have code that generates four subplots, but i want to generate those charts through loops , Currently i am following this piece of code to generate the chart
Code:
plt.figure(figsize=(20, 12))
plt.subplot(221)
sns.barplot(x = 'Category', y = 'POG_Added', data = df)
xticks(rotation = 90)
plt.xticks(size = 11)
plt.yticks(size = 11)
plt.xlabel("Category",size = 13)
plt.ylabel("POG_Added",size = 13)
plt.subplot(222)
sns.barplot(x = 'Category', y = 'Live_POG', data = df)
xticks(rotation = 90)
plt.xticks(size = 11)
plt.yticks(size = 11)
plt.xlabel("Category",size = 13)
plt.ylabel("Live_POG",size = 13)
plt.subplot(223)
sns.lineplot(x = 'Category', y = 'D01_CVR', data = df)
#sns.barplot(x = 'Category', y = 'D2-08-Visits', data = df,label='D2-08_Visits')
xticks(rotation = 90)
plt.xticks(size = 11)
plt.yticks(size = 11)
plt.xlabel("Category",size = 13)
plt.ylabel("D01_CVR",size = 13)
plt.subplot(224)
plt.xticks(rotation='vertical')
ax = sns.barplot(x='Category',y='D2-08-Units',data=df)
ax2 = ax.twinx()
ax2.plot(ax.get_xticks(), df["D01_CVR"], alpha = .75, color = 'r')
plt.subplots_adjust(hspace=0.55,wspace=0.55)
plt.show()
Here's how I do things like that:
import numpy as np
import matplotlib.pyplot as plt
data = [np.random.random((10, 10)) for _ in range(6)]
fig, axs = plt.subplots(ncols=3, nrows=2, figsize=(9, 6))
for ax, dat in zip(axs.ravel(), data):
ax.imshow(dat)
This produces:
The idea is that plt.subplots() produces an array of Axes objects, so you can loop over it and make your plots in the loop. In this case I need ndarray.ravel() because axs is a 2D array.
Consider tightening up repetitive code by:
Set unchanging aesthetics like all x-ticks and y-ticks font sizes in one call with plt.rc calls.
Build plt.subplots() and use its array of Axes objects.
Use ax argument of seaborn's barplot and lineplot to loop above Axes array.
While not completely DRY given the special two plots, below is adjustment:
# AXES AND TICKS FONT SIZES
plt.rc('xtick', labelsize=11)
plt.rc('ytick', labelsize=11)
plt.rc('axes', labelsize=13)
# FIGURE AND SUBPLOTS SETUP
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(20, 12))
# BAR PLOTS (FIRST ROW)
for i, col in enumerate(['POG_Added', 'Live_POG']):
sns.barplot(x='Category', y=col, data=df, ax=axes[0,i])
axes[0,i].tick_params(axis='x', labelrotation=90)
# LINE PLOT
sns.lineplot(x='Category', y='D01_CVR', data=df, ax=axes[1,0])
axes[1,0].tick_params(axis='x', labelrotation=90)
# BAR + LINE DUAL PLOT
sns.barplot(x='Category', y='D2-08-Units', data=df, ax=axes[1,1])
ax2 = axes[1,1].twinx()
ax2.plot(axes[1,1].get_xticks(), df["D01_CVR"], alpha = .75, color = 'r')
axes[1,1].tick_params(axis='x', labelrotation=90)
I am having issues with a plot that I have created where I am getting an unwanted additional color palette on the plot.
My script uses to list of data to create a plot with colored points.
plt.close('all')
fig, axes = plt.subplots(nrows = 1, ncols = 1)
fig.set_facecolor('white')
axes.set_ylabel('$dz$ [$\AA$]')
axes.set_xlabel('Time [ns]')
axes.spines['right'].set_visible(False)
axes.spines['top'].set_visible(False)
axes.yaxis.set_ticks_position('left')
axes.xaxis.set_ticks_position('bottom')
axes.tick_params(direction='out')
#axes.set_title('N/A')
axes.set_ylim(-20,10)
axes.set_xlim(0, 90)
cmap = plt.get_cmap('plasma')
colors = [cmap(i) for i in np.linspace(0, 1, 9)]
# Make Color Bar ------------------------------------------------------
cax = 0
divider = make_axes_locatable(axes)
cax = divider.append_axes('right', size='5%', pad=0.1)
im = axes.imshow(np.linspace(1, 8.5, 100).reshape(10, 10), cmap='plasma')
fig.colorbar(im, cax=cax)
#----------------------------------------------------------------------
for i, dist in enumerate(dz):
if i % 100 == 0:
x = i / 1000
y = dist
phval = final_pH_array[i]
axes.plot(x, y, 'k.', markersize = 4 , color = colors[int(phval)], clip_on = False)
plt.savefig('plot.pdf')
plt.show()
The results looks like this:
As you can see there is an additional color bar / color palette that I don't want on the plot but can't seem to get rid of it.
Any help with this would be great!
I think im.set_visible(False) should achieve what you want.
But maybe you should take a look at plt.scatter. scatter returns a PathCollection that you can pass to the colorbar function.