matplotlib mathtext does not work - math

I'm doing a hist plot and I want some numbers shown in the plot, so I put in a text box using mathtext for the text, but I doesn't work and I can't see why.
a = [2086., 360.5, 1000.]
b = [977., 37., 498.]
c = [4512., 690., 378.]
textstr = r'$\per50=%.2f$\n$\per16=%.2f$\n$\per84=%.2f$'%(a[0],b[0],c[0])
# these are matplotlib.patch.Patch properties
props = dict(boxstyle='round', facecolor='wheat', alpha=0.75)
# place a text box in upper left in axes coords
ax.text(0.05, 0.95, textstr, transform=ax.transAxes, fontsize=14,
verticalalignment='top', bbox=props)
At the end of my figure I'm getting this error:
matplotlib.pyparsing.ParseFatalException: Expected end of math '$'
$\per50=2086.00$\n$\per16=977.00$\n$\per84=4512.00$ (at char 0), (line:1, col:1)
I hope you can help me!

You are getting that error because the command $\per$ does not exist. Is that a latex command you defined? If you set the matplotlib parameter text.usetex=True, it is possible to set a latex preamble and define commands there, e.g.:
rc('text', usetex=True)
rc('text.latex', preamble='something')
But I don't think this can be used to define new commands (and the use of preamble is discouraged). So your best bet is to write explicitly in matplotlib whatever \per stands for.

Related

How to set the default attributes of Plots?

In Julia plotting with Plots, I know how to set the various attributes when using plot() (Attributes).
I want to know how to set the default attributes, so that I don't need to set them every time.
For instance, I want to change the font-family to another one, or show the minor ticks always.
I googled but I can not find the way.
This is the way:
Use the default() function like so
using Plots
default(titlefont = (20, "times"), legendfontsize = 18, guidefont = (18, :darkgreen), tickfont = (12, :orange), guide = "x", framestyle = :zerolines, yminorgrid = true)
plot([sin, cos], -2π, 2π, label = ["sin(θ)" "cos(θ)"], title = "Trigonometric Functions", xlabel = "θ", linewidth = 2, legend = :outertopleft)
Taken from the documentation here. I know the Plots.jl docs can be a bit tricky to navigate due to their size, but in this case I just typed default into the doc search box.
Note that when using the default function you don't supply the keyword args in subsequent calls to plot, unless of course you want to change away from your newly specified defaults.
Since you are asking for a way to save defaults across sessions, I will also point you to this additional tip from the installation docs:
You can override standard default values in your ~/.julia/config/startup.jl file: PLOTS_DEFAULTS = Dict(:markersize => 10, :legend => false, warn_on_unsupported = false)
So here you are defining the new defaults as a dictionary which is used as an environment variable, which allows setting defaults before loading Plots (and thus without having the default function available).
Store your defaults in a variable and overwrite whenever needed.
defs = (linestyle=:dash, linewidth=5, linecolor=:green)
plot(rand(5);defs...,linecolor=:red)
My solution is to create an empty plot with all "default" attributes and then just add necessary layers each time to this empty plot.

tradingview pine script error "cannot use 'plot' in a local scope"

I am trying to write a simple if-then-else statement using the Pine language under Tradingview. What the code does is based upon user input.
If the box is checked, the plot the line.
If the box is not checked do not plot the line.
This is the code I have:
notPlot = -2000
var ch382= input(true, ".382")
if ch382
plot( ch382? bottom + diff * .382: noPlot, title="fib-.236", linewidth=3, color=color.orange )
How can I write this in a proper way?
If I try to run it, I get: “cannot use 'plot' in a local scope”
Any assistance would be greatly appreciated.
ETA: I found this thread below
How to put plot statement inside if statement
but -
what I need to do is to plot if the box is checked and ~not plot~ if the box is not checked.
ETA: figured out the issue. One would use "na" (in the case of plotting) to note that the line should not be displayed - my mistake ...
var ch382 = input(true, ".382")
plot( ch382? bottom + diff * .382: na, title="fib-.382", linewidth=3, color=color.orange )

How to suppress unwanted Plot figure object information in Jupyter Notebook

I want to suppress any text output when I run Jupyter Notebook cell. Specifically I output some figures and each is accompanied by something like:
<Figure size 432x288 with 0 Axes>
I have seen that if I put a ; at the end of a line, it should suppress the output, but it is not working in my case.
The code:
for i in tqdm_notebook(range(data.shape[0])):
print('BIN:',i)
fig = plt.figure(figsize=(15,4))
plt.tight_layout()
gs = gridspec.GridSpec(2,1)
ax1 = fig.add_subplot(gs[0, 0])
ax1.plot(match[window_begin:window_end],'k')
plt.vlines(i,-np.max(match[window_begin:window_end])*0.05,np.max(match[window_begin:window_end])*1.05,'r',linewidth=4,alpha=0.2)
ax1.set_xlim(0-1,post_bin_match_median[window_begin:window_end].shape[0])
ax1.set_ylim(-np.max(match[window_begin:window_end])*0.05,np.max(match[window_begin:window_end])*1.05)
plt.tick_params(axis='y', which='both', left=True, labelleft=False)
ax1.tick_params(axis='x', which='both', bottom=False, labelbottom=False)
plt.grid()
ax2 = fig.add_subplot(gs[1, 0])
fig.subplots_adjust(hspace=0.0)
ax2.plot(gp_mjds[:],gp_data[i,:],'k')
ax2.errorbar(remain, all[i,:], yerr=all_noise[i], fmt=".k", capsize=0);
ax2.fill_between(gp[:], gp2[i,:] - np.sqrt(gp_var[i,:]), gp2[i,:] + np.sqrt(gp_var[i,:]),color="k", alpha=0.2)
ax2.set_xlim(gp[0],gp[-1])
plot_y_min = np.minimum(np.min(gp2[:,:] - np.sqrt(gp_var[:,:])),np.min(all_profile_residuals[:,:]-y_noise))
plot_y_max = np.maximum(np.max(gp2[:,:] + np.sqrt(gp_var[:,:])), np.max(all[:,:]+y_noise))
ax2.set_ylim(plot_y_min,plot_y_max)
plt.grid()
plt.show()
plt.clf()
plt.close(fig);
The semi-colon would work if the typical output from the last line of the cell is what you are trying to suppress. As succinctly summarized by #kynan here, "The reason this works is because the notebook shows the return value of the last command. By adding ; the last command is "nothing" so there is no return value to show."
However, you have a loop inside a cell generating objects.
The culprit seems to be plt.clf(). Comment out that line or remove it from your code, and it should fix it.
Plus, I'd remove plt.show() as it isn't necessary when plt.clf() is removed, and I am seeing it being in the loop causing fig = plt.figure(figsize=(15,4)) to also show output text like you posted in your issue.
(I'll add for others looking at this later, that it is important have %matplotlib inline or %matplotlib notebook at the start of the cell (or at the start of a cell somewhere above this one.))
A complete guide on how to hide or remove content in Jupyter is available from the official documentation: https://jupyterbook.org/interactive/hiding.html#
For removing the single output line, you can tweak the command lines by adding a _ = [command ] assignment as suggested in this blog: https://www.tutorialguruji.com/python/suppress-output-in-matplotlib/.
The underscore there is a throwaway variable, actually an unidentified variable "when not in interactive mode". See the official Python documentation: https://docs.python.org/3.9/reference/lexical_analysis.html#reserved-classes-of-identifiers

Infinite loop while trying simple indentedBlock expression in pyparsing

I'm trying to parse indented blocks with pyparsing and indentedBlock
Here my code
from pyparsing import *
indent_stack = [1]
line = ungroup(restOfLine)
block = ungroup(indentedBlock(line, indent_stack))
# Work
data = """ foo
bar
tar
"""
block.parseString(data).pprint()
The problem is that parseString won't return. It seems to be waiting for more input or maybe I hit an infinite loop. If I put an unidnented line in the block start to work
data = """ foo
bar
tar
end
"""
But I want to be able to parse up to unindented line (the working case), or to the end of string (the not working case)
This is a bug in pyparsing. indentedBlock uses OneOrMore internally to implement the repetition of the embedded lines. But restOfLine does not fail if it is at the end of a line, and so once you get to the end of the string, indentedBlock's repetition just keeps finding empty restOfLines, and so indentedBlock just loops forever.
A workaround for now, until this bug gets fixed and released, is to change your definition of line from:
line = ungroup(restOfLine)
to
line = ungroup(~StringEnd() + restOfLine)
I couldn't figure out exactly why the code is doing this. I even tried running it in Debug mode and pausing, but it wouldn't even pause so that I could see where it was getting stuck.
A workaround you could use for now is modifying the data to add an unindented line:
from pyparsing import *
indent_stack = [1]
line = ungroup(restOfLine)
block = ungroup(indentedBlock(line, indent_stack))
# Work
data = """ foo
bar
tar
"""
block.parseString(data + "\nend").pprint()
# Result: [['foo'], ['bar'], ['tar']]

Shortening .write commands

I am learning from the book Learn Python The Hard Way 3.6, by Zed Shaw
There are a series of 6 target.write commands towards the bottom of the script and he wants me to simplify them into a single target.write command using strings formats and escapes. However, I am stuck.
Here is the original code:
from sys import argv
script, filename = argv
print(f"We're going to erase {filename}")
print("If you don't want that, hit CTRL-C (^C).")
print("If you do want that, hit RETURN.")
input("?")
print("Opening the file...")
target = open(filename,'w')
print("Truncating the file. Goodbye!")
target.truncate()
print("Now I'm going to ask you for three lines")
line1 = input("line 1:")
line2 = input("line 2:")
line3 = input("line 3:")
print("Im going to write these to the file.")
target.write(line1)
target.write("\n")
target.write(line2)
target.write("\n")
target.write(line3)
target.write("\n")
print("And finnaly, we close it")
target.close()
So far I have tried
target.write(line1),(line2),(line3)
but this gives a logical error of only writing to one line not all three.
target.write(line1) + (line2) + (line3)
with this one I get error
'unsupported operand types for +: 'int' + 'str'
target.write(line1),\n,(line2)\n(line3),\n
with this one I get error:
unexpected character after line continuation character
(<string>,line 22)
I have been googling and searching here for answers but have not found anything. One person posted a very similar question except for Zed's 2.7 book. However I am reading Zed's 3.6 book so the answers were no help to me unfortunately.
I'm not sure what you have and haven't covered so far in the book as I'm not familiar with it but one way to do what you want is to format the string first and then pass it to the write method like this:
target.write("{0}\n{1}\n{2}\n".format(line1, line2, line3))

Resources