Python Tabelle plotten(Zeichenlänge begrenzen)

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
mgm841
User
Beiträge: 19
Registriert: Montag 7. Mai 2018, 12:15

Hallo zusammen, ich arbeite gerade an einem Uni-Projekt, und zwar soll ich mit Python eine Excel Datei auslesen und diese in Python als Tabelle plotten. Das habe ich auch soweit hinbekommen. Das Problem besteht jetzt darin eine Zeichenbegrenzung für jeden Datentyp, wie String, Integer, Float zu finden, damit sie in die vordefinierten Zellen passen. Ich habe leider diesbezüglich nichts finden können. Würde mich freuen, wenn ihr mir helfen könntet.
Bolitho
User
Beiträge: 219
Registriert: Donnerstag 21. Juli 2011, 07:01
Wohnort: Stade / Hamburg
Kontaktdaten:

zum Beispiel:

Code: Alles auswählen

string = 'abcdefghijk'
print(string[:5])
mgm841
User
Beiträge: 19
Registriert: Montag 7. Mai 2018, 12:15

Super funktioniert soweit, Danke! Nun habe ich das nächste Problem, wie kann ich mein Dataframe auf diese Funktion anwenden. Habe jetzt einfach mal eine For Schleife aufgebaut.
for str in df:
print(str[:10])

dabei wird mir aber nur die erste Zeile ausgegeben und nicht die komplette Excel Datei. Wenn ich aber print(df) nehme tut sie es aber.
Bolitho
User
Beiträge: 219
Registriert: Donnerstag 21. Juli 2011, 07:01
Wohnort: Stade / Hamburg
Kontaktdaten:

Bitte lass uns mehr an Deinem Code teilhaben, dann sehen wir auch besser wo es noch klemmt.
Und benutze bitte die Code Tags im Editor.

Die Pandas Dokumentation findest du hier: https://pandas.pydata.org/pandas-docs/s ... rrows.html

Code: Alles auswählen

import pandas as pd
dates = pd.date_range('20180629', periods=6)
df = pd.DataFrame('abcdefghijk', index=dates, columns=list('ABCD'))

for index, row in df.iterrows():
    print(str(row['A'])[:5])
    print(str(row['B'])[:5])
    print(str(row['C'])[:5])
    print(str(row['D'])[:5])
    print('----next row----')
Benutzeravatar
__blackjack__
User
Beiträge: 13112
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Eventuell ist hier ja auch die `slice()`-Methode vom `str`-Attribut von den Spalten (`Series`-Objekte) gesucht.

Code: Alles auswählen

In [16]: df
Out[16]: 
                      A            B            C            D
2018-06-29  abcdefghijk  abcdefghijk  abcdefghijk  abcdefghijk
2018-06-30  abcdefghijk  abcdefghijk  abcdefghijk  abcdefghijk
2018-07-01  abcdefghijk  abcdefghijk  abcdefghijk  abcdefghijk
2018-07-02  abcdefghijk  abcdefghijk  abcdefghijk  abcdefghijk
2018-07-03  abcdefghijk  abcdefghijk  abcdefghijk  abcdefghijk
2018-07-04  abcdefghijk  abcdefghijk  abcdefghijk  abcdefghijk

In [17]: df['A'].str.slice(0, 5)
Out[17]: 
2018-06-29    abcde
2018-06-30    abcde
2018-07-01    abcde
2018-07-02    abcde
2018-07-03    abcde
2018-07-04    abcde
Freq: D, Name: A, dtype: object
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
mgm841
User
Beiträge: 19
Registriert: Montag 7. Mai 2018, 12:15

Super danke nochmals! So sieht mein Code aus, jetzt schmeißt der mir einen neuen Fehler aus, hat mit der ursprünglichen Sache nichts zu tun, vllt könnt ihr mir trdm irgendwie helfen. Und zwar soll die erste Zeile meiner Tabelle grau untermalt sein damit es schöner ausschaut. Bevor ich es vergesse, das ganze soll als PDF ausgegeben werden, und damit es leserlich bleibt werden pro Seite max 10 Spalten ausgedruckt. Habe nur die Cell Funktion gefunden die bis jetzt funktioniert. Damit alle Zellen ausgewählt werden, musste ich eine For Schleife schreiben wie im Code ersichtlich. Nun gibt er mir einen KeyError Fehler raus, weil mein range ja immer bis Zehn geht, wenn aber die Excel Datei z.B. 32 Spalten hat, werden die ersten 30 Spalten Fehlerfrei ausgegeben, bei der 2 schmeisst der mir logischerweise den Fehler aus. Wie könnte ich das elegant lösen. BTW meine Excel Dateien können 1-60 Spalten enthalten. So die Vorgabe.

Code: Alles auswählen

import numpy as np
import matplotlib.pyplot as plt
#from matplotlib.pyplot import style
import pandas as pd
import seaborn as sns
from pyensae.graph_helper import Corrplot
#import sklearn
#from sklearn import linear_model
import matplotlib.pylab as pl
from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.backends.backend_pdf
from pandas.plotting import table
import matplotlib.patches as mpatches
from scipy import stats
from pdfrw import PdfReader, PdfWriter, PageMerge


df = pd.read_excel("C:/test/30.xlsx")

df.select_dtypes(include = ['int16', 'int32', 'int64', 'float16', 'float32', 'float64'])


#Pdf generieren
with PdfPages('multipage.pdf') as pdf:

#Tabelle 
#first_page
   s = df.iloc[0:15,0:10]
   fig, ax = plt.subplots(figsize=(5, 1),)
   plt.suptitle("1.Excel-Daten", fontsize =15)
   ax.xaxis.set_visible(False)
   ax.yaxis.set_visible(False)  
   ax.set_frame_on(False)  
   tabla = table(ax,s, colWidths=[0.20]*len(df.columns))
   tabla.auto_set_font_size(False) 
   tabla.set_fontsize(15)
   tabla.scale(1.5,1.5)
   for s in range(10):
       tabla._cells[0,s]._text.set_fontsize(13)
       tabla._cells[0,s].set_color('grey')
   pdf.savefig(fig,bbox_inches = 'tight', dpi = 300)
   plt.close

#2_page
   x= len(df.columns)
   if x > 10:  
       
    s1 = df.iloc[0:15, 10:20]
    fig1, ax1 = plt.subplots(figsize=(5, 1))
    plt.suptitle("1.Excel-Daten-Seite-2", fontsize =15)
    ax1.xaxis.set_visible(False)
    ax1.yaxis.set_visible(False)  
    ax1.set_frame_on(False)  
    tabla1 = table(ax1,s1, colWidths=[0.20]*len(df.columns))
    tabla1.auto_set_font_size(False) 
    tabla1.set_fontsize(15)
    tabla1.scale(1.5,1.5)
    for s1 in range(10):
      tabla1._cells[0,s1]._text.set_fontsize(13)
      tabla1._cells[0,s1].set_color('grey')
    pdf.savefig(fig1,bbox_inches = 'tight', dpi = 300)
    
   else:
    plt.close
   
#3_page
   x = len(df.columns)
   
   if x > 20:
    s2 = df.iloc[0:15, 20:30]
    fig, ax2 = plt.subplots(figsize=(5, 1))
    plt.suptitle("1.Excel-Daten-Seite-3", fontsize =15)
    ax2.xaxis.set_visible(False)
    ax2.yaxis.set_visible(False)  
    ax2.set_frame_on(False)  
    tabla2 = table(ax2,s2, colWidths=[0.20]*len(df.columns))
    tabla2.auto_set_font_size(False) 
    tabla2.set_fontsize(15)
    tabla2.scale(1.5,1.5)
    for s2 in range(10):
        tabla2._cells[0,s2]._text.set_fontsize(13)
        tabla2._cells[0,s2].set_color('grey')
    pdf.savefig(fig,bbox_inches = 'tight', dpi = 300)
   else:
    plt.close

#4_page
   x = len(df.columns)
   
   if x > 30:
    s3 = df.iloc[0:15, 30:40]
    fig, ax3 = plt.subplots(figsize=(5, 1))
    plt.suptitle("1.Excel-Daten-Seite-4", fontsize =15)
    ax3.xaxis.set_visible(False)
    ax3.yaxis.set_visible(False)  
    ax3.set_frame_on(False)  
    tabla3 = table(ax3,s3, colWidths=[0.20]*len(df.columns))
    tabla3.auto_set_font_size(False) 
    tabla3.set_fontsize(15)
    tabla3.scale(1.5,1.5)
    for s3 in range(10):
        tabla3._cells[0,s3]._text.set_fontsize(13)
        tabla3._cells[0,s3].set_color('grey')
    pdf.savefig(fig,bbox_inches = 'tight', dpi = 300)
    
   else:
    plt.close

#5_page
   x = len(df.columns)
   
   if x > 40:
    s4 = df.iloc[0:15, 40:50]
    fig, ax4 = plt.subplots(figsize=(5, 1))
    plt.suptitle("1.Excel-Daten-Seite-5", fontsize =15)
    ax4.xaxis.set_visible(False)
    ax4.yaxis.set_visible(False)  
    ax4.set_frame_on(False)  
    tabla4 = table(ax4,s4, colWidths=[0.20]*len(df.columns))
    tabla4.auto_set_font_size(False) 
    tabla4.set_fontsize(15)
    tabla4.scale(1.5,1.5)
    for s4 in range(10):
        tabla4._cells[0,s4]._text.set_fontsize(13)
        tabla4._cells[0,s4].set_color('grey')
    pdf.savefig(fig,bbox_inches = 'tight', dpi = 300)
    
   else:
    plt.close
    
    
#6_page
   x = len(df.columns)
   
   if x > 50:
    s5 = df.iloc[0:15, 50:60]
    fig, ax5 = plt.subplots(figsize=(5, 1))
    plt.suptitle("1.Excel-Daten-Seite-6", fontsize =15)
    ax5.xaxis.set_visible(False)
    ax5.yaxis.set_visible(False)  
    ax5.set_frame_on(False)  
    tabla5 = table(ax5,s5, colWidths=[0.20]*len(df.columns))
    tabla5.auto_set_font_size(False) 
    tabla5.set_fontsize(15)
    tabla5.scale(1.5,1.5)
    for s5 in range(10):
        tabla5._cells[0,s5]._text.set_fontsize(13)
        tabla5._cells[0,s5].set_color('grey')
    pdf.savefig(fig,bbox_inches = 'tight', dpi = 300)
    
   else:
    plt.close
Benutzeravatar
__blackjack__
User
Beiträge: 13112
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@mgm841: Das macht man nicht in dem man sechs mal fast den gleichen Quelltext schreibt, sondern mit einer Schleife die in 10er-Schritten durch die Spalten geht.

Der Quelltext ist übrigens inkonsistent eingerückt. Vier Leerzeichen pro Ebene ist die Konvention.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
__blackjack__
User
Beiträge: 13112
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Der Zugriff auf `_cells` und `_text` ist falsch. Das sind Interna auf die man von aussen nicht zugreifen darf. Der führende Unterstrich ist in Python die Namenskonvention dafür. An die Zellen kommt man mit der `get_celld()` auf der Tabelle und die Zellen selbst haben eine `set_fontsize()`-Methode — da muss man nicht in den Innereien dieser Objekte operieren.

Edit: Die Tabellenspaltenbreite wird falsch berechnet. Und ``plt.close`` hat keinen Effekt weil die `close()`-Funktion nicht aufgerufen wird. Da nirgends `show()` steht, ist das aber auch gar nicht notwendig. Bei den Importen könnte man mal radikal aufräumen. Der `select_dtypes()`-Aufruf macht keinen Sinn, weil mit dem Ergebnis überhaupt nichts gemacht wird. `s` wird in der Schleife für zwei völlig verschiedene Zwecke verwendet.

Ungetestet:

Code: Alles auswählen

import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
import pandas as pd
from pandas.plotting import table


def main():
    data_frame = pd.read_excel('C:/test/30.xlsx')

    with PdfPages('multipage.pdf') as pdf:
        columns_per_page = 10
        for page_no, start_column in enumerate(
            range(0, data_frame.shape[1], columns_per_page), 1
        ):
            sub_frame = data_frame.iloc[
                0:15, start_column:start_column + columns_per_page
            ]
            fig, ax = plt.subplots(figsize=(5, 1))
            fig.suptitle('1.Excel-Daten-Seite-{}'.format(page_no), fontsize=15)
            ax.xaxis.set_visible(False)
            ax.yaxis.set_visible(False)
            ax.set_frame_on(False)
            a_table = table(ax, sub_frame, colWidths=[0.2] * sub_frame.shape[1])
            a_table.auto_set_font_size(False)
            a_table.set_fontsize(15)
            a_table.scale(1.5, 1.5)
            cells = a_table.get_celld()
            for cell in (cells[0, i] for i in range(sub_frame.shape[1])):
                cell.set_fontsize(13)
                cell.set_color('grey')
            pdf.savefig(fig, bbox_inches='tight', dpi=300)


if __name__ == '__main__':
    main()
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
mgm841
User
Beiträge: 19
Registriert: Montag 7. Mai 2018, 12:15

__blackjack__ hat geschrieben: Freitag 29. Juni 2018, 13:23 Der Zugriff auf `_cells` und `_text` ist falsch. Das sind Interna auf die man von aussen nicht zugreifen darf. Der führende Unterstrich ist in Python die Namenskonvention dafür. An die Zellen kommt man mit der `get_celld()` auf der Tabelle und die Zellen selbst haben eine `set_fontsize()`-Methode — da muss man nicht in den Innereien dieser Objekte operieren.

Edit: Die Tabellenspaltenbreite wird falsch berechnet. Und ``plt.close`` hat keinen Effekt weil die `close()`-Funktion nicht aufgerufen wird. Da nirgends `show()` steht, ist das aber auch gar nicht notwendig. Bei den Importen könnte man mal radikal aufräumen. Der `select_dtypes()`-Aufruf macht keinen Sinn, weil mit dem Ergebnis überhaupt nichts gemacht wird. `s` wird in der Schleife für zwei völlig verschiedene Zwecke verwendet.

Ungetestet:

Code: Alles auswählen

import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
import pandas as pd
from pandas.plotting import table


def main():
    data_frame = pd.read_excel('C:/test/30.xlsx')

    with PdfPages('multipage.pdf') as pdf:
        columns_per_page = 10
        for page_no, start_column in enumerate(
            range(0, data_frame.shape[1], columns_per_page), 1
        ):
            sub_frame = data_frame.iloc[
                0:15, start_column:start_column + columns_per_page
            ]
            fig, ax = plt.subplots(figsize=(5, 1))
            fig.suptitle('1.Excel-Daten-Seite-{}'.format(page_no), fontsize=15)
            ax.xaxis.set_visible(False)
            ax.yaxis.set_visible(False)
            ax.set_frame_on(False)
            a_table = table(ax, sub_frame, colWidths=[0.2] * sub_frame.shape[1])
            a_table.auto_set_font_size(False)
            a_table.set_fontsize(15)
            a_table.scale(1.5, 1.5)
            cells = a_table.get_celld()
            for cell in (cells[0, i] for i in range(sub_frame.shape[1])):
                cell.set_fontsize(13)
                cell.set_color('grey')
            pdf.savefig(fig, bbox_inches='tight', dpi=300)


if __name__ == '__main__':
    main()
Super funktioniert, der braucht zwar etwas länger fürs plotten., kann ich aber verkraften:). Mein Anfangsproblem löst es ja trotzdem nicht wirklich. Man kann kaum was lesen, da die kompletten Buchstaben in die Zelle geprintet wird.
mgm841
User
Beiträge: 19
Registriert: Montag 7. Mai 2018, 12:15

__blackjack__ hat geschrieben: Freitag 29. Juni 2018, 11:38 Eventuell ist hier ja auch die `slice()`-Methode vom `str`-Attribut von den Spalten (`Series`-Objekte) gesucht.

Code: Alles auswählen

In [16]: df
Out[16]: 
                      A            B            C            D
2018-06-29  abcdefghijk  abcdefghijk  abcdefghijk  abcdefghijk
2018-06-30  abcdefghijk  abcdefghijk  abcdefghijk  abcdefghijk
2018-07-01  abcdefghijk  abcdefghijk  abcdefghijk  abcdefghijk
2018-07-02  abcdefghijk  abcdefghijk  abcdefghijk  abcdefghijk
2018-07-03  abcdefghijk  abcdefghijk  abcdefghijk  abcdefghijk
2018-07-04  abcdefghijk  abcdefghijk  abcdefghijk  abcdefghijk

In [17]: df['A'].str.slice(0, 5)
Out[17]: 
2018-06-29    abcde
2018-06-30    abcde
2018-07-01    abcde
2018-07-02    abcde
2018-07-03    abcde
2018-07-04    abcde
Freq: D, Name: A, dtype: object
Wie würde es denn funktionieren, wenn ich es automatisieren lassen würde. Ich will es für x beliebige Excel files benutzen. Da kann ich ja nicht jedes mal den Spaltennamen mitgeben. Bei 50 Spalten aufwärts wird das dann doch arg schwierig das zu realisieren.
Antworten