Polar axis in matplotlib - matplotlib

I'm trying to set the r-axis in a polar plot using Matplotlib. At this time, the best result I got is the following one :
I would like to modify three things :
draw a thicker line for the axis with labels,
add ticks to others r-axis,
move the legend outside of the plot.
I expect something like that :
Thanks for your help.
JD
'''
r = [0.07109986, 0.07186792, 0.07128804, 0.07093468, 0.11061314,\
0.11480423, 0.09913993, 0.13417775, 0.07485087, 0.07140557,\
0.08117919, 0.1235301 , 0.07109986]
theta = 2.0*np.pi*np.arange(len(r))/(len(r)-1)
titles = ['$a$','$\\alpha$','$b^{1}$','$b^{2}$',\
'$c^{1}_{1}$','$c^{1}_{2}$','$c^{1}_{3}$','$c^{1}_{4}$',\
'$c^{2}_{1}$','$c^{2}_{2}$','$c^{2}_{3}$','$c^{2}_{4}$']
fig = plt.figure()
ax = fig.add_subplot(111,polar='True')
ax.plot(theta,r)
ax.spines['polar'].set_visible(False)
ax.set_theta_zero_location(loc='N')
ax.set_xticks(np.arange(0,2.0*np.pi,2.0*np.pi/len(titles)))
ax.set_xticklabels(titles)
ax.yaxis.grid(False)
ax.set_rlabel_position(0)
plt.tick_params(axis='y',labelsize=12)
plt.show()
'''

Related

Integration of a piecewise regression in a subplot

I have the following code of a piecewise_regression:
data = data_heatmap_2017.copy()
data = data[['tre200h0_2017','Leistung:']].dropna()
xx = data['tre200h0_2017'].values.tolist()
yy = data['Leistung:'].values.tolist()
pw_fit = piecewise_regression.Fit(xx, yy, n_breakpoints=1)
pw_fit.summary()
If I do a single plot with the code below, I get a diagram piecewise_regression:
# Plot the data, fit, breakpoints and confidence intervals
pw_fit.plot_data(s=0.1)
# Pass in standard matplotlib keywords to control any of the plots
pw_fit.plot_fit(color="red", linewidth=2)
pw_fit.plot_breakpoints()
pw_fit.plot_breakpoint_confidence_intervals()
plt.xlabel("Lufttemperatur [°C]")
plt.ylabel("Leistung [kW]")
plt.show()
plt.close()
Now I would like to integrate the diagram piecewise regression within this subplots on position ax10:
fig, axs = plt.subplots(2, 5, figsize=(60,50), dpi=(100))
ax10 = axs[1,0]
ax10.set_title('2017, Signatur, Zähler: ' + Zaehler)
ax10.pw_fit.plot_data(s=0.1)
ax10.pw_fit.plot_fit(color="red", linewidth=2)
ax10.set_xlabel('Lufttemperatur [°C]')
ax10.set_ylabel('Leistung [kW]')
ax10.axis([-15, 35, min_Power, max_Power])
plt.show()
plt.close()
unfortunately the lines
ax10.pw_fit.plot_data(s=0.1)
ax10.pw_fit.plot_fit(color="red", linewidth=2)
do not work with the prefix ax10. I get an AttributeError 'AxesSubplot' object has no attribute 'pw_fit'. Any idea how to solve this? Thank you!

Equispacing of error bars in semilogx plot

When I plot using errorbar of matplotlib, I use the errorevery option to avoid crowding the error bars. However, if x-axis is set to log scale, then the error bars do not look equispaced anymore.
N = 40
xdata = np.arange(N)+1
ydata = (xdata/N)**2
fig, ax = plt.subplots()
ax.errorbar(xdata, ydata, yerr=0.1*np.ones(N), errorevery=4, elinewidth=0.5, ecolor='r')
ax.set_xscale("log")
Is there a way to keep the visual equispacing on log scale, which might look like the following (drawn roughly):

How to generate several legends for single plot matplotlib

I was making a plot of f(x,y,z) and wanted this to be displayed in a 2D-plane. To avoid cluttering my legend i decided to have different linestyles for y, different colors for z and place the two in two separate legends. I couldn't find out how to do this even after a lot of digging, so I'm posting the solution i came up with here :) If anyone has more elegant solutions I'm all ears :)
Basically the solution was to make three plots, set two of them to have size (0,0) and place those two where i wanted the legends. It feels like an ugly way to do it, but it gave a nice plot and i didn't find any other way :) The resulting plot looks like this:
def plot_alt(style = 'log'):
cmap = cm.get_cmap('inferno')
color_scale = 1.2 #Variable to get colors from a certain part of the colormap
#Making grids for delta T and average concentration
D_T_axis = -np.logspace(np.log10(400), np.log10(1), 7)
C_bar_list = np.linspace(5,10,4)
ST_list = np.logspace(-3,-1,100)
# f(x,y,z)
DC_func = lambda C_bar, ST, DT: 2*C_bar * (1 - np.exp(ST*DT))/(1 + np.exp(ST*DT))
#Some different linestyles
styles = ['-', '--', '-.', ':']
fig, ax = plt.subplots(1,3, figsize = (10,5))
plt.sca(ax[0])
for i, C_bar in enumerate(C_bar_list): #See plot_c_rel_av_DT() for 'enumerate'
for j, DT in enumerate(D_T_axis):
plt.plot(ST_list, DC_func(C_bar, ST_list, DT), color = cmap(np.log10(-DT)/(color_scale*np.log10(-D_T_axis[0]))),
linestyle = styles[i])
# Generating separate legends by plotting lines in the two other subplots
# Basically: to get two separate legends i make two plots, place them where i want the legends
# and set their size to zero, then display their legends.
plt.sca(ax[1]) #Set current axes to ax[1]
for i, C_bar in enumerate(C_bar_list):
# Plotting the different linestyles
plt.plot(C_bar_list, linestyle = styles[i], color = 'black', label = str(round(C_bar, 2)))
plt.sca(ax[2])
for DT in D_T_axis:
#plotting the different colors
plt.plot(D_T_axis, color = cmap(np.log10(-DT)/(color_scale*np.log10(-D_T_axis[0]))), label = str(int(-DT)))
#Placing legend
#This is where i move and scale the three plots to make one plot and two legends
box0 = ax[0].get_position() #box0 is an object that contains the position and dimentions of the ax[0] subplot
box2 = ax[2].get_position()
ax[0].set_position([box0.x0, box0.y0, box2.x0 + 0.4*box2.width, box0.height])
box0 = ax[0].get_position()
ax[1].set_position([box0.x0 + box0.width, box0.y0 + box0.height + 0.015, 0,0])
ax[1].set_axis_off()
ax[2].set_position([box0.x0 + box0.width ,box0.y0 + box0.height - 0.25, 0,0])
ax[2].set_axis_off()
#Displaying plot
plt.sca(ax[0])
plt.xscale('log')
plt.xlim(0.001, 0.1)
plt.ylim(0, 5)
plt.xlabel(r'$S_T$')
plt.ylabel(r'$\Delta C$')
ax[1].legend(title = r'$\langle c \rangle$ [mol/L]',
bbox_to_anchor = (1,1), loc = 'upper left')
ax[2].legend(title = r'$-\Delta T$ [K]', bbox_to_anchor = (1,1), loc = 'upper left')
#Suptitle is the title of the figure. You can also have titles for the individual subplots
plt.suptitle('Steady state concentration gradient as a function of Soret-coefficient\n'
'for different temperature gradients and total concentrations')

Polar plot in Matplotlib using contourf plots incorrect range

I'm plotting some hydrodynamical simulation data run in spherical coordinates and sometimes prefer to use contourf over pcolormesh because it looks nice and smooth instead of pixelated. However, I notice that contourf always extends my data to r=0 in a polar plot, yet my data never includes r=0. I have reproduced this issue with the simple example below:
from pylab import *
fig = figure(figsize=(6, 6))
ax = fig.add_subplot(111,projection='polar')
# generate some data
Nt,Nr = 150,150
r_axis = np.linspace(0.5,1.,Nr)
t_axis = np.linspace(0.,0.5*np.pi,Nt)
r_grid, t_grid = np.meshgrid(r_axis,t_axis)
data = np.zeros((Nt,Nr))
sin_theta = np.sin(t_axis)
for i in range(Nr):
data[:,i] = sin_theta
if 1: # polar plot using contourf - plots incorrectly from r = 0
scale = np.linspace(0.,1.,100)
polar = ax.contourf(t_grid,r_grid,data,scale,cmap='Spectral')
else: # correctly plots the data
polar = ax.pcolormesh(t_grid,r_grid,data,cmap='Spectral')
show()
Is there a quick fix? Thanks
One can set the axes limits. The radial scale is set as y, therefore
ax.set_ylim(0,1)
will set the origin to 0.

Imshow subplots share colorbar using AxesGrid. How to plot a grid and set number of ticks

My Program plots three subplot using the same colorbar. Here is the code:
fig=pl.figure()
grid = AxesGrid(fig, 111,nrows_ncols=(3,1),
axes_pad = 0.2,
share_all=True,
label_mode = "L",
cbar_location = "right",
cbar_mode="single",
cbar_size='1%'
)
im = grid[0].imshow(np.random.random((10,50)))
grid.cbar_axes[0].colorbar(im)
im = grid[1].imshow(np.random.random((10,50)))
im = grid[2].imshow(np.random.random((10,50)))
pl.show()
This delivers the following picture:
No I want first to set the number of ticks. E.g. 3 ticks on the y-axis and 10 on the x-axis. Furthermore I want to plot a grid into the picture. But my normal coding works only if I don't use AxisGrid:
fig=pl.figure()
im = imshow(np.random.random((10,50)))
pl.locator_params(axis='x',nbins=20)
pl.locator_params(axis='y',nbins=3)
pl.grid()
pl.show()
What can I do to plot the grid into my subplots and change the number of ticks?
try this:
im = grid[0].imshow(np.random.random((10,50)))
ax = im.get_axes( )
ax.grid( 'on' )
ax.locator_params(axis='x',nbins=20)
ax.locator_params(axis='y',nbins=3)