Tight BBox not inside SaveFig - matplotlib

Is there a way to use bbox_inches='tight' not inside plt.savefig()?
This beacuse I'm converting a Matplotlib figure to a PIL Image without saving it, but I would like to discard all the white space around it.
Thanks in advance.
I'm using this function with this code.
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
import io
def fig2img(fig):
buf = io.BytesIO()
fig.savefig(buf)
buf.seek(0)
img = Image.open(buf)
return img
H_plt = plt.figure(dpi=300)
levels = np.linspace(-1, 1, 21)
CS1 = plt.contourf(h_P, levels=levels, cmap=h_cmap)
cb1 = plt.colorbar(CS1)
ticks1 = np.linspace(-1, 1, 11)
labels = [str(int(t1)) for t1 in ticks1]
cb1.set_ticks(ticks1, labels=labels)
plt.axis('scaled')
plt.grid()
new_frame_H = fig2img(H_plt)

Related

How to recognize six characters from an image by using pytesseract

I can't understand how to recognize it.
Hope someone can get me out.
import cv2
import numpy as np
import pytesseract
from PIL import Image
image = cv2.imread('b.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (3,3), 0)
thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
# Morph open to remove noise and invert image
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=1)
invert = 255 - opening
data = pytesseract.image_to_string(image, lang='eng', config='--psm 10')
print(data)

Show exponentiated values along opposite side of log color scale

With a horizontal log-scaled color bar and logged labels along the bottom, is it possible to show the exponentiated (original) values along the top?
So in this example, there should be ticks and labels along the top of the color bar going from mat.min() = 0.058 to mat.max() = 13.396
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
mat = np.exp(np.random.randn(20, 20))
plt.matshow(mat)
norm = mpl.colors.Normalize(1, np.log(mat.max()))
plt.colorbar(plt.cm.ScalarMappable(norm=norm), orientation="horizontal")
plt.savefig("rand_mat.png", dpi=200)
Here is the best answer for your response. I've customized it based on that. Does this result match the intent of your question? The color bar and the size of the figure are not the same, so I adjusted them.
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(20210404)
mat = np.exp(np.random.randn(20, 20))
norm = mpl.colors.Normalize(1, np.log(mat.max()))
fig, (ax, cax) = plt.subplots(nrows=2, gridspec_kw=dict(height_ratios=[15,1],hspace=0.5))
im = ax.matshow(mat)
cbar = plt.colorbar(plt.cm.ScalarMappable(norm=norm), orientation="horizontal", cax=cax)
cax2 = cax.twiny()
cbar.ax.xaxis.set_label_position("bottom")
iticks = np.arange(mat.min(), mat.max(), 2)
cax2.set_xticks(iticks)
ax_pos = ax.get_position()
cax_pos = cbar.ax.get_position()
new_size = [ax_pos.x0, cax_pos.y0, ax_pos.x1 - ax_pos.x0, cax_pos.y1 - cax_pos.y0]
cbar.ax.set_position(new_size)
plt.show()
At the risk of committing a faux pas, I'll answer my own question with the solution that best suits my needs:
cb.ax.secondary_xaxis("top", functions=(np.exp, np.log))
which gives
Full Code
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
mat = np.exp(np.random.randn(20, 20))
plt.matshow(mat)
norm = mpl.colors.Normalize(np.log(mat.min()), np.log(mat.max()))
cb = plt.colorbar(plt.cm.ScalarMappable(norm=norm), orientation="horizontal")
cb_ax_top = cb.ax.secondary_xaxis("top", functions=(np.exp, np.log))
cb_ax_top.set_xticks([0.1, 0.5, 1, 4, 10, 20])

how to save plt plot obtained from netCDF4 as georeferenced geoTiff?

Below code is taken from http://www.acgeospatial.co.uk/sentinel-5p-and-python/
This is a very nice tutorial on how to process with Sentinel 5p netCDF data.
Now I tried to save obtained plt image as georeferenced Tiff (geoTiff). How to do this?
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
from netCDF4 import Dataset
import numpy as np
file = 'S5P_OFFL_L2__O3_____20201025T093552_20201025T111721_15720_01_020103_20201027T030032.nc'
fh = Dataset(file, mode='r')
lons = fh.groups['PRODUCT'].variables['longitude'][:][0,:,:]
lats = fh.groups['PRODUCT'].variables['latitude'][:][0,:,:]
o3 = fh.groups['PRODUCT'].variables['ozone_total_vertical_column'][0,:,:]
o3_units = fh.groups['PRODUCT'].variables['ozone_total_vertical_column_precision'].units
#o3_units = o3_units
m = Basemap(width=5000000,height=3500000,\
llcrnrlon=-15.,llcrnrlat=30.,urcrnrlon=80.,urcrnrlat=80.,\
resolution='c',projection='merc',\
#lat_ts=40,lat_0=lat_0,lon_0=lon_0)
lat_ts=40,lat_0=50,lon_0=20)
xi, yi = m(lons, lats)
# Plot Data
cs = m.pcolor(xi,yi,np.squeeze(o3*2241.15), cmap='jet')
#plt.axis('off')
plt.show()
As you see the result is presented with plt.show metod. But I would like to save it to geoTiff. Thanks!

How to wrap text in a dataframe's table (converted to .png)

I am having an issue where I cannot format my tables. The text is too long to just edit the dimensions or the text size. How can I quickly change this so you can see all the text when I have the data for each column more filled in? I am looking for a wrap text kind of function but I don't know if that is possible the way I'm doing it. Is there another way you'd recommend? I'm changing the table into a .png to insert into an Excel file. It has to be a .png so it's an object and doesn't mess with the size of the rows and columns in Excel.
import matplotlib.pyplot as plt
import xlsxwriter as xl
import numpy as np
import yfinance as yf
import pandas as pd
import datetime as dt
import mplfinance as mpf
import pandas_datareader
from pandas_datareader import data as pdr
yf.pdr_override()
import numpy as np
Individualreport = "C:\\Users\\Ashley\\FromPython.xlsx"
Ticklist = pd.read_excel("C:\\Users\\Ashley\\Eyes Trial Data Center.xlsx",sheet_name='Tickers', header=None)
stocks = Ticklist.values.ravel()
PipelineData = pd.read_excel("C:\\Users\\Ashley\\Eyes Trial Data Center.xlsx", sheet_name='Pipeline', header=None)
writer = pd.ExcelWriter(Individualreport, engine='xlsxwriter')
for i in stocks:
#write pipeline data
t = PipelineData.loc[(PipelineData[0]==i)]
print(t)
def render_mpl_table(data, col_width=10, row_height=1, font_size=10, wrap=True,
header_color='#40466e', row_colors=['#f1f1f2', 'w'], edge_color='w',
bbox=[0, 0, 1, 1], header_columns=0,
ax=None, **kwargs):
if ax is None:
size = (np.array(data.shape[::-1]) + np.array([0, 1])) * np.array([col_width, row_height])
fig, ax = plt.subplots(figsize=size)
ax.axis('off')
mpl_table = ax.table(cellText=data.values, bbox=bbox, colLabels=data.columns, **kwargs)
mpl_table.auto_set_font_size(False)
#mpl_table.set_fontsize(font_size)
for k, cell in mpl_table._cells.items():
cell.set_edgecolor(edge_color)
if k[0] == 0 or k[1] < header_columns:
cell.set_text_props(weight='bold', color='w')
cell.set_facecolor(header_color)
else:
cell.set_facecolor(row_colors[k[0]%len(row_colors) ])
return ax.get_figure(), ax
fig,ax = render_mpl_table(t, header_columns=0, col_width=2.0)
fig.savefig(str(i)+'pipe.png')
I think I needed to use an additional package, haven't tried with this example, but worked in another similar example I did.
from textwrap import wrap
label = ("label text that is getting put in the graph")
label = [ '\n'.join(wrap(l, 20)) for l in label ]
#20 is number of characters per line

How to resave image without borders in matplotlib

I am just want to show and then save the same image on plot but got borders.
import numpy as np
import skimage.io
import matplotlib
import matplotlib.pyplot as plt
fileName = "1.jpg"
image=mpimg.imread(fileName)
height, width = image.shape[:2]
my_dpi = 96 / 2
fg, ax = plt.subplots(1, figsize=(1080/my_dpi, 1920/my_dpi), dpi=my_dpi)
ax.set_ylim(height, 0)
ax.set_xlim(0, width)
ax.axis('off')
ax.imshow(image.astype(np.uint8))
plt.savefig("res.png")
Source image:
Result image after resaving:
How to remove the borders and make the result image be the same as original without borders?