How to show axis ticks corresponding to plotted datapoints in a seaborn plot? - matplotlib

I am using seaborn to plot some values which are numerical. But the each of those numbers correspond to a textual value and I want those textual values to be displayed on the axes. Like if the numerical values progress as 0, 5, 10, ..., 30; each of those encoded numbers must be linked to a textual description. How can I do this?

Main Point:
Use:
ax = plt.gca()
ax.set_xticks([<the x components of your datapoints>]);
ax.set_yticks([<the y components of your datapoints>]);
More elaborate version below.
You can go back to matplotlib and it will do it for you.
Let's say you want to plot [0, 7, 14 ... 35] against [0, 2, 4, ... 10]. The two arrays can be created by:
stepy=7
stepx=2
[stepy*y for y in range(6)]
(returning [0, 7, 14, 21, 28, 35])
and
[stepx*x for x in range(6)]
(returning [0, 2, 4, 6, 8, 10]).
Plot these with seaborn:
sns.scatterplot([stepx*x for x in range(6)],[stepy*y for y in range(6)]).
Give current axis to matplotlib by ax = plt.gca(), finish using set_xticks and set_yticks:
ax.set_xticks([stepx*x for x in range(6)]);
ax.set_yticks([stepy*y for y in range(6)]);
The whole code together:
stepy=7
stepx=2
sns.scatterplot([stepx*x for x in range(6)],[stepy*y for y in range(6)])
ax = plt.gca()
ax.set_xticks([stepx*x for x in range(6)]);
ax.set_yticks([stepy*y for y in range(6)]);
Yielding the plot:
I changed the example in the OP because with those numbers to plot, the plots already behave as desired.

Related

Matplotlib Plot X, Y Line Plot Multiple Columns Fixed X Axis

I'm trying to plot a df with the x axis forced to 12, 1, 2 for (Dec, Jan, Feb) and I cannot see how to do this. Matplot keeps wanting to plot the x axis in the 1,2,12 order. My DF (analogs_re) partial columns for the example looks like this:
Month 2000 1995 2009 2014 1994 2003
0 12 -0.203835 0.580590 0.233124 0.490193 0.605808 0.016756
1 1 -0.947029 -1.239794 -0.977004 0.207236 0.436458 -0.501948
2 2 -0.059957 0.708626 0.111840 0.422534 1.051873 -0.149000
I need the y data plotted with x axis in 12, 1, 2 order as shown in the 'Month" column.
My code:
fig, ax = plt.subplots()
#for name, group in groups:
analogs_re.set_index('Month').plot(figsize=(10,5),grid=True)
analogs_re.plot(x='Month', y=analogs_re.columns[1:len(analogs_re.columns)])
When you set Month as the x-axis then obviously it's going to plot it in numerical order (0, 1, 2, 3...), because a sequential series does not start with 12, then 1, then 2, ...
The trick is to use the original index as x-axis, then label those ticks using the month number:
fig, ax = plt.subplots()
analogs_re.drop(columns='Month').plot(figsize=(10,5), grid=True, ax=ax)
ax.set_xticks(analogs_re.index)
ax.set_xticklabels(analogs_re["Month"])

How to show following data with colors and color bar. What will be suitable command for this? [duplicate]

I want to make a scatterplot (using matplotlib) where the points are shaded according to a third variable. I've got very close with this:
plt.scatter(w, M, c=p, marker='s')
where w and M are the data points and p is the variable I want to shade with respect to.
However I want to do it in greyscale rather than colour. Can anyone help?
There's no need to manually set the colors. Instead, specify a grayscale colormap...
import numpy as np
import matplotlib.pyplot as plt
# Generate data...
x = np.random.random(10)
y = np.random.random(10)
# Plot...
plt.scatter(x, y, c=y, s=500) # s is a size of marker
plt.gray()
plt.show()
Or, if you'd prefer a wider range of colormaps, you can also specify the cmap kwarg to scatter. To use the reversed version of any of these, just specify the "_r" version of any of them. E.g. gray_r instead of gray. There are several different grayscale colormaps pre-made (e.g. gray, gist_yarg, binary, etc).
import matplotlib.pyplot as plt
import numpy as np
# Generate data...
x = np.random.random(10)
y = np.random.random(10)
plt.scatter(x, y, c=y, s=500, cmap='gray')
plt.show()
In matplotlib grey colors can be given as a string of a numerical value between 0-1.
For example c = '0.1'
Then you can convert your third variable in a value inside this range and to use it to color your points.
In the following example I used the y position of the point as the value that determines the color:
from matplotlib import pyplot as plt
x = [1, 2, 3, 4, 5, 6, 7, 8, 9]
y = [125, 32, 54, 253, 67, 87, 233, 56, 67]
color = [str(item/255.) for item in y]
plt.scatter(x, y, s=500, c=color)
plt.show()
Sometimes you may need to plot color precisely based on the x-value case. For example, you may have a dataframe with 3 types of variables and some data points. And you want to do following,
Plot points corresponding to Physical variable 'A' in RED.
Plot points corresponding to Physical variable 'B' in BLUE.
Plot points corresponding to Physical variable 'C' in GREEN.
In this case, you may have to write to short function to map the x-values to corresponding color names as a list and then pass on that list to the plt.scatter command.
x=['A','B','B','C','A','B']
y=[15,30,25,18,22,13]
# Function to map the colors as a list from the input list of x variables
def pltcolor(lst):
cols=[]
for l in lst:
if l=='A':
cols.append('red')
elif l=='B':
cols.append('blue')
else:
cols.append('green')
return cols
# Create the colors list using the function above
cols=pltcolor(x)
plt.scatter(x=x,y=y,s=500,c=cols) #Pass on the list created by the function here
plt.grid(True)
plt.show()
A pretty straightforward solution is also this one:
fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(8,8))
p = ax.scatter(x, y, c=y, cmap='cmo.deep')
fig.colorbar(p,ax=ax,orientation='vertical',label='labelname')

Python plot_surface set Y limits to center at 0

I'm using cylindric coordinates, created a meshgrid and tried to plot using plot_surface. My full dataset doesn't get properly drawn because the scaling on the Y-axis is not correct.
I'm trying to plot the magnetic field values versus Z and P(rho) values. Z can be both negative and positive. P(rho) can only be positive.
The problem is that p (Y-axis) always starts from 0 to 10 (giving 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) whereas I'd like to have it like: 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 so that its centered at 0.
So this is my example code. I won't add the calculations for the magnetic field. These are not relevant for this issue.
fig = plt.figure()
ax = Axes3D(fig)
# Define the plane over which fields are computed.
# N must be odd to include the point (0,0).
M = 26 # No. of points along the rho axis.
N = 51 # No. of points along the z axis.
p1 = np.linspace(0, a, M)
p = np.concatenate([p1[::-1][:-1], p1]) # Make it symmetric.
z = np.linspace(-d, d, N)
p, z = np.meshgrid(p, z) # Create grid of (p,z).
# CALCULATE magnetic field bt. So assume this is done here...
bt = np.sqrt(np.power(bz, 2) + np.power(bp, 2))
ax.plot_surface(z, p, bt, cmap=plt.cm.YlGnBu_r)
plt.show()
So when making adding the line,
p = np.concatenate([p1[::-1][:-1], p1])
the dimensions are broken and plot_surface is rightfully complaining. I'd expect this line would center the 0 in the middle of the array.
Thanks.

Matplotlib: how to control the plot interval of x axis?

I'm plotting the degree of freedom against the square error,:
plt.plot([1,2,3,4], [0.5,0.6,0.9,0.85],'-')
It will produce
The problem is that ,the x ax is has 0.5 interval, and does not make sense in this context. Because there is simply no 1.5 degree of freedom.
How can I make the x axis into [1,2,3,4,], instead of [1, 1.5, 2, ...]?
Just add directly the positions and the strings you want to put in the x axis. Using your example:
import matplotlib.pyplot as plt
x = [1,2,3,4]
y = [0.5,0.6,0.9,0.85]
plt.plot(x,y,'-')
plt.xticks(list(range(1,max(x)+1)),[str(i) for i in range(1,max(x)+1)])
plt.grid()
plt.show()
, which results in:
You have to set the XTick 1 to 4, by 1 1:1:4 like below
plot([1,2,3,4], [0.5,0.6,0.9,0.85],'-');
set(gca,'XTick',1:1:4);
or
p = plot([1,2,3,4], [0.5,0.6,0.9,0.85],'-');
set(p,'XTick',1:1:4);

How should arrays for plot_surface be built?

I'm trying to understand how to build arrays for use in plot_surface (in Axes3d).
I tried to build a simple surface manipulating data of those arrays:
In [106]: x
Out[106]:
array([[0, 0],
[0, 1],
[0, 0]])
In [107]: y
Out[107]:
array([[0, 0],
[1, 1],
[0, 0]])
In [108]: z
Out[108]:
array([[0, 0],
[1, 1],
[2, 2]])
But I can't figure out how they are interpreted - for example there is nothing in z=2 on my plot.
Anybody please explain exactly which values will be taken to make point, which for line and finally surface.
For example I would like to build a surface that would connect with lines points:
[0,0,0]->[1,1,1]->[0,0,2]
[0,0,0]->[1,-1,1]->[0,0,2]
and a surface between those lines.
What should arrays for plot_surface look like to get something like this?
Understanding how the grids in plot_surface work is not easy. So first I'll give a general explanation, and then I'll explain how to convert the data in your case.
If you have an array of N x values and an array of M y values, you need to create two grids of x and y values of dimension (M,N) each. Fortunately numpy.meshgrid will help. Confused? See an example:
x = np.arange(3)
y=np.arange(1,5)
X, Y = np.meshgrid(x,y)
The element (x[i], y[j]) is accessed as (X[j,i], Y[j,i]). And its Z value is, of course, Z[j,i], which you also need to define.
Having said that, your data does produce a point of the surface in (0,0,2), as expected. In fact, there are two points at that position, coming from coordinate indices (0,0,0) and (1,1,1).
I attach the result of plotting your arrays with:
fig = plt.figure()
ax=fig.add_subplot(1,1,1, projection='3d')
surf=ax.plot_surface(X, Y, Z)
If I understand you correctly you try to interpolate a surface through a set of points. I don't think the plot_surface is the correct function for this. But correct me if I'm wrong. I think you should look for interpolation tools, probably those in scipy.interpolate. The result of the interpolation can then be plotted using plot_surface.
plot_surface is able to plot a grid (with z values) in 3D space based on x, y coordinates. The arrays of x and y are those created by numpy.meshgrid.
example of plot_surface:
import pylab as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
plt.ion()
x = np.arange(0,np.pi, 0.1)
y = x.copy()
z = np.sin(x).repeat(32).reshape(32,32)
X, Y = np.meshgrid(x,y)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(X,Y,z, cmap=plt.cm.jet, cstride=1, rstride=1)