Pyplot polar surface plot - matplotlib

I am new in pyplot.
I have a Cartesian surface plot:
# offset and omega are arrays
Z = my_function(omega,offset) # my_function give and arrays of omega.size*offset.size
fig, ax = plt.subplots(1)
p = ax.pcolor(offset,omega,Z.T,cmap=cm.jet,vmin=abs(Z).min(),vmax=abs(Z).max())
cb = fig.colorbar(p,ax=ax)
Maybe there is a more simple way to plot a surface but that the way I've found on the internet.
Well, now I want to plot my_function as a surface using polar coordinate, I've tried this:
ax2 = plt.subplot(111, polar=True)
p2 = ax2.pcolor(offset,omega,Z.T,cmap=cm.jet,vmin=abs(Z).min(),vmax=abs(Z).max())
It kind of work, I have a surface plot but it does not take into account the limits of Y.
For example if Y is defined between -15 and 15° I only want my function to be plotted and shown between those angles and not 0 to 360° as my example is doing.
How can I do that ?
I thank you in advance for any answer.

Related

How to entend the area/boudaries that shows the data from a Axes3D with matplolib when using the set_box_aspect zoom

I'm trying to zoom in a 3D plot. I'm using the ax.set_box_aspect() fonction. When doing so, the axis are zoomed in, they appear bigger, but the area where the data can be seen stay at the same size as before (the plot are not using the total available space).
The aim in the end is to have two axis, the first one 3d, the other one 2d. I would have wanted the first plot to take all the space available at the top half of the figure.
Here is the code before the Zoom
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
#---- generate data
nn = 100
X = np.random.randn(nn)*20 + 0
Y = np.random.randn(nn)*50 + 30
Z = np.random.randn(nn)*10 + -5
#---- check aspect ratio
asx, asy, asz = np.ptp(X), np.ptp(Y), np.ptp(Z)
fig = plt.figure(figsize=(15,15))
ax = fig.add_subplot(211, projection='3d')
#---- set box aspect ratio
ax.set_box_aspect((asx,asy,asz))
scat = ax.scatter(X, Y, Z, c=X+Y+Z, s=500, alpha=0.8)
ax.set_xlabel('X-axis'); ax.set_ylabel('Y-axis'); ax.set_zlabel('Z-axis')
ax = fig.add_subplot(212)
plt.show()
Before using the zoom
And now when I zoom in, the scatter is limitted in a square frame :
ax.set_box_aspect((asx,asy,asz), zoom = 2 )
After using the zoom
(The data used for the plot doesn't matter here, it is just to showcase my issue.)
I tried changing the axis limit with set_xlim3d or set_xlim, but in either case, the result is the same.
It seems like the showing area (I can't find the right word for it) stays a square no matter what.
I didn't find any usefull information on that matter online, (maybe from the lack of vocabulary to describe my problem).

Need help displaying 4D data in matplotlib 3D scatterplot properly

Hey so I'm an undergraduate working in an imaging lab and I have a 3D numpy array that has values from 0-9 to indicate concentration in a 3D space. I'm trying to plot these values in a scatterplot with a colormap to indicate the value between 0-9. The array is 256 x 256 x 48, so I feel like the size of it is making it difficult for me to plot the array in a meaningful way.
I've attached a picture of what it looks like right now. As you can see the concentration looks very "faded" even for very high values and I'm not entirely sure why. Here is the code I'm using to generate the plot:
current heatmap
fig = plt.figure()
x, y, z = np.meshgrid(range(256), range(256), range(48))
col = sum_array.flatten()
ax = fig.add_subplot(111, projection = '3d')
sc = ax.scatter(x, y, z, c = col, cmap='Reds',
linewidths=.01, s=.03, vmin=0, vmax=9,
marker='.', alpha=1)
plt.colorbar(sc)
plt.show()
If anyone can help me display the colors in a more bright/concentrated manner so the heat map is visually useful, I'd really appreciate it. Thank you!

Pandas: How can I plot with separate y-axis, but still control the order?

I am trying to plot multiple time series in one plot. The scales are different, so they need separate y-axis, and I want a specific time series to have its y-axis on the right. I also want that time series to be behind the others. But I find that when I use secondary_y=True, this time series is always brought to the front, even if the code to plot it comes before the others. How can I control the order of the plots when using secondary_y=True (or is there an alternative)?
Furthermore, when I use secondary_y=True the y-axis on the left no longer adapts to appropriate values. Is there a fixed for this?
# imports
import numpy as np
import matplotlib.pyplot as plt
# dummy data
lenx = 1000
x = range(lenx)
np.random.seed(4)
y1 = np.random.randn(lenx)
y1 = pd.Series(y1, index=x)
y2 = 50.0 + y1.cumsum()
# plot time series.
# use ax to make Pandas plot them in the same plot.
ax = y2.plot.area(secondary_y=True)
y1.plot(ax=ax)
So what I would like is to have the blue area plot behind the green time series, and to have the left y-axis take appropriate values for the green time series:
https://i.stack.imgur.com/6QzPV.png
Perhaps something like the following using matplotlib.axes.Axes.twinx instead of using secondary_y, and then following the approach in this answer to move the twinned axis to the background:
# plot time series.
fig, ax = plt.subplots()
y1.plot(ax=ax, color='green')
ax.set_zorder(10)
ax.patch.set_visible(False)
ax1 = ax.twinx()
y2.plot.area(ax=ax1, color='blue')

3d plot with multiple lines showing the projection on the xy plane

I was wondering how to have a 3d plot with multiple lines showing the projection on the xy plane by means of something like fill_between but in 3D. I have here a sample code.
fig, ax = plt.subplots(figsize=(12,8),subplot_kw={'projection': '3d'})
for i in np.arange(0.0,1,0.1):
x1=np.arange(0,1-i+0.01,0.01)
y1=1.0-i-x1
def z_func(x,y,z):
return x+y**2+0.5*z #can be any fn
coordinates3= [[i,j,1-i-j] for j in np.arange(0,1-i+0.01,0.01)]
z1=np.array([z_func(*k) for k in coordinates3])
ax.plot(x1,y1,z1)
ax.view_init(azim=10,elev=20)
plt.show()
I'd like to have each line 'projected' on the xy plane, with a shaded filling in between the curve and its projection. Anybody knows a quick way?
After the suggestion in the comments of #ImportanceOfBeingErnest, I was able to write a solution. I came up with this:
fig, ax = plt.subplots(figsize=(12,8),subplot_kw={'projection': '3d'})
prop_cycle = plt.rcParams['axes.prop_cycle']
colors = prop_cycle.by_key()['color']
for color,i in enumerate(np.arange(0.0,1,0.1)):
x1=np.arange(0,1-i+0.01,0.01)
y1=1.0-i-x1
def z_func(x,y,z):
return x+y**2+0.5*z #can be any fn
coordinates3= [[i,j,1-i-j] for j in np.arange(0,1-i+0.01,0.01)]
z1=np.array([z_func(*k) for k in coordinates3])
verts=[[(k[1],k[2],z_func(*k)) for k in coordinates3]]
verts[0].insert(0,(coordinates3[0][1],coordinates3[0][2],0))
verts[0].insert(0,(coordinates3[-1][1],coordinates3[-1][2],0))
poly = Poly3DCollection(verts,color=colors[color])
poly.set_alpha(0.2)
ax.add_collection(poly)
ax.plot(x1,y1,z1,linewidth=10)
ax.view_init(azim=10,elev=20)
plt.show()
One thing that puzzles me is that the shade doesn't get the color of the line and that I had to supply it myself. If you remove the color=colors[color] in the Poly3DCollection you always get blue shades, whereas the lines automatically get the different colors, as one can see in the question. Anybody knows a reason for this?

Can I move about the axes in a matplotilb subplot?

Once I have created a system of subplots in a figure with
fig, ((ax1, ax2)) = plt.subplots(1, 2)
can I play around with the position of ax2, for example, by shifting it a little bit to the right or the left?
In other words, can I customize the position of an axes object in a figure after it has been created as a subplot element?
If so, how could I code this?
Thanks for thinking along
You can use commands get_position and set_position like in this example:
import matplotlib.pyplot as plt
fig, ((ax1, ax2)) = plt.subplots(1, 2)
box = ax1.get_position()
box.x0 = box.x0 + 0.05
box.x1 = box.x1 + 0.05
ax1.set_position(box)
plt.show()
which results in this:
You'll notice I've used attributes x0 and x1 (first and last X coordinate of the box) to shift the plot in 0.05 in that axis. The logic applies to y also.
In fact should the shift be to big and the boxes will overlap (like in this image with a shift of 0.2).