Multiple density plot with plotly in R - python

I really like this python example:https://plot.ly/python/distplot/ scroll to Plot Multiple Datasets. I would expect the exact same thing is available for R, but it's not documented. Does this mean it's not possible? I came across this example https://community.plot.ly/t/r-plotly-overlay-density-histogram/640/4 which I find far less nice.
This doesn't work but would give an idea about the data I use.
# Add histogram data
x1 = data.table(a=rnorm(n = 200,mean = 0,sd = .1), by='Group1')
x2 = data.table(a=rnorm(n = 200,mean = 1,sd = .15), by='Group2')
x3 = data.table(a=rnorm(n = 200,mean = 2,sd = .2), by='Group3')
x4 = data.table(a=rnorm(n = 200,mean = 3,sd = .25), by='Group4')
agg <- rbind(x1,x2,x3,x4)
plot_ly(data = agg, type = "histogram",histnorm, name = "Histogram",group_by='by')
plot_ly(data = agg, type = "density",histnorm, name = "Density",group_by='by')

I'm not entirely sure which critical element you are missing in R, but here is a plotly-based density plus rug plot example based on your sample data.
This is the static ggplot version.
require(ggplot2);
gg <- ggplot(agg, aes(x = a, colour = by)) + geom_density() + geom_rug();
And the interactive ggplotlyed version including screenshot.
require(plotly);
ggplotly(gg);
You can also add a histogram with e.g.
gg + geom_histogram(aes(y = ..density.., fill = by), alpha = 0.2, bins = 50)

Related

Jupyter noterbook How to show percentage on bar graph for this code?

I want to show the percentage on the bar graph from the code below, how do I do it?
results = pd.Series([accu_dt , accu_svm, accu_rf, accu_lg, accu_knn, accu_nb ])
names = ['Decision Tree','SVm','Random Forest','Logistic Regression','KNN','Naive Bayes']
ax = results.plot(kind = 'bar',figsize=(13,7),color=['black','gray','brown','blue','pink','green'])
ax.set_title('Comparision of Models',fontsize=15)
ax.set_yticks([0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9])
ax.set_xticklabels(names ,fontsize=15,rotation = 45)
ax.set_xlabel("Models",fontsize=15)
ax.set_ylabel("Accuracy",fontsize=15)
Is this your expected output?
If so, credit to Chris Adams for his answer.
I predefined the values for accu_dt , accu_svm, accu_rf, accu_lg, accu_knn, accu_nb as such:
accu_dt = [0.90,0.92,0.91,0.95,0.99,0.95,0.90]
accu_svm = [0.89,0.92,0.95,0.98,0.97,0.89,0.95]
accu_rf = [0.98,0.99,0.97,0.96,0.98,0.99,0.95]
accu_lg = [0.79,0.77,0.90,0.85,0.83,0.80,0.78]
accu_knn = [0.85,0.85,0.84,0.89,0.83,0.81,0.80]
accu_nb = [0.85,0.84,0.83,0.81,0.85,0.85,0.85]
I didn't change much of your code except the width = 0.7 and the figsize=(30,7) to make the numbers more readable. Noticed that I added loop at the bottom of your code
ax = results.plot(kind = 'bar',figsize=(30,7),color=['black','gray','brown','blue','pink','green'],width = 0.7)
ax.set_title('Comparision of Models',fontsize=15)
ax.set_yticks([0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9])
ax.set_xticklabels(names ,fontsize=15,rotation = 45)
ax.set_xlabel("Models",fontsize=15)
ax.set_ylabel("Accuracy",fontsize=15)
# Newly Added Loop
for p in ax.patches:
width = p.get_width()
height = p.get_height()
x, y = p.get_xy()
ax.annotate(f'{height:.0%}', (x + width/2, y + height*1.02), ha='center')
Basically what the code does in simple term:
Getting the heights, width and (x,y) coordinate of the bars
Set the annotation at designated (x,y) coordinate
Set the VALUE of the annotation equals the height of the bar (the '.0%' means percentage with zero decimal place)

How to set widgets to link to array for jupyternotebooks

I am trying to set an interactive notebook up that plots some interpolated GPS data. I have the plotting working by itself, but I am trying to use the ipython widgets to make it more interactive for others.
Currently, my plotting looks like this
def create_grid(array,spacing=.01):
'''
creates evenly spaced grid from the min and max of an array
'''
grid = np.arange(np.amin(array), np.amax(array),spacing)
return grid
def interpolate(x, y, z, grid_spacing = .01, model='spherical',returngrid = False):
'''Interpolates z value and uses create_grid to create a grid of values based on min and max of x and y'''
grid_x = create_grid(x,spacing = grid_spacing)
grid_y = create_grid(y, spacing = grid_spacing)
OK = OrdinaryKriging(x, y, z, variogram_model=model, verbose = False,\
enable_plotting=False, nlags = 20)
z1, ss1 = OK.execute('grid', grid_x,grid_y,mask = False)
print('Interpolation Complete')
vals=np.ma.getdata(z1)
sigma = np.ma.getdata(ss1)
if returngrid == False:
return vals,sigma
else:
return vals, sigma, grid_x, grid_y
mesh_x, mesh_y = np.meshgrid(grid_x,grid_y)
plot = plt.scatter(mesh_x, mesh_y, c = z1, cmap = cm.hsv)
cb = plt.colorbar(plot)
cb.set_label('Northing Change')
plt.show()
'''
This works currently, but I am trying to set up a widget to change the variogram model in the kriging interpolation, as well as change the field to be interpolated.
Currently, to do that I have:
def update_plot(zfield,variogram):
plt.clf()
z1, ss1, grid_x,grid_y =interpolate(lon,lat,zfield,returngrid= True,model=variogram)
mesh_x, mesh_y = np.meshgrid(grid_x,grid_y)
plot = plt.scatter(mesh_x, mesh_y, c = z1, cmap = cm.hsv)
cb = plot.colorbar(plot)
cb.set_label('Interpolated Value')
variogram = widgets.Dropdown(options = ['linear', 'power', 'gaussian', 'spherical', 'exponential', 'hole-effect'],
value = 'spherical', description = "Variogram model for interpolation")
zfield = widgets.Dropdown(options = {'Delta N':delta_n, 'Delta E': delta_e,'Delta V':delta_v},value = 'Delta N',
description = 'Interpolated value')
widgets.interactive(update_plot, variogram = variogram,zfield =zfield)
Which brings up the error
TraitError: Invalid selection: value not found
the values delta_n, delta_e and delta_v are numpy arrays. I have tried looking at documentation but it is not as detailed as something like matplotlibs documentation or something so I feel like I am kind of flying blind here.
Thank you
In this line, you specify the possible values of the Dropdown as:
zfield = widgets.Dropdown(options = {'Delta N':delta_n, 'Delta E': delta_e,'Delta V':delta_v}
When a mapping is used, the values of the dict are interpreted as the possible options. So value = 'Delta N' causes an error as this is not one of the possible values of the Dropdown (although it is one of the keys in the mapping dict). I believe you want value = delta_n instead.

Creating a 2D Gaussian random field from a given 2D variance

I've been trying to create a 2D map of blobs of matter (Gaussian random field) using a variance I have calculated. This variance is a 2D array. I have tried using numpy.random.normal since it allows for a 2D input of the variance, but it doesn't really create a map with the trend I expect from the input parameters. One of the important input constants lambda_c should manifest itself as the physical size (diameter) of the blobs. However, when I change my lambda_c, the size of the blobs does not change if at all. For example, if I set lambda_c = 40 parsecs, the map needs blobs that are 40 parsecs in diameter. A MWE to produce the map using my variance:
import numpy as np
import random
import matplotlib.pyplot as plt
from matplotlib.pyplot import show, plot
import scipy.integrate as integrate
from scipy.interpolate import RectBivariateSpline
n = 300
c = 3e8
G = 6.67e-11
M_sun = 1.989e30
pc = 3.086e16 # parsec
Dds = 1097.07889283e6*pc
Ds = 1726.62069147e6*pc
Dd = 1259e6*pc
FOV_arcsec_original = 5.
FOV_arcmin = FOV_arcsec_original/60.
pix2rad = ((FOV_arcmin/60.)/float(n))*np.pi/180.
rad2pix = 1./pix2rad
x_pix = np.linspace(-FOV_arcsec_original/2/pix2rad/180.*np.pi/3600.,FOV_arcsec_original/2/pix2rad/180.*np.pi/3600.,n)
y_pix = np.linspace(-FOV_arcsec_original/2/pix2rad/180.*np.pi/3600.,FOV_arcsec_original/2/pix2rad/180.*np.pi/3600.,n)
X_pix,Y_pix = np.meshgrid(x_pix,y_pix)
conc = 10.
M = 1e13*M_sun
r_s = 18*1e3*pc
lambda_c = 40*pc ### The important parameter that doesn't seem to manifest itself in the map when changed
rho_s = M/((4*np.pi*r_s**3)*(np.log(1+conc) - (conc/(1+conc))))
sigma_crit = (c**2*Ds)/(4*np.pi*G*Dd*Dds)
k_s = rho_s*r_s/sigma_crit
theta_s = r_s/Dd
Renorm = (4*G/c**2)*(Dds/(Dd*Ds))
#### Here I just interpolate and zoom into my field of view to get better resolutions
A = np.sqrt(X_pix**2 + Y_pix**2)*pix2rad/theta_s
A_1 = A[100:200,0:100]
n_x = n_y = 100
FOV_arcsec_x = FOV_arcsec_original*(100./300)
FOV_arcmin_x = FOV_arcsec_x/60.
pix2rad_x = ((FOV_arcmin_x/60.)/float(n_x))*np.pi/180.
rad2pix_x = 1./pix2rad_x
FOV_arcsec_y = FOV_arcsec_original*(100./300)
FOV_arcmin_y = FOV_arcsec_y/60.
pix2rad_y = ((FOV_arcmin_y/60.)/float(n_y))*np.pi/180.
rad2pix_y = 1./pix2rad_y
x1 = np.linspace(-FOV_arcsec_x/2/pix2rad_x/180.*np.pi/3600.,FOV_arcsec_x/2/pix2rad_x/180.*np.pi/3600.,n_x)
y1 = np.linspace(-FOV_arcsec_y/2/pix2rad_y/180.*np.pi/3600.,FOV_arcsec_y/2/pix2rad_y/180.*np.pi/3600.,n_y)
X1,Y1 = np.meshgrid(x1,y1)
n_x_2 = 500
n_y_2 = 500
x2 = np.linspace(-FOV_arcsec_x/2/pix2rad_x/180.*np.pi/3600.,FOV_arcsec_x/2/pix2rad_x/180.*np.pi/3600.,n_x_2)
y2 = np.linspace(-FOV_arcsec_y/2/pix2rad_y/180.*np.pi/3600.,FOV_arcsec_y/2/pix2rad_y/180.*np.pi/3600.,n_y_2)
X2,Y2 = np.meshgrid(x2,y2)
interp_spline = RectBivariateSpline(y1,x1,A_1)
A_2 = interp_spline(y2,x2)
A_3 = A_2[50:450,0:400]
n_x_3 = n_y_3 = 400
FOV_arcsec_x = FOV_arcsec_original*(100./300)*400./500.
FOV_arcmin_x = FOV_arcsec_x/60.
pix2rad_x = ((FOV_arcmin_x/60.)/float(n_x_3))*np.pi/180.
rad2pix_x = 1./pix2rad_x
FOV_arcsec_y = FOV_arcsec_original*(100./300)*400./500.
FOV_arcmin_y = FOV_arcsec_y/60.
pix2rad_y = ((FOV_arcmin_y/60.)/float(n_y_3))*np.pi/180.
rad2pix_y = 1./pix2rad_y
x3 = np.linspace(-FOV_arcsec_x/2/pix2rad_x/180.*np.pi/3600.,FOV_arcsec_x/2/pix2rad_x/180.*np.pi/3600.,n_x_3)
y3 = np.linspace(-FOV_arcsec_y/2/pix2rad_y/180.*np.pi/3600.,FOV_arcsec_y/2/pix2rad_y/180.*np.pi/3600.,n_y_3)
X3,Y3 = np.meshgrid(x3,y3)
n_x_4 = 1000
n_y_4 = 1000
x4 = np.linspace(-FOV_arcsec_x/2/pix2rad_x/180.*np.pi/3600.,FOV_arcsec_x/2/pix2rad_x/180.*np.pi/3600.,n_x_4)
y4 = np.linspace(-FOV_arcsec_y/2/pix2rad_y/180.*np.pi/3600.,FOV_arcsec_y/2/pix2rad_y/180.*np.pi/3600.,n_y_4)
X4,Y4 = np.meshgrid(x4,y4)
interp_spline = RectBivariateSpline(y3,x3,A_3)
A_4 = interp_spline(y4,x4)
############### Function to calculate variance
variance = np.zeros((len(A_4),len(A_4)))
def variance_fluctuations(x):
for i in xrange(len(x)):
for j in xrange(len(x)):
if x[j][i] < 1.:
variance[j][i] = (k_s**2)*(lambda_c/r_s)*((np.pi/x[j][i]) - (1./(x[j][i]**2 -1)**3.)*(((6.*x[j][i]**4. - 17.*x[j][i]**2. + 26)/3.)+ (((2.*x[j][i]**6. - 7.*x[j][i]**4. + 8.*x[j][i]**2. - 8)*np.arccosh(1./x[j][i]))/(np.sqrt(1-x[j][i]**2.)))))
elif x[j][i] > 1.:
variance[j][i] = (k_s**2)*(lambda_c/r_s)*((np.pi/x[j][i]) - (1./(x[j][i]**2 -1)**3.)*(((6.*x[j][i]**4. - 17.*x[j][i]**2. + 26)/3.)+ (((2.*x[j][i]**6. - 7.*x[j][i]**4. + 8.*x[j][i]**2. - 8)*np.arccos(1./x[j][i]))/(np.sqrt(x[j][i]**2.-1)))))
variance_fluctuations(A_4)
#### Creating the map
mean = 0
delta_kappa = np.random.normal(0,variance,A_4.shape)
xfinal = np.linspace(-FOV_arcsec_x*np.pi/180./3600.*Dd/pc/2,FOV_arcsec_x*np.pi/180./3600.*Dd/pc/2,1000)
yfinal = np.linspace(-FOV_arcsec_x*np.pi/180./3600.*Dd/pc/2,FOV_arcsec_x*np.pi/180./3600.*Dd/pc/2,1000)
Xfinal, Yfinal = np.meshgrid(xfinal,yfinal)
plt.contourf(Xfinal,Yfinal,delta_kappa,100)
plt.show()
The map looks like this, with the density of blobs increasing towards the right. However, the size of the blobs don't change and the map looks virtually the same whether I use lambda_c = 40*pc or lambda_c = 400*pc.
I'm wondering if the np.random.normal function isn't really doing what I expect it to do? I feel like the pixel scale of the map and the way samples are drawn make no link to the size of the blobs. Maybe there is a better way to create the map using the variance, would appreciate any insight.
I expect the map to look something like this , the blob sizes change based on the input parameters for my variance :
This is quite a well visited problem in (surprise surprise) astronomy and cosmology.
You could use lenstool: https://lenstools.readthedocs.io/en/latest/examples/gaussian_random_field.html
You could also try here:
https://andrewwalker.github.io/statefultransitions/post/gaussian-fields
Not to mention:
https://github.com/bsciolla/gaussian-random-fields
I am not reproducing code here because all credit goes to the above authors. However, they did just all come right out a google search :/
Easiest of all is probably a python module FyeldGenerator, apparently designed for this exact purpose:
https://github.com/cphyc/FyeldGenerator
So (adapted from github example):
pip install FyeldGenerator
from FyeldGenerator import generate_field
from matplotlib import use
use('Agg')
import matplotlib.pyplot as plt
import numpy as np
plt.figure()
# Helper that generates power-law power spectrum
def Pkgen(n):
def Pk(k):
return np.power(k, -n)
return Pk
# Draw samples from a normal distribution
def distrib(shape):
a = np.random.normal(loc=0, scale=1, size=shape)
b = np.random.normal(loc=0, scale=1, size=shape)
return a + 1j * b
shape = (512, 512)
field = generate_field(distrib, Pkgen(2), shape)
plt.imshow(field, cmap='jet')
plt.savefig('field.png',dpi=400)
plt.close())
This gives:
Looks pretty straightforward to me :)
PS: FoV implied a telescope observation of the gaussian random field :)
A completely different and much quicker way may be just to blur the delta_kappa array with gaussian filter. Try adjusting sigma parameter to alter the blobs size.
from scipy.ndimage.filters import gaussian_filter
dk_gf = gaussian_filter(delta_kappa, sigma=20)
Xfinal, Yfinal = np.meshgrid(xfinal,yfinal)
plt.contourf(Xfinal,Yfinal,dk_ma,100, cmap='jet')
plt.show();
this is image with sigma=20
this is image with sigma=2.5
ThunderFlash, try this code to draw the map:
# function to produce blobs:
from scipy.stats import multivariate_normal
def blob (positions, mean=(0,0), var=1):
cov = [[var,0],[0,var]]
return multivariate_normal(mean, cov).pdf(positions)
"""
now prepare for blobs generation.
note that I use less dense grid to pick blobs centers (regulated by `step`)
this makes blobs more pronounced and saves calculation time.
use this part instead of your code section below comment #### Creating the map
"""
delta_kappa = np.random.normal(0,variance,A_4.shape) # same
step = 10 #
dk2 = delta_kappa[::step,::step] # taking every 10th element
x2, y2 = xfinal[::step],yfinal[::step]
field = np.dstack((Xfinal,Yfinal))
print (field.shape, dk2.shape, x2.shape, y2.shape)
>> (1000, 1000, 2), (100, 100), (100,), (100,)
result = np.zeros(field.shape[:2])
for x in range (len(x2)):
for y in range (len(y2)):
res2 = blob(field, mean = (x2[x], y2[y]), var=10000)*dk2[x,y]
result += res2
# the cycle above took over 20 minutes on Ryzen 2700X. It could be accelerated by vectorization presumably.
plt.contourf(Xfinal,Yfinal,result,100)
plt.show()
you may want to play with var parameter in blob() to smoothen the image and with step to make it more compressed.
Here is the image that I got using your code (somehow axes are flipped and more dense areas on the top):

Bokeh equivalent of Matplotlib scatter_matrix

Is there a better way of reproducing matplotlibs scatter_matrix (plot all data against all data) in Bokeh than the code below:
defaults.width = 100
defaults.height = 100
scatter_plots = []
y_max = len(dataset.columns)-1
for i, y_col in enumerate(dataset):
for j, x_col in enumerate(dataset):
df = pd.DataFrame({x_col: dataset[x_col].tolist(), y_col: dataset[y_col].tolist()})
p = Scatter(df, x=x_col, y=y_col)
if j > 0:
p.yaxis.axis_label = ""
p.yaxis.visible = False
if i < y_max:
p.xaxis.axis_label = ""
p.xaxis.visible = False
scatter_plots.append(p)
grid = gridplot(scatter_plots, ncols = len(dataset.columns))
show(grid)
In particular I would like to be able to zoom and pan the entire grid of plots as a single entity rather than zoom/pan the subplot the mouse is hovering over.
In general, to have linked panning/zooming, you share the ranges that you want to be linked between plots. This is described here in the Users Guide:
https://docs.bokeh.org/en/latest/docs/user_guide/interaction/linking.html
You can also check out this linked SPLOM example:
https://github.com/bokeh/bokeh/blob/master/examples/models/iris_splom.py
That example is longer/more verbose because it uses the low level bokeh.models API. The important part is where it re-uses the ranges xdr and ydr on ever plot that gets created.
In your particular case, since high level charts don't accept range parameters up front (IIRC), I think you'll have to fix up the charts "after the fact", so maybe something like:
xr = scatter_plots[0].x_range
yr = scatter_plots[0].y_range
for p in scatter_plots:
p.x_range = xr
p.y_range = yr
In case it is useful, I faced the same problem. In actual fact you don't want all the axis linked - but rather each rows y-axis linked and each columns x-axis linked. I'm surprised that this isn't a built in bokeh feature. even iris the example gets this wrong:
http://docs.bokeh.org/en/latest/docs/gallery/iris_splom.html
Here's a code snippet I used:
def scatter_matrix(dataset):
dataset_source = ColumnDataSource(data=dataset)
scatter_plots = []
y_max = len(dataset.columns)-1
for i, y_col in enumerate(dataset.columns):
for j, x_col in enumerate(dataset.columns):
p = figure(plot_width=100, plot_height=100, x_axis_label=x_col, y_axis_label=y_col)
p.circle(source=dataset_source,x=x_col, y=y_col, fill_alpha=0.3, line_alpha=0.3, size=3)
if j > 0:
p.yaxis.axis_label = ""
p.yaxis.visible = False
p.y_range = linked_y_range
else:
linked_y_range = p.y_range
p.plot_width=160
if i < y_max:
p.xaxis.axis_label = ""
p.xaxis.visible = False
else:
p.plot_height=140
if i > 0:
p.x_range = scatter_plots[j].x_range
scatter_plots.append(p)
grid = gridplot(scatter_plots, ncols = len(dataset.columns))
show(grid)

Matplotlib Table's Font Size

Working with Matplotlib in Python (2.7.9). I have to plot a table in a subplot (in this case subplot name is tab) but I can't seem to find a way to change the font size of the table (http://imgur.com/0Ttvzee - bottom left). Antman is happy about the results, I am not.
This is the code I've been using.
EDIT: Added full code
def stat_chart(self):
DN = self.diff
ij = self.ij_list
mcont = self.mcont
ocont = self.ocont
ucont = self.ucont
dist = self.widths
clon = '%1.2f' %self.mclon
clat = '%1.2f' %self.mclat
clonlat = "{0}/{1}".format(clon,clat)
area = self.area
perim = self.perimeter
mdist = np.array(self.widths)
mdist = mdist[:,0]*10
mdist = np.mean(mdist)
pstat = self.polygon_status
if pstat == 1:
status = "Overestimation"
else:
status = "Underestimation"
# Setting up the plot (2x2) and subplots
fig = plt.figure()
gs = gridspec.GridSpec(2,2,width_ratios=[2,1],height_ratios=[4,1])
main = plt.subplot(gs[0,0])
polyf = plt.subplot(gs[0,1])
tab = plt.subplot(gs[1,0])
leg = plt.subplot(gs[1,1])
tab.set_xticks([])
leg.set_xticks([])
tab.set_yticks([])
leg.set_yticks([])
tab.set_frame_on(False)
leg.set_frame_on(False)
# Main image on the top left
main.imshow(DN[::-1],cmap='winter')
x1,x2,y1,y2 = np.min(ij[:,1])-15,np.max(ij[:,1])+15,np.min(ij[:,0])-15,np.max(ij[:,0])+15
main.axvspan(x1,x2,ymin=1-((y1-320)/float(len(DN)-320)),ymax=1-((y2-320)/float(len(DN)-320)),color='red',alpha=0.3)
main.axis([0,760,0,800])
# Polygon image on the top right
polyf.imshow(DN,cmap='winter')
polyf.axis([x1,x2,y2,y1])
polyf.plot(mcont[:,1],mcont[:,0],'ro',markersize=4)
polyf.plot(ocont[:,1],ocont[:,0],'yo',markersize=4)
polyf.plot(ucont[:,1],ucont[:,0],'go',markersize=4)
for n,en in enumerate(dist):
polyf.plot([en[2],en[4]],[en[1],en[3]],color='grey',alpha=0.3)
# Legend on the bottom right
mc = mlines.Line2D([],[],color='red',marker='o')
oc = mlines.Line2D([],[],color='yellow',marker='o')
uc = mlines.Line2D([],[],color='green',marker='o')
ed = mlines.Line2D([],[],color='black',alpha=0.5)
pos_p = mpatches.Patch(color='lightgreen')
neg_p = mpatches.Patch(color='royalblue')
leg.legend([mc,oc,uc,ed,pos_p,neg_p],("Model Cont.","Osisaf Cont.","Unknown Cont.","Dist. Mdl to Osi", \
'Model Overestimate','Model Underestimate'),loc='center')
# Statistics table on the bottom left
stats = [[clonlat+' degrees' ,'%1.4E km^2' %area,'%1.4E km' %perim,'%1.4f km' %mdist,status]]
columns = ('Center Lon/Lat','Area','Perimeter','Mean Width','Status')
rows = ['TODOpolyname']
cwid = [0.1,0.1,0.1,0.1,0.1,0.1]
the_table = tab.table(cellText=stats,colWidths=cwid,rowLabels=rows,colLabels=columns,loc='center')
table_props = the_table.properties()
table_cells = table_props['child_artists']
for cell in table_cells: cell.set_height(0.5)
plt.show()
return
EDIT2: Eventually (un)solved plotting text instead of table. Good enough.
I had a similar issue in changing the fontsize. Try the following
the_table.auto_set_font_size(False)
the_table.set_fontsize(5.5)
Worked for me.
According to the docs, table has a kwarg called fontsize, a float value for the size in points.
In your example from above, for a fontsize of 5 points you would use:
the_table =tab.table(cellText=stats,colWidths=cwid,rowLabels=rows,colLabels=columns,loc='center',fontsize=5)
If you require greater control, you can pass a FontManager instance to the cell.set_text_props() method as described in this example. That would enable you to set the family, spacing, style etc, in addition to the size.
EDIT: Playing around with Matplotlib's example, it seems that just passing fontsize to the table has no effect. However, importing
from matplotlib.font_manager import FontProperties
and then looping through the cells and running
cell.set_text_props(fontproperties=FontProperties(size = 5))
does have the desired effect. It is unclear why the documented kwarg fontsize does not work in this (or apparently in your) case.

Categories

Resources