QPrinter margins under Py3 and PyQt5 - python-3.x

I am updating my program under Python3 and PyQt5, I use QPrinter to associate different small texts (and also images) in a single PDF document. The Python2 and PyQt4 version of the program works well, but by passing it under PyQt5 (and QPrinter) I have a problem with the margins (they are much too wide afterwards); it seems that setPageMargins is not working well (at least not as well as in QPrinter's PyQt4 version). I wrote a little script inspired by the one present in my program:
#!/usr/bin/python
#-*- coding: utf-8 -*-
import sys, os
from PyQt5.QtPrintSupport import QPrinter
from PyQt5.QtGui import QTextDocument
from PyQt5.QtWidgets import QApplication
class Html_vers_pdf_fiche_eleve(QPrinter):
def __init__(self, niv_de_classe, nbre_seances, titre_prog, num_seq, incitation, demande, vocabulaire, questions, texte_ref_art_1, texte_ref_art_2, texte_ref_art_3, vignette_img_src_1, vignette_img_src_2, vignette_img_src_3, marge_gauche, marge_haute, marge_droite, marge_basse, police_normaux_caracteres, police_petits_caracteres):
super(Html_vers_pdf_fiche_eleve, self).__init__(QPrinter.HighResolution)
# Rubriques ...
variable_001 = "Classe :"
variable_002 = "Date :"
variable_003 = "Durée :"
variable_004 = "Nom :"
variable_005 = "Prénom :"
variable_006 = "Titre de la progression :"
variable_007 = "Séquence n° :"
variable_008 = "Incitation :"
variable_009 = "Demande :"
variable_010 = "Vocabulaire :"
variable_011 = "Questions (répondre derrière cette feuille) EVENTUELLEMENT ECRIRE UN COMMENTAIRE :"
variable_012 = ''
variable_014 = "Travaux d'artistes (références) :"
variable_015 = "Les élèves, évaluez vontre travail en utilisant les smileys juste en dessous de Eval Elève"
variable_016 = "Eval Elève"
variable_017 = "Evaluation Professeur"
variable_018 = "Ci-dessous se trouvent les critères d'évaluation des compétences travaillées en arts plastiques"
# HTML ; écriture de l'entête
html_entete = '''<html><head><title></title>'''+'''\n'''+'''<style type="text/css">'''+'''\n'''+'''table { border-style:solid;border-width:1.3px;border-color:#3c3c3c;font-size:'''+str(police_normaux_caracteres)+'''pt;font-family: "DejaVu Sans, sans-serif" }'''+'''\n'''+'''</style>'''+'''\n'''+'''</head>'''+'''\n'''+'''<body>'''+'''\n'''
# HTML ; écriture du niveau de classe, de la date et de la durée
html_tab_ligne_0 = '''<table width="100%" cellpadding="3"
cellspacing="0.5">'''+'''\n'''+'''<tr>'''+'''\n'''+'''<td width="22%"><p><b>'''+str(variable_001)+''' '''+str(niv_de_classe)+'''ème</b></p></td>'''+'''\n'''+'''<td width="35%"><p><b>'''+str(variable_002)+'''</b></p></td>'''+'''\n'''+'''<td width="43%"><p><b>'''+str(variable_003)+''' '''+nbre_seances+'''</b></p></td>'''+'''\n'''+'''</tr>'''+'''\n'''+'''</table>'''+'''\n'''
# HTML ; écriture du nom et du prénom
html_tab_ligne_1 = '''<table width="100%" cellpadding="3"
cellspacing="0.5">'''+'''\n'''+'''<tr>'''+'''\n'''+'''<td width="50%"><p><b>'''+str(variable_004)+'''</b></p></td>'''+'''\n'''+'''<td width="50%"><p><b>'''+str(variable_005)+'''</b></p></td>'''+'''\n'''+'''</tr>'''+'''\n'''+'''</table>'''+'''\n'''
# HTML ; écriture du titre de la progression et du numéro de la séquence
html_tab_ligne_2 = '''<table width="100%" cellpadding="3"
cellspacing="0.6">'''+'''\n'''+'''<tr>'''+'''\n'''+'''<td width="83%"><p><b><u>'''+str(variable_006)+'''</u>'''+''' '''+titre_prog+'''</b></p></td>'''+'''\n'''+'''<td width="17%"><p><u><b>'''+str(variable_007)+'''</u>'''+''' <b>'''+str(num_seq)+'''</b></p></td>'''+'''\n'''+'''</tr>'''+'''\n'''+'''</table>'''+'''\n'''
# HTML ; écriture de l'incitation
html_tab_ligne_3 = '''<table width="100%" cellpadding="3"
cellspacing="0.5">'''+'''\n'''+'''<tr>'''+'''\n'''+'''<td width="100%" bgcolor="#e1dede"><p><b><u>'''+str(variable_008)+'''</u>'''+''' '''+incitation+'''</b></p></td>'''+'''\n'''+'''</tr>'''+'''\n'''+'''</table>'''+'''\n'''
# HTML ; écriture de la demande
html_tab_ligne_4 = '''<table width="100%" cellpadding="3"
cellspacing="0.6">'''+'''\n'''+'''<tr>'''+'''\n'''+'''<td width="100%" bgcolor="#e1dede"><p><b><u>'''+str(variable_009)+'''</u></b>'''+''' '''+demande+'''</p></td>'''+'''\n'''+'''</tr>'''+'''\n'''+'''</table>'''+'''\n'''
# HTML ; écriture de l'entête de la liste des mots de vocabulaire
html_tab_ligne_5 = '''<table width="100%" cellpadding="3"
cellspacing="0.5" bgcolor="#cccccc">'''+'''\n'''+'''<tr>'''+'''\n'''+'''<td width="100%"><p><b><u>'''+str(variable_010)+'''</u></b></p></td>'''+'''\n'''+'''</tr>'''+'''\n'''+'''</table>'''+'''\n'''
# HTML ; écriture de la liste des mots de vocabulaire
html_tab_ligne_6 = '''<table width="100%" cellpadding="3"
cellspacing="0.5">'''+'''\n'''+'''<tr>'''+'''\n'''+'''<td width="100%"><p>'''+vocabulaire+'''</p></td>'''+'''\n'''+'''</tr>'''+'''\n'''+'''</table>'''+'''\n'''
# HTML ; écriture de l'entête des questions posées aux élèves
html_tab_ligne_7 = '''<table width="100%" cellpadding="3"
cellspacing="0.5" bgcolor="#cccccc">'''+'''\n'''+'''<tr>'''+'''\n'''+'''<td width="100%"><p><u><b>'''+str(variable_011)+'''</b></u></p></td>'''+'''\n'''+'''</tr>'''+'''\n'''+'''</table>'''+'''\n'''
# HTML ; écriture des questions posées aux élèves
html_tab_ligne_8 = '''<table width="100%" cellpadding="3"
cellspacing="0.5">'''+'''\n'''+'''<tr>'''+'''\n'''+'''<td width="100%"><p><b>'''+questions+'''</b></p></td>'''+'''\n'''+'''</tr>'''+'''\n'''+'''</table>'''+'''\n'''
# HTML ; écriture de l'entête Travaux d'artistes (références)
html_tab_ligne_9 = '''<table width="100%" cellpadding="3"
cellspacing="0.5" bgcolor="#cccccc">'''+'''\n'''+'''<tr>'''+'''\n'''+'''<td width="100%"><p><u><b>'''+str(variable_014)+'''</b></u></p></td>'''+'''\n'''+'''</tr>'''+'''\n'''+'''</table>'''+'''\n'''
#html_tab_ligne_9 = html_tab_ligne_9.decode('utf-8')
# HTML ; écriture du nom de l'artiste, de l'oeuvre, d'un résumé et des vignettes correspondantes
html_tab_ligne_10 = '''<table width="100%" cellpadding="3"
cellspacing="0.5">'''+'''\n'''+'''<tr>'''+'''\n'''+'''<td width="33%"><font color="#000000" size="'''+str(police_petits_caracteres)+'''" family="DejaVu Sans, sans-serif"><b>'''+texte_ref_art_1+'''</b></font><br />'''+'''<div align="center">'''+vignette_img_src_1+'''</div><p />'''+'''</td>'''+'''\n'''+'''<td width="33%"><font color="#000000" size="'''+str(police_petits_caracteres)+'''" family="DejaVu Sans, sans-serif"><b>'''+texte_ref_art_2+'''</b></font><br />'''+'''<div align="center">'''+vignette_img_src_2+'''</div><p />'''+'''</td>'''+'''\n'''+'''<td width="34%"><font color="#000000" size="'''+str(police_petits_caracteres)+'''" family="DejaVu Sans, sans-serif"><b>'''+texte_ref_art_3+'''</b></font><br />'''+'''<div align="center">'''+vignette_img_src_3+'''</div><p />'''+'''</td>'''+'''\n'''+'''</tr>'''+'''\n'''+'''</table>'''+'''\n'''
# HTML ; écriture de la fin de la page
html_body_html_final = '''</body></html>'''
#
self.doc = QTextDocument()
# Ecriture de la syntaxe HTML finale
self.doc.setHtml(html_entete + html_tab_ligne_0 + html_tab_ligne_1 + html_tab_ligne_2 + html_tab_ligne_3 + html_tab_ligne_4 + html_tab_ligne_5 + html_tab_ligne_6 + html_tab_ligne_7 + html_tab_ligne_8 + html_tab_ligne_9 + html_tab_ligne_10 + html_body_html_final)
# Ecriture du fichier PDF par QPrinter
self.printer = QPrinter(QPrinter.HighResolution)
self.printer.setOutputFormat(QPrinter.PdfFormat)
self.printer.setOrientation(QPrinter.Portrait)
self.printer.setPaperSize(QPrinter.A4)
# La taille des marges est convertie en millimètres
self.printer.setPageMargins(int(marge_gauche*10), int(marge_haute*10), int(marge_droite*10), int(marge_basse*10), QPrinter.Millimeter)
print("Le fichier pdf a été crée !")
self.printer.setOutputFileName("test.pdf")
# Ecriture finale du fichier PDF
self.doc.print_(self.printer)
if __name__ == '__main__':
app = QApplication(sys.argv)
#############################################
# Pictures (3 pictures)
img_ref_art_1 = os.path.expanduser('~')+os.sep+"college/cours/Cours_Travaux_a_faire__COLLEGE_NOUVEAUX_PROGRAMMES/Niveau_3eme_cycle_4/sequence_eleve/tom_wesselmann_still_life_20_vue_01.jpg"
img_ref_art_2 = os.path.expanduser('~')+os.sep+"college/cours/Cours_Travaux_a_faire__COLLEGE_NOUVEAUX_PROGRAMMES/Niveau_3eme_cycle_4/sequence_eleve/georges_melies_le_voyage_ds_la_lune_1902.png"
img_ref_art_3 = os.path.expanduser('~')+os.sep+"college/cours/Cours_Travaux_a_faire__COLLEGE_NOUVEAUX_PROGRAMMES/Niveau_3eme_cycle_4/sequence_eleve/louise_nevelson_sky_cathedral_bois_peint_en_noir_1958.png"
# (Réglages) Valeurs des marges
marge_gauche = 0.00 # marge en cm
marge_droite = 0.00 # marge en cm
marge_haute = 0.00 # marge en cm
marge_basse = 0.00 # marge en cm
# (Réglages) Taille de la police
# ------------------------------------------
# Texte partie générale (taille de la police)
taille_police_texte_general = 8 # (valeurs entre 6 et 10, 8 par défaut)
# Texte travaux d'artistes et évaluation (taille de la police)
taille_police_trav_artist = 2 # (valeurs 1 ou 2, 2 par défaut)
liste_vocab = ['<b><u>Mot de vocabulaire 1 :</u></b> La définition du mot de vocabulaire 1 ... '+'bla bla blablablabla '*10+'<br />', '<b><u>Mot de vocabulaire 2 :</u></b> La définition du mot de vocabulaire 2.<br />', '<b><u>Mot de vocabulaire 3 :</u></b> La définition du mot de vocabulaire 3 ...'+'bla bla blablablabla '*14+'<br />', '<b><u>Mot de vocabulaire 4 :</u></b> La définition du mot de vocabulaire 4 ...'+'bla bla blablablabla '*17+'<br />', '<b><u>Mot de vocabulaire 5 :</u></b> La définition du mot de vocabulaire 5.<br />', '<b><u>Mot de vocabulaire 6 :</u></b> La définition du mot de vocabulaire 6.<br />', '<b><u>Mot de vocabulaire 7 :</u></b> La définition du mot de vocabulaire 7 ...'+'bla bla blablablabla '*5+'<br />', '<b><u>Mot de vocabulaire 8 :</u></b> La définition du mot de vocabulaire 8.']
liste_questions = ["1) Est-ce que QPrinter est intéressant ?, ... oui en fait.<br />", "2) Est-ce que c'est facile à manipuler ?, ... oui quand on a compris comment ça fonctionne.<br />", "3) Est-ce que QPrinter est pratique ?, ... oui oui !, dans mon cas pour faire quelque chose en full Python, sans devoir appeler (et embarquer) un programme tiers."]
liste_textes_art = ['''* Tom Wesselmann, "Still Life 20" (1962). Résumé du contexte de l'oeuvre ... '''+"bla bla blablablabla "*16, '''* Georges Meliès, "Le voyage dans la lune" (1902). Résumé du contexte de l'oeuvre ...'''+"bla bla blablablabla "*18, '''* Louise Nevelson, "Sky cathedral" (1958) ... bois peint en noir ...'''+"bla bla blablablabla "*10]
liste_img_src_ref_art = ['''<img src="'''+img_ref_art_1+'''"'''+''' width="150" height="146" />''', '''<img src="'''+img_ref_art_2+'''"'''+''' width="150" height="100" />''', '''<img src="'''+img_ref_art_3+'''"'''+''' width="150" height="109" />''']
#############################################
# Appel de la classe
Html_vers_pdf_fiche_eleve(3, "2 à 3 séances", "" Une progression avec un titre "", 1, "" Une incitation qui n'en dit pas trop ! "", "La demande est faite pour faire en sorte que l'élève comprenne un peu plus ce qu'il y a à faire mais en même temps cette demande ne lui donne pas trop de pistes de travail afin que la situation problème (énoncée par l'incitation) soit tout de même présente."+" Blabla blablabla "+"blablabla blabla"*32, ''.join(liste_vocab), ''.join(liste_questions), liste_textes_art[0], liste_textes_art[1], liste_textes_art[2], liste_img_src_ref_art[0], liste_img_src_ref_art[1], liste_img_src_ref_art[2], marge_gauche, marge_haute, marge_droite, marge_basse, taille_police_texte_general, taille_police_trav_artist)
Output:
Maybe it's a PyQt5 bug at this level, or has the syntax for using QPrinter changed in margin management?
My version of Python: 3.4.3 and my version of PyQt5: 5.2.1.
Can you help me ?

Related

Probelm with my webapp, how can I solve it?

I have a small big problem with an app I have created, using Python and Streamlit.
The problem is that when I want to deploy it to the Heroku services, it builds, but when I try to access it, it tells me that there is an applicaiton error.
I have looked at my code, whcih on the local machine works pefectly.
Do you have any idea?
Code:
# Loading packages ##########################################################################
import streamlit as st
import numpy as np
import networkx as nx
from pyvis.network import Network
# import plotly.express as px
###############################################################################################
st.set_page_config(layout="wide")
##### Creazione Sidebar ####################################################################
st.sidebar.title('Ottimizzazione')
st.sidebar.header('Creazione matrice')
st.sidebar.write('Scrivere la matrice quadrata come da esempio Matrice: 1,2;4,5')
st.sidebar.write('Usare la , per separe le varie colonne e il ; per andare alla prossima riga')
input_matrice=st.sidebar.text_area('Scrivere Matrice:')
# Creazione matrice
matrice = np.matrix(input_matrice)
matrice_array = np.asarray(matrice)
##### Creazione Due colonne per output ##############################################################
left_column1, right_column1 = st.beta_columns(2)
left_column2, right_column2 = st.beta_columns(2)
## Visualizzazione matrice
with left_column1:
st.header('Matrice Quadrata Creata:')
matrice_array
with right_column1:
st.header('Visualizzazione del grafo:')
st.write('Il grafo verrà visualizzato in una apgina separata, in quanto al momento non riuslta possible integrarlo nella pagina pricipale')
##### Creaizone Input per calcolo #######################################################
st.sidebar.header('Calcolo percorso:')
st.sidebar.write('Calcolo del percorso più corto, Nx nodo di partenza e Ny nodo di arrivo. I nodi della matrice corrispondono agli indici della colonna.')
selezione = st.sidebar.radio("Seleziona tipo di calcolo",('Da Nx a tutti più vicini','Da Nx a Ny'))
if selezione == 'Da Nx a tutti più vicini':
nodo_partenza=np.int(st.sidebar.number_input('Scrivere nodo di partenza (Numero intero):'))
bottone_calcolo = st.sidebar.button('Calcola percorso', key=1)
if bottone_calcolo:
grafo_matrice = nx.from_numpy_matrix(matrice_array)
percorso = nx.single_source_dijkstra_path(grafo_matrice, nodo_partenza, weight='weight')
lunghezza = nx.single_source_dijkstra_path_length(grafo_matrice, nodo_partenza, weight='weight')
with left_column2:
st.header('Percorsi:')
st.write('Qui vengono mostrati i vari percorsi che sono stati trovati. I valori a destra corrispondono al ordine di successione, mentre I valori a destra i vari nodi.')
percorso
with right_column2:
st.header('Tempi percorsi:')
st.write('Qui vengono mostrati i vari tempi dei vari percorsi')
lunghezza
with right_column1:
nt=Network("1000px","1000px")
nt.from_nx(grafo_matrice)
nt.show("nx.html")
elif selezione == 'Da Nx a Ny':
nodo_partenza=np.int(st.sidebar.number_input('Scrivere nodo di partenza (Numero intero):'))
nodo_arrivo=np.int(st.sidebar.number_input('Scrivere nodo di arrivo (Numero intero):'))
bottone_calcolo = st.sidebar.button('Calcola percorso', key=2)
if bottone_calcolo:
grafo_matrice = nx.from_numpy_matrix(matrice_array)
percorso = nx.shortest_path(grafo_matrice, source=nodo_partenza, target=nodo_arrivo, weight='weight')
lunghezza = nx.shortest_path_length(grafo_matrice, source=nodo_partenza, target=nodo_arrivo, weight='weight')
with left_column2:
st.header('Percorso:')
st.write('Qui viene mostrato il percorso trovato. I valori a destra corrispondono al ordine di successione, mentre I valori a destra i vari nodi.')
percorso
with right_column2:
st.header('Tempo percorso:')
st.write('Qui viene mostrato il tempo totale del pecrorso più breve')
lunghezza
with right_column1:
nt=Network("1000px","1000px")
nt.from_nx(grafo_matrice)
nt.show("nx.html")
Requirements:
streamlit==0.75.0
numpy==1.19.2
networkx==2.5.0
pyvis==0.1.9
Thank you for the help!
I solved the issue, it appear the problem was not in the code, but inside the command of the code for running the webapp

Python scraping regex (word just next to the number)

I hope you're well. I'd like to scrape different data with regex :)
#Récupération des ingrédients
try:
ingredients = [item.text.replace("\n", "").strip() for item in soup.find_all("li", {"class": "recipe-ingredients__list__item"})]
except Exception as e:
ingredients = None
Here is the json result
"ingredients": [
"250g de porc h\u00e2ch\u00e9 (le filet mignon c'est vraiment bon)",
"1 oignon blanc",
"1 carotte",
"6 champignons parfum\u00e9s chinois (pas des champignons noirs)",
"1poign\u00e9e de vermicelles de riz (cheveux d'ange)",
"1poign\u00e9e de germes de soja",
"3 oeufs",
"2gousses d'ail",
"Galette de riz vietnamiennes (les grandes)",
"4cuill\u00e8res \u00e0 soupe de nuoc mam",
"Poivre"
Do you how I can scrape separately
the quantity (here is the number)
the quantifying (which always sticks to the number when it exists)
the name of the ingredient
I do not find how to do it with regex
Thanks for your response #Ryszard Czech :) it's the first time use regex. If I want to save directly the separated data in json:
what should be the code something like that?
#Récupération des ingrédients
try:
ingredients = [item.text.replace("\n", "").strip() for item in soup.find_all("li", {"class": "recipe-ingredients__list__item"}, [re.compile(r'^(?:(\d+)([^\W\d_]*))?(.*)', x), for x in ingredients])]
except Exception as e:
ingredients = None
Or do I need to use some pattern to apply to ingredients
Use
import json, re
j="""{"ingredients": [
"250g de porc h\u00e2ch\u00e9 (le filet mignon c'est vraiment bon)",
"1 oignon blanc",
"1 carotte",
"6 champignons parfum\u00e9s chinois (pas des champignons noirs)",
"1poign\u00e9e de vermicelles de riz (cheveux d'ange)",
"1poign\u00e9e de germes de soja",
"3 oeufs",
"2gousses d'ail",
"Galette de riz vietnamiennes (les grandes)",
"4cuill\u00e8res \u00e0 soupe de nuoc mam",
"Poivre"]}"""
jsObj = json.loads(j)
print( [re.findall(r'^(?:(\d+)([^\W\d_]*))?(.*)', x) for x in jsObj["ingredients"]] )
Output:
[[('250', 'g', " de porc hâché (le filet mignon c'est vraiment bon)")], [('1', '', ' oignon blanc')], [('1', '', ' carotte')], [('6', '', ' champignons parfumés chinois (pas des champignons noirs)')], [('1', 'poignée', " de vermicelles de riz (cheveux d'ange)")], [('1', 'poignée', ' de germes de soja')], [('3', '', ' oeufs')], [('2', 'gousses', " d'ail")], [('', '', 'Galette de riz vietnamiennes (les grandes)')], [('4', 'cuillères', ' à soupe de nuoc mam')], [('', '', 'Poivre')]]
The ^(?:(\d+)([^\W\d_]*))?(.*) expression matches optionally one or more digits (capture 1) and an optional letters after (capture 2), and then captures the rest into capture 3.

Globcolour data and projection error in Python

I'm having trouble displaying some data from Globcolour (1), due to the projection used with the matplotlib and cartopy definition of the image.
I downloaded a Total Suspended Matter image in NetCDF format (here is the data enter link description here), and when I tried to display it, along with a coastline from the cartopy package, there is a notorious gap between the coastline and the data. As you can see below, the pixels should be next to the coastline (black line), and not surpassed into the land (yellow pixels in the flags image)
This shouldn't happen. I check using QGIS and loading directly the netcdf file the coastline is set correctly.
Initially I used a PlateeCarrer projection for the image, considering that if the image was in WGS84 they would match, but clearly they don't. I've tried using the transform option in the matplotlib function but I haven't made it work. Either the gap remains, or the coordinates of the figure change to projected ones and my data (which is in geographical coordinates) disappear.
The attributes of the NetCDF file are:
'grid_type': 'Equirectangular',
'spatial_resolution': 4.6383123,
'nb_equ_bins': 55,
'registration': 5,
'lat_step': 0.041666668,
'lon_step': 0.041666668,
'earth_radius': 6378.137,
'max_north_grid': 11.124998,
'max_south_grid': 9.27,
'max_west_grid': -86.25,
'max_east_grid': -83.97,
'northernmost_latitude': 11.124998,
'southernmost_latitude': 9.249998,
'westernmost_longitude': -86.25,
'easternmost_longitude': -84.0,
'nb_grid_bins': 2475,
'nb_bins': 2475,
'pct_bins': 100.0,
'nb_valid_bins': 1089,
'pct_valid_bins': 44.0,
'netcdf_version': '4.3.3.1 of Jul 8 2016 18:15:50 $',
'DPM_reference': 'GC-UD-ACRI-PUG',
'IODD_reference': 'GC-UD-ACRI-PUG'}
The code that I'm using to plot the image is:
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib
import cartopy.crs as ccrs
import dill as pickel
def paint_maps(df_std=None, fecha=1, attributes=None,
savefol='/media/felipe/TOSHIBA EXT/iMARES/Investigacion/2019_MariculturaPacifico/DB/figures/',
disp_fig=0):
"""Función para dibujar los datos contenidos en los archivos netCDF de SST, Salinidad y propiedad ópticas del agua.
Recibe el dataframe con la información en formato de Pandas Dataframe, y selecciona según una fecha establecida,
el conjunto de datos con coordenadas Lat-Lon que debe dibujar. Esos los dibuja y transforma a formato raster. Unido
se dibuja también la línea de costa proveniente de un archivo shapefile. La función dibuja toda la información
contenida en el dataframe aportado (datos, anomalías, flags, y cualquier otro dato que tenga.
Recibe:
df_std: dataframe con la información a dibujar. Debe venir indexado por fecha, lat y lon.
fecha: día que se elige dibujar. Formato string 'yyyymmdd'. Valor 1 significa que grafica el valor promedio de todas las fechas en cada
píxel. Promedio simple ignorando NaN's
attributes: diccionario con los atributos del netcdf de donde se obtiene nombre de variable y unidades. Creado
con open_netcdf.py
savefol: carpeta donde se guardan las imágenes dibujadas
disp_fig: booleano para imprimir figura en pantalla.
Devuelve:
Nada. Solo crea y guarda figuras"""
# Identifica la fecha solicitada (cuando se ha especificado) y confirma que sea parte del registro. Extrae la
# información del Dataframe en la fecha que se solicitó, o calcula el promedio de todas las fechas para graficar
# el valor promedio.
if fecha != 1:
if isinstance(fecha, str):
fecha = pd.to_datetime(fecha + '120000')
else:
print('La fecha indicada no está en formato String. Reinicie la ejecución.')
try:
idx = pd.IndexSlice
df_map = df_std.loc[idx[:, :, fecha], :]
except:
print('Se generó un error. Posiblemente fecha no está dentro del registro. La fecha debe estar entre el ' + df_std.index[0][-1].strftime('%d/%m/%Y') + ' y el ' + df_std.index[-1][-1].strftime('%d/%m/%Y'))
raise
else:
df_map = df_std.groupby(['lat', 'lon']).mean()
# Reestructura la información para tenerla en forma de matriz y dibujarla de forma más simple. Extrae los valores y
# las latitudes y longitudes correspondientes, así como los valores de la variable y sus flags.
df_map2 = df_map.unstack(level=0)
vari = df_map2['mean_val'].values
flags = df_map2['flag_val'].values
lat = df_map2['mean_val'].columns.get_level_values('lat')
lon = df_map2['mean_val'].index.get_level_values('lon')
# Extrae de los atributos del netcdf el nombre de la variable a graficar y las unidades
variable_str = attributes['variable']['long_name']
variable_units = attributes['variable']['units']
# Dibuja el mapa que se haya seleccionado según fecha (valor promedio del valor o fecha específica)
fig, ax = plt.subplots(1, 2, figsize=(10, 10), subplot_kw={'projection': ccrs.PlateCarree()})
extend = [lon[1], lon[-1], lat[1], lat[-1]]
# Primera figura. Variable a graficar. Usa línea de costa del cartopy y coloca una leyenda abajo
ax[0].set_extent(extend)
ax[0].coastlines(resolution='10m')
#cs = ax[0].pcolormesh(lon, lat, vari.T)
cs = ax[0].pcolormesh(lon, lat, vari.T, transform=ccrs.PlateCarree())
ax[0].set_title(variable_str)
cax, kw = matplotlib.colorbar.make_axes(ax[0], location='bottom', pad=0.05, shrink=0.7)
out = fig.colorbar(cs, cax=cax, extend='both', **kw)
out.set_label('Units: '+variable_units, size=10)
# Segunda figura. Flags de la figura. Usa la leyenda directamente de los datos usados.
ax[1].set_extent(extend)
ax[1].coastlines(resolution='10m')
cs2 = ax[1].pcolormesh(lon, lat, flags.T)
ax[1].set_title('Flags')
cax, kw = matplotlib.colorbar.make_axes(ax[1], location='bottom', pad=0.05, shrink=0.7)
out = fig.colorbar(cs2, cax=cax, extend='both', **kw)
out.set_label('Flags', size=10)
# Salva la figura
plt.savefig(savefol+variable_str+'.jpg', bbox_inches='tight')
with open(savefol+'fig_'+variable_str+'.pickel', 'wb') as f:
pickel.dump(fig, f)
# Imprime figura si se elige opción con disp_fig
if disp_fig == 1:
plt.show()
return
It receives the data as a Pandas dataframe. The NetCDF was opened using xarray.open_dataset and then transforming it to Pandas with to_dataframe()
I'm using Python 3.7 in Ubuntu.
Last thing. When loading the cartopy.crs package, this error occurs:
ERROR 1: PROJ: proj_create_from_database: Open of /home/felipe/anaconda3/envs/personal/share/proj failed
Could it be affecting?
we answered to Felipe by email, I copy/paste here:
A small Python script to create a map on your area from a TSM GlobColour Product (I used a monthly product to have a good coverage):
import netCDF4 as nc
import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
fig, ax = plt.subplots(figsize=(5, 5), subplot_kw=dict(projection=ccrs.PlateCarree()))
# my region of interest
ax.set_extent([-86, -84, 9, 11])
ax.coastlines(resolution='10m', color='red')
nc_dst = nc.Dataset('L3m_20100101-20100131__GLOB_4_AV-MER_TSM_MO_00.nc')
# extent of the product
data_extent = [nc_dst.max_west_grid, nc_dst.max_east_grid,
nc_dst.max_south_grid, nc_dst.max_north_grid]
data = nc_dst.variables['TSM_mean'][:]
flags = nc_dst.variables['TSM_flags'][:]
land = flags & 8 # LAND == 3rd bit == 2^3 == 8
data_noland = np.ma.masked_where(land, data)
ax.imshow(data_noland, origin='upper', extent=data_extent)
plt.savefig('TSM_noland.png')
ax.imshow(data, origin='upper', extent=data_extent)
plt.savefig('TSM.png')
I think you are facing to 2 problems:
1) Our products may overlap some land areas because of the Level-3 rebinning during the GlobColour processing: if a 4km pixel has only the corner on the water we will fill the full pixel. We keep them because they may be usefull for some needs (for example areas where the land/water limit is varying), but in the quality flags we provide a LAND mask which could be used to remove these pixels. You can also use your own LAND mask if you prefer. The Python example below shows how to use the LAND mask.
2) I suspect that your Python code introduces an east/south shift of at least half a pixel maybe because the lat/lon arrays are for the center of each pixel but the extent needed by cartopy is the exterior limit.
GlobColour flags are defined in the Product User Guide http://www.globcolour.info/CDR_Docs/GlobCOLOUR_PUG.pdf page 76.
The GlobColour Team
Are you sure your data are in WGS84? Looking at the metadata, I only see:
'earth_radius': 6378.137
which I imply means assume a spherical Earth with radius 6378.137 km. I don't have access to your data, but I would try setting up a cartopy.crs.Globe instance with that radius.

How do I run a grep command for each line in a file?

I have a file called adrese.csv that contains the first lines from another file called rezultate2.txt. For example:
www.afahc.ro/ro/rcic/simpozion/Simpozion_13/first_call.html
www.anmb.ro/ro/files/bric/mars_bric_2008/corespondente.html
www.anmb.ro/ro/files/bric/mars_bric_2011/corespondente.html
www.anmb.ro/ro/files/bric/mars_bric_2015/corespondente.html
www.anmb.ro/ro/files/bric/mars_bric_2017/corespondente.html
www.anmb.ro/ro/files/erasmus/parteneriate.html
www.anmb.ro/ro/files/studenti/ccoc/1/obiective.html
www.anmb.ro/ro/files/studenti/ccoc/2/servicii.html
www.anmb.ro/ro/files/studenti/ccoc/3/aspecte.html
The file rezultate2.txt contains beside these first lines a batch of text that has the word ”abandon” in it. I need to run grep -E -o ".{0,50}abandon.{0,50}" on rezultate2.txt for each line starting with the string in adrese.csv and output everything to a file, preferably a CSV. I tried different commands but nothing worked.
Sample rezultate2.txt
2345678abcd www.utm.ro/proiecte-europene/despre-pos-dru/index.html-
www.utm.ro/proiecte-europene/despre-pos-dru/index.html:Axa prioritară 2 finanţează activităţi care
urmăresc facilitarea tranziţiei de la şcoală la viaţa activă prin
dezvoltarea de programe integrate de orientare şi consiliere în
carieră şi prin sprijinirea parteneriatelor între şcoli, universităţi
şi întreprinderi; prevenirea şi corectarea fenomenului de părăsire
timpurie a şcolii prin programe integrate pentru prevenirea
abandonului şcolar, încurajarea participării şcolare şi reintegrarea
celor care au părăsit şcoala timpuriu; creşterea accesului şi
participării la formare profesională continuă prin diversificarea
programelor de formare profesională continuă şi sprijinirea
participării angajaţilor la astfel de programe.
www.utm.ro/proiecte-europene/despre-pos-dru/index.html-Axa Prioritară 3 “Creşterea
adaptabilităţii lucrătorilor şi a
întreprinderilor” 12345678abcd
www.utm.ro/posdru141699.1- www.utm.ro/posdru141699.1: Axa
prioritară 2 finanţează activităţi care urmăresc facilitarea
tranziţiei de la şcoală la viaţa activă prin dezvoltarea de programe
integrate de orientare şi consiliere în carieră şi prin sprijinirea
parteneriatelor între şcoli, universităţi şi întreprinderi, prevenirea
şi corectarea fenomenului de părăsire timpurie a şcolii prin programe
integrate pentru prevenirea abandonului şcolar, încurajarea
participării şcolare şi reintegrarea celor care au părăsit şcoala
timpuriu, creşterea accesului şi participării la formare profesională
continuă prin diversificarea programelor de formare profesională
continuă şi sprijinirea participării angajaţilor la astfel de
programe. www.utm.ro/posdru141699.1- 12345678abcd
www.utm.ro/posdru141699/index.html-
www.utm.ro/posdru141699/index.html: Axa prioritară 2 finanţează
activităţi care urmăresc facilitarea tranziţiei de la şcoală la viaţa
activă prin dezvoltarea de programe integrate de orientare şi
consiliere în carieră şi prin sprijinirea parteneriatelor între şcoli,
universităţi şi întreprinderi, prevenirea şi corectarea fenomenului de
părăsire timpurie a şcolii prin programe integrate pentru prevenirea
abandonului şcolar, încurajarea participării şcolare şi reintegrarea
celor care au părăsit şcoala timpuriu, creşterea accesului şi
participării la formare profesională continuă prin diversificarea
programelor de formare profesională continuă şi sprijinirea
participării angajaţilor la astfel de programe.
www.utm.ro/posdru141699/index.html- 12345678abcd
www.utm.ro/posdru141699/Despre_POSDRU.html-
www.utm.ro/posdru141699/Despre_POSDRU.html: Axa prioritară 2
finanţează activităţi care urmăresc facilitarea tranziţiei de la
şcoală la viaţa activă prin dezvoltarea de programe integrate de
orientare şi consiliere în carieră şi prin sprijinirea parteneriatelor
între şcoli, universităţi şi întreprinderi, prevenirea şi corectarea
fenomenului de părăsire timpurie a şcolii prin programe integrate
pentru prevenirea abandonului şcolar, încurajarea participării şcolare
şi reintegrarea celor care au părăsit şcoala timpuriu, creşterea
accesului şi participării la formare profesională continuă prin
diversificarea programelor de formare profesională continuă şi
sprijinirea participării angajaţilor la astfel de programe.
www.utm.ro/posdru141699/Despre_POSDRU.html- 12345678abcd
www.utm.ro/en/proiecte-europene/despre-pos-dru/index.html-
www.utm.ro/en/proiecte-europene/despre-pos-dru/index.html:Axa prioritară 2 finanţează activităţi care
urmăresc facilitarea tranziţiei de la şcoală la viaţa activă prin
dezvoltarea de programe integrate de orientare şi consiliere în
carieră şi prin sprijinirea parteneriatelor între şcoli, universităţi
şi întreprinderi; prevenirea şi corectarea fenomenului de părăsire
timpurie a şcolii prin programe integrate pentru prevenirea
abandonului şcolar, încurajarea participării şcolare şi reintegrarea
celor care au părăsit şcoala timpuriu; creşterea accesului şi
participării la formare profesională continuă prin diversificarea
programelor de formare profesională continuă şi sprijinirea
participării angajaţilor la astfel de programe.
www.utm.ro/en/proiecte-europene/despre-pos-dru/index.html-Axa Prioritară 3 “Creşterea
adaptabilităţii lucrătorilor şi a
întreprinderilor”
Desired output is a file containing the line in adrese.csv and it's corresponding text with just the word "abandon" and the 50 chars to the left and right of it:
www.utgjiu.ro/despre/index.html?p=5400 în timp ce vechi așezări se depopulează și cad în abandon. Nevoia unor sisteme de referință este, poate, ma
Managed to get what I needed with the help of a friend. The Python script below was written by Radu Eosif Mihăilescu:
#!/usr/bin/python
"""Custom work for Razvan T. Coloja, placed in the public domain by the author.
"""
import sys
MAGIC_WORD = 'abandon'
def main(argv):
with open(argv[1], 'r') as faddr:
addresses = set(l.rstrip() for l in faddr)
with open(argv[2], 'r') as fres:
the_text = set(l.rstrip() for l in fres)
for address in addresses:
for line in the_text:
if line.startswith(address):
where_found = line.find(MAGIC_WORD)
if where_found != -1:
if where_found > 50:
start_excerpt = where_found - 50
else:
start_excerpt = 0
print '"%s","%s"' % (
address,
line[start_excerpt:where_found + len(MAGIC_WORD) + 50])
if __name__ == '__main__':
main(sys.argv)
If I got it right what you are trying to achieve (running a grep on adrese.csv for each line with "abandon" in rezultate2.txt) the following snippet should do just that:
grep -E -o ".{0,50}abandon.{0,50}" rezultate2.txt | while read LINE ; do
grep "$LINE" adrese.csv >> output.csv
done
If I have understood you correctly, this:
sed 's/,/\n/g' adrese.csv | while read text ; do grep -F "$text" rezultate2.txt ; done > output.txt
Will:
The sed will convert the csv file into single lines
The while loop will take each of those inputs
And grep through the file for them.
Each of the output will be saved into output.txt

gnuplot rowstacked : Sum of rows is alway 100 but on the graphic bar are less than 100

I try to represent a budget with gnuplot with rowstacked histograms.
Here is my script
#Ce fichier permet de plotter les dépenses et les récettes sur une même image
#Les fichiers des données sont structurées comme suit
#Sur la première ligne qui commence par un croisillon suivi d'une espace, les textes des libellés. Les espaces à l'intérieur des libellés sont insécables
#Sur la deuxième ligne qui commence par un croisillon suivi d'une espace les valeurs en euros
#Sur la troisième ligne, le total de la section
#Sur la quatrième ligne les valeurs en pourcentage
#Dans un terminal, se placer dans le dossier où se trouve ce fichier, entrer la commande gnuplot
# puis au prompt de gnuplot taper : call "InvestissementRowStacked.gnu" "Fonctionnement" "2017" "545 000"
set decimalsign ','
unset multiplot
unset ylabel
set term pngcairo size 2048,800
set output ARG1.'.png'
#Le titre est commun aux deux plots
set multiplot title "Budget primitif - ".ARG1." ".ARG2." (Total ".ARG3." €)" font 'Arial,18'
#réglages communs aux deux plots
set style data histogram
set style histogram rowstacked
set boxwidth 2 absolute
set style fill solid border
#unset xtics
#unset ytics
#####################################
#DÉPENSES
######################################
#place le premier plot et le limite à la moitié de la largeur
set origin 0.01,0.05
set size 0.49,0.9
#titre pour le premier plot
set title "Dépenses" font 'Arial,16'
file ="Dépenses".ARG1.ARG2.".dat"
#regarde le nombre de données
unset xrange
unset yrange
stats file output
n=STATS_columns
set yrange [0:120]
#lit les valeurs en pourcentage sur la troisième ligne du fichier
getData(fName, row)=system(sprintf("sed -n -e %dp %s", row, fName))
values = getData(file, 3)
#lit les valeurs en euros sur la deuxième ligne
values2= getData(file, 2)
#utilise la première ligne pour les libellés
names=system(sprintf("head -1 '%s'",file))
#calcule le point d'arrivée des flèches en ordonnées
cumul_D=0
f(x)=(cumul_D=cumul_D+x, cur_D=cumul_D-x/2., cur_D)
#supprime la légende
unset key
#plot les dépenses avec les libellés et les flèches sur la gauche
set xrange [-14:2]
plot for [C=1:n] sprintf('%s',file) u C, \
for [C=1:n] sprintf('%s',file) u (-3.8):(2+9*C):(+2.8):(f(column(C))-2-9*C) w vectors lc rgb('black'), \
for [C=1:n] sprintf('%s',file) u (-4):(2+9*C):(word(names,C+1).' ('.word(values,C).'% | '.word(values2,C+1).' €) ') w labels right font 'Arial,14'
######################
# RECETTES
#######################
#plot les recettes avec les libellés et les flèches sur la droite
fileR ="Recettes".ARG1.ARG2.".dat"
#regarde le nombre de données
unset yrange
unset xrange
stats fileR output
n=STATS_columns
set yrange [0:120]
set xrange [-2:14]
set title "Recettes" font 'Arial,16'
#lit les valeurs en pourcentage dans la troisième ligne du fichier
values = getData(fileR, 3)
#lit les valeurs en euros sur la deuxième ligne du fichier
values2=getData(fileR, 2)
#utilise la première ligne pour les libellés
names=system(sprintf("head -1 '%s'",fileR))
#place le deuxième plot dans la seconde moitié en largeur du canvas
set origin 0.5,0.05
set size 0.49,0.9
#réinitialise le calcul des points d'arrivée des flèches de libellé
cumul_D=0
#plot les recettes avec les flèches et les libellés à droite
plot for [C=1:n] sprintf('%s',fileR) u C, \
for [C=1:n] sprintf('%s',fileR) u (3.8):(2+9*C):(-2.8):(f(column(C))-2-9*C) w vectors lc rgb('black'), \
for [C=1:n] sprintf('%s',fileR) u (4):(2+9*C):('('.word(values,C).'% | '.word(values2,C+1).' €) '.word(names,C+1)) w labels left font 'Arial,14'
unset multiplot; set output
the budget has two sections Investissement and Fonctionnement and I use the following command to plot the sections
call "BudgetRowStacked.gnu" "Fonctionnement" "2017" "460 000"
and
call "BudgetRowStacked.gnu" "Investissement" "2017" "545 000"
I get the following
There are some strangeness I have trouble to explain.
The bars doesn't reach 100 despite the fact that the sum of the data is always 100, moreover, in the Investissement section, the bars are of different heights.
I solved every thing using
set locale 'fr_FR'
set decimalsign locale

Resources