How to insert line break long mathematical questions in latex for proper display in python - python-3.x

I have created a function which is takes the latex and Description about the question and render it as image, what i want is to split it so that i can display properly in web site.
from io import BytesIO as StringIO
import matplotlib.pyplot as plt
import textwrap as tw
def render_latex(formula, fontsize=12, dpi=300, format_='svg'):
"""Renders LaTeX formula into image.
"""
import pdb; pdb.set_trace()
note1_txt = 'This is sample question to check the new line break for latex, which is not working as expected.'
fig = plt.figure(figsize=(0.01, 0.10))
note1_txt += tw.fill(tw.dedent(formula.rstrip()), width=60)
fig.text(0, 0, u'${}$'.format(note1_txt), fontsize=fontsize)
buffer_ = StringIO()
fig.savefig(buffer_, dpi=dpi, transparent=True, format=format_, bbox_inches='tight', pad_inches=2)
plt.close(fig)
return buffer_.getvalue()
if __name__ == '__main__':
image_bytes = render_latex(
r'\theta=\theta+C(1+\theta-\beta)\sqrt{1-\theta}succ_mul \theta=\theta+C(1+\theta-\beta)\sqrt{1-\theta}succ_mul \theta=\theta+C(1+\theta-\beta)\sqrt{1-\theta}succ_mul',
fontsize=10, dpi=200, format_='png')
with open('formula.png', 'wb') as image_file:
image_file.write(image_bytes)
After executing getting image which is
I want to format it in multi line without losing the latex formatting. I have tried reducing the width. if width is larger and it result properly but that is not my case. for mobile view i am render it as image. Please help me to sort this out.

Related

Struggling to displaying the right (formatted) value for a matplotlib labels

Guide:
https://theoehrly.github.io/Fast-F1/examples_gallery/plot_qualifying_results.html#sphx-glr-examples-gallery-plot-qualifying-results-py
I am having trouble displaying the correct value or formatted form as a matplotlib label.
Issue: Bar Graph labels displaying as an unwanted, or badly formatted values.
(Is this TimeDelta[ns] in an integer under scientific notation? The dtype is timedelta64[ns])
Expected Values: The amount of time each driver is from the leader (s.ms) (HAM=0.038). Note: order is the same
print(times)
Code:
#!/usr/bin/python3-64
#required packages
#pip3 install fastf1
#pip3 install pandas
#pip3 install matplotlib
#pip3 install numpy
import matplotlib.pyplot as plt
import matplotlib.patches as pat
import fastf1 as ff1
import fastf1.plotting as ff1p
ff1p.setup_mpl(mpl_timedelta_support=True, color_scheme=None, misc_mpl_mods=False)
from fastf1.core import Laps
import pandas as pd
import numpy as np
from timple.timedelta import strftimedelta as td
import os
l=str.lower
def data_cache():
cache='/ff1_temp' #temp cache
while(True):
warn=input(l(f'!WARNING! A data cache will be made at {cache}\n'
f'Formula 1 Race Data will be downloaded to {cache}\n'
f'Would you like to continue? [y/n]\n'))
if(warn=='n'):
print('Quitting!\n')
exit(0)
elif(warn=='y'):
print(f'cache location: {cache}\n')
if not os.path.exists(cache): # os.path.exists(cache)
os.mkdir(cache) # os.mkdir(cache)
ff1.Cache.enable_cache(cache) # Fast F1 Cache API
break
else:
print('Plese Enter [y/n]\n')
continue
def data_load():
data=ff1.get_session(2021,'Netherlands','Q') #Y,L,S = Year, Location, Session
data.load(laps=True,telemetry=False,weather=False,messages=False)
return(data)
def data_graph():
data=data_load()
drivers=pd.unique(data.laps['DriverNumber'])
fll=list()
for row in drivers: #get fastest laps for session from each driver
fld=data.laps.pick_driver(row).pick_fastest()
fll.append(fld)
fl=Laps(fll).sort_values(by='LapTime').reset_index(drop=True)
flf=fl.pick_fastest()
fl['LapTimeDelta']=fl['LapTime']-flf['LapTime'] #determine the TimeDelta from leader
tc=list()
for index, lap in fl.iterlaps(): #team colours
color=ff1p.team_color(lap['Team'])
tc.append(color)
return(fl,tc,flf)
def data_plot():
fl,tc,flf=data_graph()
fig,ax=plt.subplots()
times=fl['LapTimeDelta']
fli=fl.index
# y x
bars=ax.barh(fli,times, color=tc,edgecolor='grey')
print(times) #expected values
ax.set_yticks(fl.index)
ax.set_yticklabels(fl['Driver'])
ax.set_xlabel('Time Difference (ms)')
#should be x axis?
ax.bar_label(bars) #(times)
ax.invert_yaxis()
lt=td(flf['LapTime'], '%m:%s.%ms')
plt.suptitle(f'2021 Dutch GP Qualifying\n'
f"Fastest at {lt} ({flf['Driver']})")
plt.show()
if(__name__=="__main__"):
data_cache()
data_plot()
exit(0)
results of print(bars)
results of print(type(times)) and print(type(bars))
What has been Attempted:
def data_plot():
ax.bar_label(times)
Traceback (most recent call last):
File "\python\datacollection\fp1.ff1.graph.py", line 144, in <module>
data_plot()
File "\python\datacollection\fp1.ff1.graph.py", line 132, in data_plot
ax.bar_label(times)
File "\Python\Python310\lib\site-packages\matplotlib\axes\_axes.py", line 2609, in bar_label
bars = container.patches
File "\Python\Python310\lib\site-packages\pandas\core\generic.py", line 5575, in __getattr__
return object.__getattribute__(self, name)
AttributeError: 'Lap' object has no attribute 'patches'
---
def data_plot_label(fli,times):
for i in range(len(fli)):
plt.text(i,times[i],times[i],ha='center',bbox=dict(alpha=0.8))
def data_plot():
data_plot_label(fli,times)
Close:
I'm still pretty green with this stuff,
Am I going about this correctly?
What are my options regarding labelling and matplotlib?
How do I set the correct formatted value for this label?
I find the graph is harder to understand without the actual values on it. It has less depth.
Relevant Docs:
https://theoehrly.github.io/Fast-F1/
https://pandas.pydata.org/docs/reference/index.html
https://matplotlib.org/stable/api/index
I overlooked something in the docs. I was not specifying the label only the container.
Reference:
https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.bar_label.html#matplotlib.axes.Axes.bar_label
Axes.bar_label(container, labels=None, *, fmt='%g', label_type='edge', padding=0, **kwargs)
Solution:
prfx='0 days 00:00:0'
sufx='000'
remov=''
def data_plot():
#removes leading and tailingzeros
times=times.astype(str).str.replace(prfx,remov).str.replace(sufx,remov)
#before: 0 days 00:00:0x.xxx000
#after: x.xxx
#over looked label, label_type=position-on-bar
ax.bar_label(bars, times, label_type='edge')
Just a little more formatting and it should look great!

How to show episode in rendered openAI gym environment

If we look at the previews of the environments, they show the episodes increasing in the animation on the bottom right corner. https://gym.openai.com/envs/CartPole-v1/ .Is there a command to explicitly show that?
I don't think there is a command to do that directly available in OpenAI, but I've written some code that you can probably adapt to your purposes. This is the end result:
These is how I achieve the end result:
For each step, you obtain the frame with env.render(mode='rgb_array')
You convert the frame (which is a numpy array) into a PIL image
You write the episode name on top of the PIL image using utilities from PIL.ImageDraw (see the function _label_with_episode_number in the code snippet).
You save the labeled image into a list of frames.
You render the list of frames as a GIF using matplotlib utilities.
Here is the code I wrote for obtaining a GIF of the behavior of a random agent with the Episode number displayed in the top left corner of each frame:
import os
import imageio
import numpy as np
from PIL import Image
import PIL.ImageDraw as ImageDraw
import matplotlib.pyplot as plt
def _label_with_episode_number(frame, episode_num):
im = Image.fromarray(frame)
drawer = ImageDraw.Draw(im)
if np.mean(im) < 128:
text_color = (255,255,255)
else:
text_color = (0,0,0)
drawer.text((im.size[0]/20,im.size[1]/18), f'Episode: {episode_num+1}', fill=text_color)
return im
def save_random_agent_gif(env):
frames = []
for i in range(5):
state = env.reset()
for t in range(500):
action = env.action_space.sample()
frame = env.render(mode='rgb_array')
frames.append(_label_with_episode_number(frame, episode_num=i))
state, _, done, _ = env.step(action)
if done:
break
env.close()
imageio.mimwrite(os.path.join('./videos/', 'random_agent.gif'), frames, fps=60)
env = gym.make('CartPole-v1')
save_random_agent_gif(env)
You can find a working version of the code here: https://github.com/RishabhMalviya/dqn_experiments/blob/master/train_and_visualize.py#L10

Plotly dash - Dynamically displaying a ndarray image

Context : I'm trying to create a simple image processing application using Plotly Dash. It has to be able to display images and execute some operations on the image while updating the image's display. The image will either be generated on the fly or uploaded to the application.
The images are in the numpy ndarray format because my processing is based on numpy and matplotlib operations that use such format.
Question : What are the Python code that allows to display a ndarray while being able to update it by some GUI operation ?
I'm basically searching the closest thing that dash can offer to a matplotlib.pyplot.imshow()
Research : In my research, I've found this repository which probably incorporate all the basic features I need to start working, but as a beginner in Plotly Dash I struggle to extract the code I need, and it seems it doesn't use numpy either.
I've found this question, which is very close to what I'm asking, but the only answer does not incorporate numpy arrays.
I've found a solution, with Flask.Response and the src parameter of html.Img, and openCV for the image encoding :
import dash
import dash_core_components as dcc
import dash_html_components as html
import cv2
from flask import Flask, Response
import numpy as np
import time
def get_image(seed=0):
# strip slide
size = 400
res = np.mod((np.arange(size)[..., None] + np.arange(size)[None, ...]) + seed, [255])
ret, jpeg = cv2.imencode('.jpg', res)
return jpeg.tobytes()
def gen():
i = 0
while True:
time.sleep(0.03333)
frame = get_image(i)
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
i += 1
server = Flask(__name__)
app = dash.Dash(__name__, server=server)
#server.route('/video_feed')
def video_feed():
return Response(gen(),
mimetype='multipart/x-mixed-replace; boundary=frame')
app.layout = html.Div([
html.H1("Webcam Test"),
html.Img(src="/video_feed")
])
if __name__ == '__main__':
app.run_server(debug=True)
Result :
On the browser, the strips are slowly moving, I guess a gif would've made a better demonstration.
Careful to not send too much images per second, or you'll overflow the application and the browser and they'll eventually crash. So use time.pause or other equivalent limiter in the generator loop.
Tough, I'm still intrested on how other people would do that. One drawback with this solution is that I think that the users would have to share the same display, defined at the path /video_feed.

How To Find a Point In Polygon from a Geojson file Using Python And Geopandas

So I have a .geojson file that contains a FeatureCollection of multiple polygons representing a country. I am trying to determine if a specific point is inside one of these polygons. If so, I return the entire feature itself; if not, I return a simple message.
So far, I am able to load the data into a GeoDataFrame using geopandas, but for some reasons, I can't successfully iterate through the geodataframe and successfully perform polygon.contains(point). It seems to me that the iteration stops after a certain point, or maybe my code does not work at all.
I have tried multiple suggestions from S/O and other tutorials on Google, but I couldn't successfully get what I wanted. Below is my code.
Geojson file
data
Code
%matplotlib inline
import json
import pandas as pd
import geopandas as gpd
import matplotlib.pyplot as plt
import shapely
from shapely.geometry import Point, Polygon
from descartes import PolygonPatch
import geocoder
import requests
import copy
session = requests.Session()
test_point = [14.1747157, 10.4952759]
f, ax = plt.subplots(1, figsize=(10, 10))
url = 'https://trello-attachments.s3.amazonaws.com/599b7f6ff18b8d629ac53168/5d03586a06add530095c325c/26f5d54bbfa9731ec16737641b59de9a/CMR_adm3-2.geojson'
df = gpd.read_file(url)
df['Area']= df['geometry'].area
df['centroid'] = df['geometry'].centroid
df.plot(ax=ax, column="Area", cmap='OrRd', alpha=0.5, edgecolor='k')
# ax.set_title(arr + " " + depart + " " + region, fontsize = font_size)
# print(df.head(3))
plt.show()
print("The length of the Dataframe is:", len(df))
def find_department(df, point):
for feature in df['geometry']:
polygon = Polygon(feature)
# print(type(polygon))
if polygon.contains(point):
# print(feature.to_json())
print ('Found containing polygon:', feature)
else:
print('Found nothing!')
p1 = Point(float(test_point[0]), float(test_point[1]))
dept = find_department(df, p1)
print("The department is:", dept)
This is the response I get when I run it on notebook:
This worked for me:
def find_department(df, point):
for index, row in df.iterrows():
if row.geometry.contains(point):
return row

Import PDF Image From MatPlotLib to ReportLab

I am trying to insert a saved PDF image into a ReportLab flowable.
I have seen several answers to similar questions and many involve using Py2PDF like this:
import PyPDF2
import PIL
input1 = PyPDF2.PdfFileReader(open(path+"image.pdf", "rb"))
page0 = input1.getPage(0)
xObject = page0['/Resources']['/XObject'].getObject()
for obj in xObject:
#Do something here
The trouble I'm having is with a sample image I've saved from MatPlotLib as a PDF. When I try to access that saved image with the code above, it returns nothing under page0['/Resources']['/XObject'].
In fact, here's what I see when I look at page0 and /XObject:
'/XObject': {}
Here's the code I used to generate the PDF:
import matplotlib.pyplot as plt
import numpy as np
# Fixing random state for reproducibility
np.random.seed(19680801)
plt.rcdefaults()
fig, ax = plt.subplots()
# Example data
people = ('Tom', 'Dick', 'Harry', 'Slim', 'Jim')
y_pos = np.arange(len(people))
performance = 3 + 10 * np.random.rand(len(people))
error = np.random.rand(len(people))
ax.barh(y_pos, performance, xerr=error, align='center',
color='green', ecolor='black')
ax.set_yticks(y_pos)
ax.set_yticklabels(people)
ax.invert_yaxis() # labels read top-to-bottom
ax.set_xlabel('Performance')
ax.set_title('How fast do you want to go today?')
plt.savefig(path+'image.pdf',bbox_inches='tight')
Thanks in advance!

Resources