Matplotlib Datum formatieren

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
Hypec
User
Beiträge: 183
Registriert: Mittwoch 1. August 2018, 16:11

Hallo hat irgendwer eine Idee wie ich hier in diesem Beispiel das Datum so anzeigen lassen kann das man es komplett lesen kann?

Code: Alles auswählen

from flask import Flask, render_template, url_for, request, make_response
import matplotlib 
matplotlib.use('agg') 
import matplotlib.pyplot as plt     #Csv Daten plotten
import datetime                     #Uhrzeit
import pytz                         #Zeitzone
import csv                          #Csv Datei schreiben
import io
import pandas as pd

PLOTS = {
    'luftfeuchtigkeit': {
        'title': 'Luftfeuchtigkeit',
        'ylabel': 'Luftfeuchtigkeit in %',
        'plots': [('luftfeuchtedrin', 1), ('luftfeuchteausen', 3)]
    },
    'temperatur': {
        'title': 'Temperatur',
        'ylabel': 'Temperatur in °C',
        'plots': [("Temperatur drin", 2), ("Temperatur ausen", 4)]
    },
    'erdfeuchtigkeit': {
        'title': 'Erdfeuchtigkeit',
        'ylabel': 'Erdfeuchtigkeit in %',
        'plots': [('Erdfeuchtigkeit', 5)]
    },
    'lux': {
        'title': 'Lichtitensität',
        'ylabel': 'Lichtitensität in Lux',
        'plots': [('Lichtitensität(lux)', 6)]
    },
}

app = Flask(__name__)

@app.route('/')
@app.route('/index')
def index():
    return render_template('index.html')

@app.route('/test')
def test():
    return render_template('test.html')

@app.route('/getdata', methods=['GET', 'POST'])
def getdata():
    if request.method == 'POST':
        file = open('test.txt', "a")
        data = request.data
        my_date = datetime.datetime.now(pytz.timezone('Europe/Berlin'))
        fmt = "%Y-%m-%d %H:%M:%S"
        for i in data:
                file.write(my_date.strftime(fmt) + "; ")
                file.write(str(data) + '\n')        
        return data
    return render_template('getdata.html')


@app.route('/image/<filename>', methods=['GET'])
def daten(filename):
    data_one = filename.split('.')[0]
    with open('data/data.csv') as lines:
        reader = csv.reader(lines, delimiter=',')
        tabelle = [
            row[:1] + [float(c) for c in row[1:]]
            for row in reader
        ]

    time = [zeile[0] for zeile in tabelle]
    plot = PLOTS[data_one]
    fig, ax = plt.subplots()
    for label, idx in plot['plots']:
        ax.plot(time, [zeile[idx] for zeile in tabelle], label=label)
    ax.grid(True)
    fig.legend()
    ax.set_title(plot['title'])
    ax.set_ylabel(plot['ylabel'])
    ax.set_xlabel('Uhrzeit')

    buffer = io.BytesIO()
    plt.savefig(buffer, format = 'png')
    plot_data = buffer.getvalue()

    response = make_response(plot_data)
    response.headers['Content-type'] = 'image/png'
    return response

@app.route('/data', methods=['GET', 'POST'])
def data():
    data_one = ""
    src = '/image/' + data_one + '.png'
    if request.method == 'POST':
        data_one = request.form['data_one']
        src = '/image/' + data_one + '.png'
    else:
        data_one = None
    return render_template('benutzer.html', data_one=data_one, src=src)

if __name__ == '__main__': app.run(debug=True)

Code: Alles auswählen

{% extends "base.html" %}
{% block content %}
    <h1>Upload new Data</h1>
    <br>
    <form method = "post">
            <div class="row">
                <div class="col-25">
                  <label for="data_one">Messdaten:</label>
                </div>
                <div class="col-75">
                  <select id="data_one" name="data_one">
                    <option value="luftfeuchtigkeit">Luftfeuchtigkeit</option>
                    <option value="temperatur">Temperatur</option>
                    <option value="erdfeuchtigkeit">Erdfeuchtigkeit</option>
                    <option value="lux">Lux</option>
                  </select>
                </div>
            </div>
        <input type = "submit" value = "submit" />
    </form>
{%if data_one %}<img src={{src}}>{%endif%}
{% endblock %}
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Eigentlich solle die Form keine POST-Methode sondern GET benutzt werden, weil man ja ein Bild anfordert und keine Daten hochladen will. Wenn keine from-Daten gesendet werden, ist der src-Link kaputt. `data_one` aus der ersten Zeile wird nicht benutzt.

Code: Alles auswählen

@app.route('/data', methods=['GET', 'POST'])
def data():
    data_one = request.form.get('data_one')
    return render_template('benutzer.html', data_one=data_one, plots=PLOTS)

Code: Alles auswählen

{% extends "base.html" %}
{% block content %}
    <h1>Upload new Data</h1>
    <br>
    <form method = "GET">
            <div class="row">
                <div class="col-25">
                  <label for="data_one">Messdaten:</label>
                </div>
                <div class="col-75">
                  <select id="data_one" name="data_one">
{%for key, entry in plots.items() %}
                    <option value="{{key}}">{{entry.title}}</option>
{% endfor %}
                  </select>
                </div>
            </div>
        <input type = "submit" value = "submit" />
    </form>
{%if data_one %}<img src="/image/{{data_one}}.png">{%endif%}
{% endblock %}
Im anderen Beitrag benutzt Du Pandas zum Lesen der Daten. Das kann auch plotten.
Hypec
User
Beiträge: 183
Registriert: Mittwoch 1. August 2018, 16:11

Das ganze funktioniert schon so aber die Anzeige kann man nicht lesen https://pythonv1.herokuapp.com/image/temperatur
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Bei GET vs. POST fällt mir hier noch auf, dass man wenn da immer aktuelle Daten im Bild angezeigt werden sollen, vielleicht bei der Bilddatei noch im Header sagen sollte das der Browser es nicht oder nur entsprechend kurz cachen sollte.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Hypec
User
Beiträge: 183
Registriert: Mittwoch 1. August 2018, 16:11

Danke für die Tipps, aber das alles beantwortet meine Frage, wie ich unten das Datum so anzeigen kann das man es lesen kann, leider nicht.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Hypec: Du könntest die Datumsangaben schräg oder vielleicht sogar komplett vertikal ausrichten.

Edit: Und/oder weil da ja Uhrzeit als Achsenbeschriftung steht, einfach nur die Uhrzeit ausgeben und das Datum mit in die Achsenbeschriftung oder den Titel/Untertitel nehmen. Wenn es mehr als ein Tag ist, könnte man die Datumsangaben vielleicht auch als Major-Ticks und die Stunden dazwischen als Minor-Ticks setzen.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@Hypec: hast Du Dir schon die Beispiele auf der Matplotlib-Seite angeschaut? Das ist immer die erste Anlaufstelle.

Date tick labels

Custom tick formatter for time series
Antworten