Plot a function with telegram bot (python, matplotlib) - python

I faced with the problem during telegram bot writing. I would be very happy if somebody help me with this.
My code
import telebot
import matplotlib.pyplot as plt
import numpy as np
...
def plot_func(message):
x = np.linspace(-5,5,100)
y = message.text # <-- here is something wrong I supppose
plt.plot(x, y, 'r')
plt.savefig('plot_name.png', dpi = 300)
bot.send_photo(message.chat.id, photo=open('plot_name.png', 'rb'))
#plt.show()
Main idea
User send function, bot plot it and send image back:
ERROR
/home/anmnv/Desktop/news_scrapper_bot/bot.py:148: UserWarning: Starting a Matplotlib GUI outside of the main thread will likely fail.
plt.plot(x, y, 'r')
Traceback (most recent call last):
File "/home/anmnv/Desktop/news_scrapper_bot/bot.py", line 424, in <module>
bot.polling(none_stop=True)
File "/home/anmnv/.local/lib/python3.10/site-packages/telebot/__init__.py", line 1047, in polling
self.__threaded_polling(non_stop=non_stop, interval=interval, timeout=timeout, long_polling_timeout=long_polling_timeout,
File "/home/anmnv/.local/lib/python3.10/site-packages/telebot/__init__.py", line 1122, in __threaded_polling
raise e
File "/home/anmnv/.local/lib/python3.10/site-packages/telebot/__init__.py", line 1078, in __threaded_polling
self.worker_pool.raise_exceptions()
File "/home/anmnv/.local/lib/python3.10/site-packages/telebot/util.py", line 154, in raise_exceptions
raise self.exception_info
File "/home/anmnv/.local/lib/python3.10/site-packages/telebot/util.py", line 98, in run
task(*args, **kwargs)
File "/home/anmnv/Desktop/news_scrapper_bot/bot.py", line 148, in plot_func
plt.plot(x, y, 'r')
File "/home/anmnv/.local/lib/python3.10/site-packages/matplotlib/pyplot.py", line 2730, in plot
return gca().plot(
File "/home/anmnv/.local/lib/python3.10/site-packages/matplotlib/axes/_axes.py", line 1662, in plot
lines = [*self._get_lines(*args, data=data, **kwargs)]
File "/home/anmnv/.local/lib/python3.10/site-packages/matplotlib/axes/_base.py", line 311, in __call__
yield from self._plot_args(
File "/home/anmnv/.local/lib/python3.10/site-packages/matplotlib/axes/_base.py", line 504, in _plot_args
raise ValueError(f"x and y must have same first dimension, but "
ValueError: x and y must have same first dimension, but have shapes (100,) and (1,)
Thank you in advance

Assuming message.text contains the string 'x**2', you can use numexpr.evaluate to convert to numpy array:
import numexpr
import matplotlib.pyplot as plt
x = np.linspace(-5, 5, 100)
y = numexpr.evaluate(message.text) # message.text = 'x**2'
plt.plot(x, y, 'r')
Output:

Related

How to name a figure following its histogram name in matplotlib pyplot using savefig

I use the script
import matplotlib.pyplot as plt
import numpy as np
import yoda
def readScatter2D(histname, filename):
histos = yoda.core.read(filename+".yoda")
x = []
y = []
h = histos[histname]
for b in h:
x.append(b.x())
y.append(b.y())
plt.plot([x],[y], 'bo')
plt.savefig(str(histname)+".pdf")
readScatter2D("totalCh", "properties_file")
Compiling this with python3 gives me the error:
Traceback (most recent call last):
File "enhancement.py", line 18, in <module>
readScatter2D("totalCh", "properties_file")
File "enhancement.py", line 16, in readScatter2D
plt.savefig(str(histname)+".pdf")
File "/usr/lib64/python2.7/site-packages/matplotlib/pyplot.py", line 697, in savefig
res = fig.savefig(*args, **kwargs)
File "/usr/lib64/python2.7/site-packages/matplotlib/figure.py", line 1573, in savefig
self.canvas.print_figure(*args, **kwargs)
File "/usr/lib64/python2.7/site-packages/matplotlib/backend_bases.py", line 2252, in print_figure
**kwargs)
File "/usr/lib64/python2.7/site-packages/matplotlib/backends/backend_pdf.py", line 2519, in print_pdf
file = PdfFile(filename)
File "/usr/lib64/python2.7/site-packages/matplotlib/backends/backend_pdf.py", line 422, in __init__
fh = open(filename, 'wb')
IOError: [Errno 2] No such file or directory: 'totalCh.pdf'
I do not understand why matplotlib cannot name the file while saving, by following the histogram names. What is the solution to save the figure following the original histogram? I am using matplotlib version 2.0.2

Buffer is too small for requested array-Astropy

I'm reading TESS data and as you might expect it can be really large, My Buffer is too small. Is there a way I can avoid this error? Like maybe skip the file that has a large file? Or is there a more permanent solution(not involving more memory)? My Code is below, along with the Full Error
from lightkurve import TessTargetPixelFile
import lightkurve as lk
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
def func(tpf):
tpf.plot(aperture_mask=tpf.pipeline_mask);
lc = tpf.to_lightcurve()
mask = (lc.time.value < 1464)
masked_lc = lc[mask]
clipped_lc = masked_lc.remove_outliers(sigma=5);
flat_lc = clipped_lc.flatten()
binned_lc = flat_lc.bin(binsize=5)
periodogram = binned_lc.to_periodogram(method="bls", period=np.arange(1, 20, 0.001))
print(periodogram.plot())
planet_b_period = periodogram.period_at_max_power
planet_b_t0 = periodogram.transit_time_at_max_power
planet_b_dur = periodogram.duration_at_max_power
ax = binned_lc.fold(period=planet_b_period, epoch_time=planet_b_t0).scatter()
ax.set_xlim(-5, 5);
best_fit_period = periodogram.period_at_max_power
print('Best fit period: {:.3f}'.format(best_fit_period))
bfc=best_fit_period
print(bfc)
folded_lc = binned_lc.fold(period=bfc)
folded_lc.scatter(s=7);
plt.show()
planet_b_period
planet_b_model = periodogram.get_transit_model(period=planet_b_period,
transit_time=planet_b_t0,
duration=planet_b_dur)
ax = binned_lc.fold(planet_b_period, planet_b_t0).scatter(s=7)
planet_b_model.fold(planet_b_period, planet_b_t0).plot(ax=ax, c='r', lw=2)
ax.set_xlim(-5, 5);
dataset=pd.read_csv("all_targets_S001_v1.csv")
d=dataset["TICID"]
print(d)
IDs=[]
for i in range(len(d)):
IDs.append("TIC"+str(d[i]))
for i in range(len(IDs)):
tpf_file = lk.search_targetpixelfile(IDs[i], mission="TESS", sector=5).download(quality_bitmask='default')
try:
func(tpf_file)
continue
except:
continue
Thanks
The Full Error
WARNING: File may have been truncated: actual file length (262144) is smaller than the expected size (46402560) [astropy.io.fits.file]
Traceback (most recent call last):
File "lc.py", line 42, in <module>
tpf_file = lk.search_targetpixelfile(IDs[i], mission="TESS", sector=5).download(quality_bitmask='default')
File "C:\ProgramData\Anaconda3\lib\site-packages\lightkurve\utils.py", line 555, in wrapper
return f(*args, **kwargs)
File "C:\ProgramData\Anaconda3\lib\site-packages\lightkurve\search.py", line 355, in download
return self._download_one(
File "C:\ProgramData\Anaconda3\lib\site-packages\lightkurve\search.py", line 290, in _download_one
return read(path, quality_bitmask=quality_bitmask, **kwargs)
File "C:\ProgramData\Anaconda3\lib\site-packages\lightkurve\io\read.py", line 112, in read
return getattr(__import__("lightkurve"), filetype)(path_or_url, **kwargs)
File "C:\ProgramData\Anaconda3\lib\site-packages\lightkurve\targetpixelfile.py", line 2727, in __init__
quality_array=self.hdu[1].data["QUALITY"], bitmask=quality_bitmask
File "C:\ProgramData\Anaconda3\lib\site-packages\astropy\utils\decorators.py", line 758, in __get__
val = self.fget(obj)
File "C:\ProgramData\Anaconda3\lib\site-packages\astropy\io\fits\hdu\table.py", line 399, in data
data = self._get_tbdata()
File "C:\ProgramData\Anaconda3\lib\site-packages\astropy\io\fits\hdu\table.py", line 171, in _get_tbdata
raw_data = self._get_raw_data(self._nrows, columns.dtype,
File "C:\ProgramData\Anaconda3\lib\site-packages\astropy\io\fits\hdu\base.py", line 520, in _get_raw_data
return self._file.readarray(offset=offset, dtype=code, shape=shape)
File "C:\ProgramData\Anaconda3\lib\site-packages\astropy\io\fits\file.py", line 330, in readarray
return np.ndarray(shape=shape, dtype=dtype, offset=offset,
TypeError: buffer is too small for requested array

Why am I receiving this error when using pylab to make a bar graph

I am using data from a file to make a bar graph using pylab. When I run it I get a very long error code.
This is my code.
bar_width=0.5
x_values=[1,2,3,4,5,6,7,8,9,10]
y_values=[3,2,5,7,4,10,12]
tlabel=["0-10", "11-20", "21-30", "31-40", "41-50", "51-60", "61-70", "71-80", "81-90", "Above 90"]
#pylab.xticks(range(6),rotation=30)
pylab.title("Homicide Occurance by Age")
pylab.bar(x_values,y_values,width=bar_width,tick_label=tlabel, align='center',color='b')
pylab.show()
And here is the error message I am receiving.
Traceback (most recent call last):
File "C:\Users\mads\OneDrive\Desktop\CSC 130\prog5.py", line 39, in <module>
pylab.bar(x_values,y_values,width=bar_width,tick_label=tlabel, align='center',color='b')
File "C:\Users\mads\anaconda3\lib\site-packages\matplotlib\pyplot.py", line 2487, in bar
return gca().bar(
File "C:\Users\mads\anaconda3\lib\site-packages\matplotlib\__init__.py", line 1447, in inner
return func(ax, *map(sanitize_sequence, args), **kwargs)
File "C:\Users\mads\anaconda3\lib\site-packages\matplotlib\axes\_axes.py", line 2430, in bar
x, height, width, y, linewidth = np.broadcast_arrays(
File "<__array_function__ internals>", line 5, in broadcast_arrays
File "C:\Users\mads\anaconda3\lib\site-packages\numpy\lib\stride_tricks.py", line 538, in broadcast_arrays
shape = _broadcast_shape(*args)
File "C:\Users\mads\anaconda3\lib\site-packages\numpy\lib\stride_tricks.py", line 420, in _broadcast_shape
b = np.broadcast(*args[:32])
ValueError: shape mismatch: objects cannot be broadcast to a single shape
you have 10 x_values but only 7 y_values. Try to run the same code with balanced data.

Matplotlib problems with converting string into date readable format cannot be compiled

I've got a problem with programming live - changing plot and histogram from csv file, where the data is saved - the record contains date ('%Y-%M-%D %H:%m:%S') and the time seperated, by tabulator sign '\t'.
However, I was searching through several toturials and documentation and simply can't fix it. Below, there are links I came across:
https://github.com/etsy/skyline/issues/123
How to fix AttributeError: 'Series' object has no attribute 'find'?
https://docs.python.org/3.4/library/datetime.html
Python/Numpy: problems with type conversion in vectorize and item
I did not find answer there and other similar websites, including sentdex toturials on YT. The code below is going to be compiled and used at Raspberry Pi 3 B+, but it was created on Ubuntu OS on standard PC - this code works perfectly there:
import serial
import pandas as pd
import matplotlib.pyplot as plt
import csv
import datetime
import matplotlib.animation as animation
fig, axes = plt.subplots(nrows=1, ncols=2)
ax1, ax2 = axes.flatten()
def update(i):
file_data = pd.read_csv("/home/pi/Desktop/score_board3", delimiter="\t",
parse_dates=[0], header=None, usecols=[0, 1])
ax1.clear()
ax2.clear()
ax1.plot(file_data[0].astype(float), file_data[1])
ax2.hist([file_data[1],], bins='auto', histtype='bar', facecolor='#FF8C00', edgecolor='red')
ax1.set_title('History')
ax1.set_xlabel('Measurement time')
ax1.set_ylabel('Reaction time [s]')
ax2.set_title('Histogram')
ax2.set_xlabel('Reaction time [s]')
ax2.set_ylabel('Number of results')
ani = animation.FuncAnimation(fig, update, interval=1000)
plt.show()
arduino = serial.Serial('/dev/ttyACM0', 9600)
file = open ('/home/pi/Desktop/Noc_Naukowcow/score_board3', 'r+')
try:
while True:
file.read(1)
new_score = arduino.readline()
print(new_score)
score = new_score.decode('utf-8').strip() + "\n"
score_time = '{:%Y-%M-%D %H:%m:%S}'.format(datetime.datetime.now())
file.write(score_time)
file.write('\t')
file.write(score)
file.flush()
except KeyboardInterrupt:
print("KeyboardInterrupt has been caught.")
file.close()
scores_to_read.close()
After compiling that code, I receive a lot of errors found:
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.5/tkinter/__init__.py", line 1562, in __call__
return self.func(*args)
File "/usr/lib/python3/dist-packages/matplotlib/backends/backend_tkagg.py", line 280, in resize
self.show()
File "/usr/lib/python3/dist-packages/matplotlib/backends/backend_tkagg.py", line 351, in draw
FigureCanvasAgg.draw(self)
File "/usr/lib/python3/dist-packages/matplotlib/backends/backend_agg.py", line 464, in draw
self.figure.draw(self.renderer)
File "/usr/lib/python3/dist-packages/matplotlib/artist.py", line 63, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
File "/usr/lib/python3/dist-packages/matplotlib/figure.py", line 1150, in draw
self.canvas.draw_event(renderer)
File "/usr/lib/python3/dist-packages/matplotlib/backend_bases.py", line 1815, in draw_event
self.callbacks.process(s, event)
File "/usr/lib/python3/dist-packages/matplotlib/cbook.py", line 549, in process
proxy(*args, **kwargs)
File "/usr/lib/python3/dist-packages/matplotlib/cbook.py", line 416, in __call__
return mtd(*args, **kwargs)
File "/usr/lib/python3/dist-packages/matplotlib/animation.py", line 831, in _start
self._init_draw()
File "/usr/lib/python3/dist-packages/matplotlib/animation.py", line 1490, in _init_draw
self._draw_frame(next(self.new_frame_seq()))
File "/usr/lib/python3/dist-packages/matplotlib/animation.py", line 1512, in _draw_frame
self._drawn_artists = self._func(framedata, *self._args)
File "/home/pi/Desktop/kod testowy.py", line 16, in update
parse_dates=[0], header=None, usecols=[0, 1])
File "/home/pi/.local/lib/python3.5/site-packages/pandas/io/parsers.py", line 678, in parser_f
return _read(filepath_or_buffer, kwds)
File "/home/pi/.local/lib/python3.5/site-packages/pandas/io/parsers.py", line 440, in _read
parser = TextFileReader(filepath_or_buffer, **kwds)
File "/home/pi/.local/lib/python3.5/site-packages/pandas/io/parsers.py", line 787, in __init__
self._make_engine(self.engine)
File "/home/pi/.local/lib/python3.5/site-packages/pandas/io/parsers.py", line 1014, in _make_engine
self._engine = CParserWrapper(self.f, **self.options)
File "/home/pi/.local/lib/python3.5/site-packages/pandas/io/parsers.py", line 1756, in __init__
_validate_usecols_names(usecols, self.names)
File "/home/pi/.local/lib/python3.5/site-packages/pandas/io/parsers.py", line 1134, in _validate_usecols_names
"columns expected but not found: {missing}".format(missing=missing)
ValueError: Usecols do not match columns, columns expected but not found: [1]
UPDATE:
I think I've just overcame that problem using thread library. However I need to figure out how to set up them together:
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import serial
import datetime
import threading
fig, axes = plt.subplots(nrows=2, ncols=1)
ax1, ax2 = axes.flatten()
scores_to_read = serial.Serial ('/dev/ttyACM0', 9600)
file = open ("/home/pi/Desktop/Noc_Naukowcow/score_board.csv", 'r+')
def update(i):
file_data = pd.read_csv("/home/pi/Desktop/Noc_Naukowcow/score_board.csv", delimiter="\t",
parse_dates=[0], header=None, usecols=[0, 1])
ax1.clear()
ax2.clear()
ax1.plot(file_data[0],file_data[1])
ax2.hist([file_data[1],], bins='auto', histtype='bar')
#ax1.set_title('History')
ax1.set_xlabel('Measurement time')
ax1.set_ylabel('Reaction time [s]')
#ax2.set_title('Histogram')
ax2.set_xlabel('Reaction time [s]')
ax2.set_ylabel('Number of results')
ani = animation.FuncAnimation(fig, update, interval=1000)
plt.plot()
def serial_port(file):
file.read()
new_score = scores_to_read.readline()
print(new_score)
score = new_score.decode('utf-8').strip() + "\n"
score_time = '{:%Y-%m-%d %H:%M:%S}'.format(datetime.datetime.now())
file.write(score_time)
file.write('\t')
file.write(score)
file.flush()
thread1 = threading.Thread(target=serial_port, args=(file))
thread1.start()

Matplotlib dateformat issue

I'm trying to plot time series data using matplotlib using the following code
import matplotlib.pyplot as plt
x, y = data.shape
y_metrics = alarms_metrics + udp_alarms_metrics_names
print x, y
for j in range(1, y):
time_stamp = []
metric = []
plt.figure()
for i in range(x):
time_stamp.append(data_time[i][0])
metric.append(data[i][j])
plt.xlabel("Time")
plt.ylabel(str(y_metrics[j-1]))
plt.plot(time_stamp, metric)
plt.savefig(str(j))
The format of time_stamp is
['2017:02:01:14:44:00', '2017:02:01:14:44:01',...etc]
time_stamp is a list of type 'numpy.string_'
I'm getting the following error
Traceback (most recent call last):
File "/home/joseph/PycharmProjects/demo/src/alarm_log/alarm_db_plot.py", line 23, in <module>
plt.plot(time_stamp, metric)
File "/usr/lib/python2.7/dist-packages/matplotlib/pyplot.py", line 3154, in plot
ret = ax.plot(*args, **kwargs)
File "/usr/lib/python2.7/dist-packages/matplotlib/__init__.py", line 1814, in inner
return func(ax, *args, **kwargs)
File "/usr/lib/python2.7/dist-packages/matplotlib/axes/_axes.py", line 1425, in plot
self.add_line(line)
File "/usr/lib/python2.7/dist-packages/matplotlib/axes/_base.py", line 1708, in add_line
self._update_line_limits(line)
File "/usr/lib/python2.7/dist-packages/matplotlib/axes/_base.py", line 1730, in _update_line_limits
path = line.get_path()
File "/usr/lib/python2.7/dist-packages/matplotlib/lines.py", line 925, in get_path
self.recache()
File "/usr/lib/python2.7/dist-packages/matplotlib/lines.py", line 612, in recache
x = np.asarray(xconv, np.float_)
File "/usr/local/lib/python2.7/dist-packages/numpy/core/numeric.py", line 482, in asarray
return array(a, dtype, copy=False, order=order)
ValueError: invalid literal for float(): 2017:02:01:14:44:00
I think I might need to used matplotlib dateformatter to parse the time_stamp. I tried so but I couldn't figure out how. Any help please?
Not exactly sure what you're trying to plot without seeing the data, but you could try to convert the string to a datetime object. See here for a list with the format codes.
from datetime import datetime
time_stamp = ['2017:02:01:14:44:00', '2017:02:01:14:44:01']
time_stamp = [datetime.strptime(i, '%Y:%m:%d:%H:%M:%S') for i in time_stamp]
print(time_stamp)

Categories

Resources