Simple way to plot multi-color line in matplotlib

There are multiple ways of plotting a multi-color line in matplotlib. A special property of the plot command allowing plotting multiple datasets in columns of 2D arrays makes it possible to do this with a single plot command using the cycler for the colors. Here are a sample code segment for this.

Generate sample data

import numpy as np
import matplotlib.pyplot as plt
from cycler import cycler

x = np.linspace(-np.pi,np.pi,9)
y = np.sin(x)
rng = np.random.default_rng(123)
c = rng.uniform(size=(len(x),3))

plt.scatter(x,y,c=c)
plt.show()

Quick plotting with line colors

plt.gca().set_prop_cycle(cycler('color',c[:-1]))
plt.plot(np.c_[x[:-1],x[1:]].T,np.c_[y[:-1],y[1:]].T)
plt.show()

More careful plotting with point colors

y_ = (y[:-1]+y[1:])/2
x_ = (x[:-1]+x[1:])/2

plt.gca().set_prop_cycle(cycler('color',c[:-1]))
plt.plot(np.c_[x[:-1],x_].T,np.c_[y[:-1],y_].T)
plt.gca().set_prop_cycle(cycler('color',c[1:]))
plt.plot(np.c_[x_,x[1:]].T,np.c_[y_,y[1:]].T)
plt.show()

Day of the week calculation

For given date in year-month-day, the day of the week can be deduced for the rule of leap years [1] and the fact that January 1, 1 is a Monday [2].

Since a year is a leap year if the year number is a multiple of 4 that is not a multiple of 100 that is not a multiple of 400. The number of leap year up to year y is given by:

def num_leap(y):
    return y//4-y//100+y//400

For a common year, the numbers of days for the twelve months are:

[31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

The number of days before each month in a common year is calculated with:

p = 0
days_before_month = [
    [p, p := p + m][0] for m in
    [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
]
print('[',', '.join(map(str,days_before_month)),']',sep='')

The result is:

[0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]

Since the extra day of a leap year is added to February, the leap status of current year is only relevant when month number m<3. We can calculate the number of days from January 1, 1 as:

def day_number(y,m,d):
    return (y-1)*365+num_leap(y-(m<3))+days_before_month[m-1]+d

Or, pack everything in the function:

def day_number(y,m,d):
    return (y-1)*365+(lambda y:y//4-y//100+y//400)(y-(m<3))+[0,31,59,90,120,151,181,212,243,273,304,334][m-1]+d

[1] https://en.wikipedia.org/wiki/Leap_year
[2] https://en.wikipedia.org/wiki/AD_1

If you are good at finding things, what about searching for the meaning of all this?

Things that are important and things that matter are what should be prioritized. But, what are they? We need the meaning of all this to know. It’s not that we can not act without it. We can still try striking in the dark and hoping to hit something. With some intuition and educated guesses, things that we happen to hit may happen to align with what are meaningful. And, with luck, there may be more meaningfully good than the meaningfully bad.

Reverse SSH tunnel from a firewalled host

You have an SSH server A behind a firewall that you wish to connect to. You have no control over the firewall but has an account on an open SSH server B on the internet outside the firewall. You can setup a reverse tunnel from A to B so that you can connect to A through B from anywhere.

In the SSH configuration file A:~/.ssh/config, add the following section

Host b-tun
	HostName B
	ServerAliveInterval 30
	ExitOnForwardFailure yes
	RemoteForward 8822 localhost:22

Afterward, you can create the reverse tunnel on A by running ssh -Nf b-tun. and login with your credential on B or setup key authentication for automatic login. If the tunnel has been created successfully, you can now connect to the port 8822 of localhost on B to login to A, e.g., ssh -p 8822 localhost. If you have access to the nc command on B, you can add the section below to the ~/.ssh/config on a machine outside the firewall:

Host A
	ProxyCommand ssh -qax B 'nc -w 600 localhost 8822'
	ServerAliveInterval 30

You will then be able to connect to A with a simple ssh A on that machine.

You can also make the creation of the reverse tunnel automatic by creating a systemd unit, say, ~/.config/systemd/user/b-tun.service with the content

[Unit]
Description=Create SSH tunnel through B
After=network-online.target

[Service]
Type=idle
ExecStart=/usr/bin/ssh -N b-tun
RestartSec=39
Restart=always

[Install]
WantedBy=default.target

and start the process with systemctl --user start b-tun.service. You may need to enable unattended job for the user on A with loginctl enable-linger user as the root on A. To make the service start on boot automatically, you need to enable it with systemctl --user enable b-tun.service.

科學的邊際是信仰的起點

科學是我們對現實經驗的一種整合壓縮。它所包含的是這些經驗中可以被重複驗證的部分。而信仰是我們心中恆常的、未能在現實中實際證明的、但卻對我們行為及精神有重要影響的想法。兩者所涵蓋的範圍沒有重疊的理由。只是說,科學的範疇並不固定,而一般情況下,隨時代的演化會愈來愈廣闊。若是信仰的領域,或因為其恆常性的關係,不能及時修整,重疊的地方難免會發生。這時可能造成的衝突會是一個不幸的根源因素。

或許因為某些知識背景的關係,我們會想:科學怎麼會有邊呢?即使有也應該只是暫時的吧!總有一天我們將可以解釋驗證所有的現實經驗。屆時,還會有信仰的空間嗎?這樣想法的一大挑戰應該就是量子力學吧。如果我的理解可靠的話,它告訴我們:不可確定性是真實存在的。而在某些尺度條件下,科學所能告訴我們的,僅是各個不同結果發生的可能機率而已。

而另一個可以的開口則是宇宙的初始條件問題:即使我們有的是一個封閉的宇宙,沒有辦法排除的是,在開端的那一點,是不是有別的系統和我們糾纏在一起。而這與我們糾纏的系統也有可能會比我們要大而複雜許多,其可能透過這樣的糾纏性而對我們的演變造成的影響也不是我們可以重複驗證出來的。

L1 or L2 in Support Vector Machine of scikit-learn

The SVC in the sklearn.svm sub-module claims to use “a squared l2 penalty”. However, the mathematical formulation in the user guide describes an L1 penalty term. Unless I have misunderstood the writing, there must be an error among the two.

Since the implementation claims to use the libsvm, which has similar documentation with linear slack terms, I am assuming the SVC is actually L1 instead of L2 as suggested by the API documentation.