(Seaborn)making tick figures larger - seaborn

My code used 'Paper' style as below.By using set_theme(), making larger or smaller overall plots is possible.
My goal is to make tick figures 1.00, 1.25 .. at the vertical axis lager. How to modify my code below?
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
data=pd.DataFrame({'val':[1, 1, 2, 2.1, 2, 2.5, 2.3],'site':['a','a','a','b','b','b','b'],
'X2':[4, 5 ,6 ,10, 10, 11, 11], 'X3':[100,100,200,200,200,300,300],
'applydate':[1101,1102,1201,1202,1204,1204,1204],
'X1':['b','b','h','b','b','h','h'] })
def my_scatter(x,y, **kwargs):
plt.scatter(x=x, y=y,**kwargs)
mx = np.mean(x);my= np.mean(y);
sns.set_context("paper") # the 'paper'style
g = sns.FacetGrid(data,col='site',height=3)
g.map(my_scatter, "X2", "val",s=100, alpha=.5)
g.add_legend()

You can access the grid axes with the axes attribute (see doc) and use the set_yticklabels method (link):
g.axes[0, 0].set_yticklabels(g.axes[0, 0].get_yticklabels(), fontsize=14)

Related

How to add z-axis as color bar in 2d histogram

The scattered data is not showing up on an exact scale. I want to show time vs radius.
Plot
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm
r = np.array([12.6, 10.5, 9.2, 5.1, 11.2, 4])
time = np.array([6.7, 6.7, 6.8, 5.6, 17.7, 17.7])
col = np.array([1.84e-6,6.00e-9,6.49e-8,2.44e-10,2.78e-9, 1.65e-7])
fig=plt.figure()
ax=fig.add_subplot(111, polar=True)
pc=ax.scatter(time, r, c=col, cmap='turbo', norm=LogNorm(vmin=col.min(), vmax=col.max()))
fig.colorbar(pc)
# Set the circumference labels
ax.set_xticks(np.linspace(0, 2*np.pi, 24, endpoint=False))
ax.set_xticklabels(range(24))
# Make the labels go clockwise
ax.set_theta_direction(-1)
# Place 0 at the top
ax.set_theta_offset(np.pi/2.0)
# display the polar plot
plt.show()

Discrete logarithmic colorbar in matplotlib

I want to create a pcolormesh plot with a discrete logarithmic colorbar. Some resolution is lost, but the matching between colors and values seems to be easier (at least for me) if the colormap is discrete.
The code snippet below produces a continuous log colormap with the preferred value range. How can I make it discrete? Here I found how to create a discrete linear colormap, but I couldn't extend it to log scale.
plt.pcolormesh(X,Y,Z,norm=mcolors.LogNorm(vmin=0.01, vmax=100.))
plt.colorbar()
fig = matplotlib.pyplot.gcf()
fig.set_size_inches(4*2.5, 3*2.5)
plt.xlabel("X", horizontalalignment='right', x=1.0)
plt.ylabel("Y", horizontalalignment='right', y=1.0)
plt.tight_layout()
I've managed to create a logarithmic colorbar with even spacing. However, I couldn't figure out how to create a discrete logarithmic colorbar with a logarithmic spacing of the colorbar. I hope this helps!
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
X = np.arange(0, 50)
Y = np.arange(0, 50)
Z = np.random.rand(50, 50)*10
bounds = [0, 0.1, 0.2, 0.3, 0.4, 0.5, .7, .8, .9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
num_c = len(bounds)
cmap = mpl.colormaps['viridis'].resampled(num_c)
norm = mpl.colors.BoundaryNorm(bounds, cmap.N)
fig, ax = plt.subplots()
fig.set_size_inches(4*2.5, 3*2.5)
ax.pcolormesh(X, Y, Z, norm=norm, cmap=cmap)
plt.xlabel("X", horizontalalignment='right', x=1.0)
plt.ylabel("Y", horizontalalignment='right', y=1.0)
fig.colorbar(mpl.cm.ScalarMappable(cmap=cmap, norm=norm))
plt.tight_layout()

Pyorch: Applying a batch of filters (kernels) on one single picture using conv2d

I have a batch of filters, i.e., w, whose size is torch.Size([64, 3, 7, 7]) as follows:
Also, I have a picture p from Imagenet as follows:
How can I apply the filters to the picture and get a grid of 64x64 where each cell contains the same picture on which a different filter has been applied? I would like to make the grid using torchvision.utils.make_grid but do not know how?
My try
y = F.conv2d(p, w)
The size of y is torch.Size([1, 64, 250, 250]) which does not make sense to me.
Each of your filters has size [3, 7, 7], so they would take an RGB image and produce a single channel output which is stacked in the channel dimension so your output [1, 64, H, W] makes perfect sense.
To visualize these filters:
import torch
import torch.nn as nn
import torch.nn.functional as F
import torchvision
from torchvision import transforms
from PIL import Image
import matplotlib.pyplot as plt
torch.random.manual_seed(42)
transform = transforms.Compose([transforms.ToTensor()])
img = transform(Image.open('dog.jpg')).unsqueeze(0)
print('Image size: ', img.shape)
filters = torch.randn(64, 3, 7, 7)
out = F.conv2d(img, filters)
print('Output size: ', out.shape)
list_of_images = [out[:,i] for i in range(64)]
grid = torchvision.utils.make_grid(list_of_images, normalize=True)
plt.imshow(grid.numpy().transpose(1,2,0))
plt.show()
This is a more accurate representation of the output. It is however not very attractive -- we can obtain the colored version by processing each color channel independently. (The grayscale version can be obtained by summing over the color channels)
color_out = []
for i in range(3):
color_out.append(F.conv2d(img[:,i:i+1], filters[:,i:i+1]))
out = torch.stack(color_out, 2)
print('Output size: ', out.shape)
list_of_images = [out[0,i] for i in range(64)]
print(list_of_images[0].shape)
grid = torchvision.utils.make_grid(list_of_images, normalize=True)
plt.imshow(grid.numpy().transpose(1,2,0))
plt.show()

Best learning algorithms concentric and not linearly separable data

Below are two scatter plots. The first one is for data points that have values of x and y, and I would like to know if there is a clustering algorithm that will automatically recognize that there are two clusters. They are concentric and not linearly separable. K-means is not right for several reasons. The other plot is similar but it has x, y and color values, and I would like to know what learning algorithm would be best at classifying or predicting the correct color from the values of x and y.
I got good classifier results for this problem using the sklearn MLPClassifier algorithm. Here is the scatter and contour plots:
Detailed code at: https://www.linkedin.com/pulse/couple-scikit-learn-classifiers-peter-thorsteinson. The simplified code below shows how it works:
import math
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.neural_network import MLPClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report, confusion_matrix
# Generate the artificial data set and display the resulting scatter plot
x = []
y = []
z = []
for i in range(500):
rand = np.random.uniform(0.0, 2*math.pi)
randx = np.random.normal(0.0, 30.0)
randy = np.random.normal(0.0, 30.0)
if np.random.random() > 0.5:
z.append(0)
x.append(100*math.cos(rand) + randx)
y.append(100*math.sin(rand) + randy)
else:
z.append(1)
x.append(300*math.cos(rand) + randx)
y.append(300*math.sin(rand) + randy)
plt.axis('equal')
plt.axis([-500, 500, -500, 500])
plt.scatter(x, y, c=z)
plt.show()
# Run the MLPClassifier algorithm on the training data
XY = pd.DataFrame({'x': x, 'y': y})
print(XY.head())
Z = pd.DataFrame({'z': z})
print(Z.head())
XY_train, XY_test, Z_train, Z_test = train_test_split(XY, Z, test_size = 0.20)
mlp = MLPClassifier(hidden_layer_sizes=(10, 10, 10), max_iter=1000)
mlp.fit(XY_train, Z_train.values.ravel())
# Make predictions on the test data and display resulting scatter plot
predictions = mlp.predict(XY_test)
print(confusion_matrix(Z_test,predictions))
print(classification_report(Z_test,predictions))
plt.axis('equal')
plt.axis([-500, 500, -500, 500])
plt.scatter(XY_test.x, XY_test.y, c=predictions)
plt.show()

Non-linear axes for imshow in matplotlib

I am generating 2D arrays on log-spaced axes (for instance, the x pixel coordinates are generated using logspace(log10(0.95), log10(2.08), n).
I want to display the image using a plain old imshow, in its native resolution and scaling (I don't need to stretch it; the data itself is already log scaled), but I want to add ticks, labels, lines that are in the correct place on the log axes. How do I do this?
Ideally I could just use commands line axvline(1.5) and the line would be in the correct place (58% from the left), but if the only way is to manually translate between logscale coordinates and image coordinates, that's ok, too.
For linear axes, using extents= in the call to imshow does what I want, but I don't see a way to do the same thing with a log axis.
Example:
from matplotlib.colors import LogNorm
x = logspace(log10(10), log10(1000), 5)
imshow(vstack((x,x)), extent=[10, 1000, 0, 100], cmap='gray', norm=LogNorm(), interpolation='nearest')
axvline(100, color='red')
This example does not work, because extent= only applies to linear scales, so when you do axvline at 100, it does not appear in the center. I'd like the x axis to show 10, 100, 1000, and axvline(100) to put a line in the center at the 100 point, while the pixels remain equally spaced.
In my view, it is better to use pcolor and regular (non-converted) x and y values. pcolor gives you more flexibility and regular x and y axis are less confusing.
import pylab as plt
import numpy as np
from matplotlib.colors import LogNorm
from matplotlib.ticker import LogFormatterMathtext
x=np.logspace(1, 3, 6)
y=np.logspace(0, 2,3)
X,Y=np.meshgrid(x,y)
z = np.logspace(np.log10(10), np.log10(1000), 5)
Z=np.vstack((z,z))
im = plt.pcolor(X,Y,Z, cmap='gray', norm=LogNorm())
plt.axvline(100, color='red')
plt.xscale('log')
plt.yscale('log')
plt.colorbar(im, orientation='horizontal',format=LogFormatterMathtext())
plt.show()
As pcolor is slow, a faster solution is to use pcolormesh instead.
im = plt.pcolormesh(X,Y,Z, cmap='gray', norm=LogNorm())
Actually, it works fine. I'm confused.
Previously I was getting errors about "Images are not supported on non-linear axes" which is why I asked this question. But now when I try it, it works:
import matplotlib.pyplot as plt
import numpy as np
x = np.logspace(1, 3, 5)
y = np.linspace(0, 2, 3)
z = np.linspace(0, 1, 4)
Z = np.vstack((z, z))
plt.imshow(Z, extent=[10, 1000, 0, 1], cmap='gray')
plt.xscale('log')
plt.axvline(100, color='red')
plt.show()
This is better than pcolor() and pcolormesh() because
it's not insanely slow and
is interpolated nicely without misleading artifacts when the image is not shown at native resolution.
To display imshow with abscisse log scale:
ax = fig.add_subplot(nrow, ncol, i+1)
ax.set_xscale('log')

Resources