Способ сделать это - передать массив date
вместе с массивом data
в методе plot. То есть с данным примером это будет:
import numpy as np
import datetime as dt
import matplotlib.pyplot as plt
from matplotlib.dates import (DateFormatter, rrulewrapper, RRuleLocator, YEARLY)
# Generate random data and dates
data = np.random.randn(10000)
start = dt.datetime.strptime("2019-03-14", "%Y-%m-%d")
end = dt.datetime.strptime("2046-07-30", "%Y-%m-%d")
date = [start + dt.timedelta(days=x) for x in range(0, (end-start).days)]
rule = rrulewrapper(YEARLY, byeaster=1, interval=2)
loc = RRuleLocator(rule)
formatter = DateFormatter('%d/%m/%y')
fig, ax = plt.subplots()
ax.xaxis.set_major_locator(loc)
ax.xaxis.set_major_formatter(formatter)
ax.xaxis.set_tick_params(rotation=30, labelsize=10)
plt.plot(date, data)
ax.set_xlim(min(date), max(date))
plt.show()
Тогда вы получите:
См. matplotlib.pyplot.plot () для получения дополнительной информации.
Взгляните на Асинхронный ввод-вывод . Это освободит процессор, чтобы продолжить выполнение других задач.
Объедините с ReaderWriterLock , как упоминал @Jack B Nimble
Если по
записывает в файловую систему как как можно более эффективный
вы имеете в виду, как сделать фактический файловый ввод-вывод как можно более быстрым, вам будет трудно значительно его ускорить, диск просто физически медленнее. Может SSD?
Сохраните для входа с Очередью и несколькими потоками (.Net Core 2.2, к которому образцу Linux - протестированный)
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
// add
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.Net.Security;
using System.Security.Authentication;
using System.IO;
using System.Timers;
namespace LogToFile
{
class Program
{
public static Logger logger = new Logger("debug.log");
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
logger.add("[001][LOGGER STARTING]");
Thread t0 = new Thread(() => DoWork("t0"));
t0.Start();
Thread t1 = new Thread(() => DoWork("t1"));
t1.Start();
Thread t2 = new Thread(() => DoWork("t2"));
t2.Start();
Thread ts = new Thread(() => SaveWork());
ts.Start();
}
public static void DoWork(string nr){
while(true){
logger.add("Hello from worker .... number " + nr);
Thread.Sleep(300);
}
}
public static void SaveWork(){
while(true){
logger.saveNow();
Thread.Sleep(50);
}
}
}
class Logger
{
// Queue import:
// using System.Collections
public Queue logs = new Queue();
public string path = "debug.log";
public Logger(string path){
this.path = path;
}
public void add(string t){
this.logs.Enqueue("[" + currTime() +"] " + t);
}
public void saveNow(){
if(this.logs.Count > 0){
// Get from queue
string err = (string) this.logs.Dequeue();
// Save to logs
saveToFile(err, this.path);
}
}
public bool saveToFile(string text, string path)
{
try{
// string docPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
// text = text + Environment.NewLine;
using (StreamWriter sw = File.AppendText(path))
{
sw.WriteLine(text);
sw.Close();
}
}catch(Exception e){
// return to queue
this.logs.Enqueue(text + "[SAVE_ERR]");
return false;
}
return true;
}
public String currTime(){
DateTime d = DateTime.UtcNow.ToLocalTime();
return d.ToString("yyyy-MM-dd hh:mm:ss");
}
}
}
Компиляция (Сохраняют: LogToFile/Program.cs):
dotnet new console -o LogToFile
cd LogToFile
dotnet build
dotnet run
приложение Остановки CTRL+C и посмотрите файл журнала
cat debug.log
Можно использовать события для регистратора:
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace EventLogger
{
class Program
{
static void Main(string[] args)
{
// Event handler
LogData ld = new LogData();
// Logger
Logger lo = new Logger();
// Subscribe to event
ld.MyEvent += lo.OnMyEvent;
// Thread loop
int cnt = 1;
while(cnt < 5){
Thread t = new Thread(() => RunMe(cnt, ld));
t.Start();
cnt++;
}
Console.WriteLine("While end");
}
// Thread worker
public static void RunMe(int cnt, LogData ld){
int nr = 0;
while(true){
nr++;
// Add user and fire event
ld.AddToLog(new User(){Name = "Log to file Thread" + cnt + " Count " + nr, Email = "em@em.xx"});
Thread.Sleep(1);
}
}
}
class LogData
{
public delegate void MyEventHandler(object o, User u);
public event MyEventHandler MyEvent;
protected virtual void OnEvent(User u)
{
if(MyEvent != null){
MyEvent(this, u);
}
}
// Wywołaj
public void AddToLog(User u){
Console.WriteLine("Add to log.");
// Odpal event
OnEvent(u);
Console.WriteLine("Added.");
}
}
class User
{
public string Name = "";
public string Email = "";
}
class Logger
{
// Catch event
public void OnMyEvent(object o, User u){
try{
Console.WriteLine("Added to file log! " + u.Name + " " + u.Email);
File.AppendAllText(@"event.log", "Added to file log! " + u.Name + " " + u.Email+"\r\n");
}catch(Exception e){
Console.WriteLine("Error file log " + e);
}
}
}
}
Используйте Reader / Writer блокировки для доступа файловый поток.