Diagramm DIN matplotlib

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
dl6tud
User
Beiträge: 5
Registriert: Dienstag 15. Mai 2012, 13:46

Sonntag 29. Juni 2014, 15:22

Ich würde gern Diagramme nach DIN 461 erstellen (http://de.wikipedia.org/wiki/DIN_461). Insbesondere möchte ich die Einheit direkt an die Achse schreiben, zwischen die Zahlen, siehe auch http://de.wikipedia.org/wiki/DIN_461#me ... itativ.svg unten. Auf "polnischem" Wege wäre mit "ax.annotate" sicher möglich, ich sucher aber eher nach einer einfacheren Möglichkeit.
Mit gnuplot geht es nicht, mit pgfplots sicher, aber python wäre der doch schnellste Weg um gute Diagramme zu erstellen. Daher die Frage.
EyDu
User
Beiträge: 4874
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Sonntag 29. Juni 2014, 15:31

Hallo!

Hast du dich schon durch die Gallery (oder die schönere Version :-) ) von Matplotlib gearbeitet? Vielleicht ist da ein Ansatz für dich bei.
Das Leben ist wie ein Tennisball.
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Sonntag 29. Juni 2014, 15:57

Das hilft zwar nicht großartig weiter, aber du kannst ruhig die Standardstile verwenden. Die orientieren sich grob daran was auch bei wissenschaftlichen Publikationen verwendet wird. Gerade Einheiten in den Zwischen den Zahlen sind unüblich. Die gehören in die Achsenbeschriftung.
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Sonntag 29. Juni 2014, 16:14

Mit Matplotlib geht in Sachen Diagrammen (fast) alles.

Wenn Du hier Hilfestellung haben möchtest, dann poste Python-Code der ein Diagramm erzeugt, das schon ungefähr Deinen Vorstellungen entspricht. Auf dieser Grundlage können hier dann Details diskutiert und probiert werden.
a fool with a tool is still a fool, www.magben.de, YouTube
dl6tud
User
Beiträge: 5
Registriert: Dienstag 15. Mai 2012, 13:46

Sonntag 29. Juni 2014, 18:56

Danke für die Tipps! Die Gallery habe ich jetzt (ohne Erfolg) kontrolliert. Das Einheiten zwischen den Zahlen unüblich sind, liegt darin, dass gnuplot, matplotlib etc. das leider nicht unterstützen. Egal, ich will das so :-)

Ich hänge mal ein Beispiel an. Das "s" und "V" müsste sozusagen an die richtige Stelle.

Code: Alles auswählen

#!/usr/bin/env python
import numpy as np
import matplotlib.pyplot as plt
import pylab
params = {'font.size' : 18, 'legend.fontsize': 20}
pylab.rcParams.update(params)

t = np.arange(0.0, 1.0 + 0.01, 0.01)
s = np.cos(4 * np.pi * t) + 2

plt.rc('text', usetex=True)
#plt.rc('font', family='serif')
plt.plot(t, s)

plt.xlabel(r'\textit{t}')
plt.ylabel(r'\textit{U}')
plt.subplots_adjust(top=0.8)

plt.annotate(r's', (0.9, 1.0), horizontalalignment='left', verticalalignment='top')
plt.annotate(r'V', (0.0, 2.75), horizontalalignment='left', verticalalignment='top')

plt.savefig('demo')
plt.show()
EyDu
User
Beiträge: 4874
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Sonntag 29. Juni 2014, 19:52

Vielleicht könntest du mit "set_yticks" und "set_yticklabels" da etwas drehen, besonders sauber scheint mir das aber nicht. Vielleicht hilft auch ein genauer Blick in die Dokumentation zum axis-Modul, da ist jede Menge einstellbar. Mit der Tick-Klasse geht vielleicht auch noch etwas.
Das Leben ist wie ein Tennisball.
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Montag 30. Juni 2014, 06:45

Ich habe Deine Font-Einstellungen weggelassen, die haben bei mir nicht funktioniert (Ubuntu 14.04).
Den Y-Label habe ich Horizontal gedreht, mit Leerzeichen den Abstand zur Achse vergrößert und den Font größer gemacht, sonst sieht der LaTeX Label kleiner aus als die Ticks.
Für die Einheit habe ich den Tick-Label vom letzten Tick ausgetauscht. Damit das funktioniert muss der Plot mit canvas.draw() schon gezeichnet worden sein, davor sind die Tick-Label noch nicht initialisiert.

Wichtig ist auch, dass Du den Rückgabewert von ax.get_xticklabels() nicht einfach nach ax.set_xticklabels() übergeben darfst. ax.get_xticklabels() gibt eine Liste von Tick Objekten zurück, ax.set_xticklabels() erwartet eine Liste von String Objekten, bzw. ruft einfach str() bei allen Elementen auf.

Code: Alles auswählen

import numpy as np
import matplotlib.pyplot as plt
 
t = np.arange(0.0, 1.0 + 0.01, 0.01)
s = np.cos(4 * np.pi * t) + 2
 
plt.plot(t, s)

#Der Plot muss schon gezeichnet sein, damit Du ihn veraendern kannst!
plt.gcf().canvas.draw()
 
plt.xlabel(r'$t$',                             fontsize=18)
plt.ylabel(r'$U$     ', rotation='horizontal', fontsize=18)

ax = plt.gca()
labels = [tick.get_text() for tick in ax.get_xticklabels()]
labels[-1] = 's'
ax.set_xticklabels(labels)
labels = [tick.get_text() for tick in ax.get_yticklabels()]
labels[-1] = 'V'
ax.set_yticklabels(labels)

plt.savefig('demo.png')
plt.show()
a fool with a tool is still a fool, www.magben.de, YouTube
Benutzeravatar
gkuhl
User
Beiträge: 600
Registriert: Dienstag 25. November 2008, 18:03
Wohnort: Hong Kong

Montag 30. Juni 2014, 08:43

Hi,

ich würde folgendes vorschlagen:

Code: Alles auswählen

import matplotlib.pyplot as plt 

def add_ax_units(ax, xunit, yunit):

    unitlabels = []

    for unit, labels in zip(
        [xunit, yunit], [ax.get_xticklabels(), ax.get_yticklabels()]
    ):  
        x0,y0 = labels[-2].get_position()
        x1,y1 = labels[-1].get_position()

        x = 0.5 * (x0 + x1) 
        y = 0.5 * (y0 + y1) 

        text = ax.text(x, y, unit)
        text.update_from(labels[-1])

        unitlabels.append(text)

    plt.draw()

    return unitlabels
Grüße
Gerrit
dl6tud
User
Beiträge: 5
Registriert: Dienstag 15. Mai 2012, 13:46

Montag 30. Juni 2014, 16:02

Vielen Dank, beide Varianten funktionieren sehr gut. Ich dachte nicht, dass das so einfach geht. :D

Zwei kleine Fragen habe ich noch:
(1) Die Koordinate der Sekunde wird oben referenziert. Dadurch ist das 's' oben bündig mit den Zahlen, unten wäre mir aber lieber. Gibt's dafür eine Lösung?

(2) Kann man einen Pfeil in die Achsenbeschriftung malen, wie z.B. "t ---->" und kann man die Beschriftung seitlich verschieben? Danke!!!!

Code: Alles auswählen

#!/usr/bin/env python    
import numpy as np
import matplotlib.pyplot as plt

def add_ax_units(ax, xunit, yunit):

  unitlabels = []

  for unit, labels in zip([xunit, yunit], [ax.get_xticklabels(), ax.get_yticklabels()]):
    x0,y0 = labels[-2].get_position()
    x1,y1 = labels[-1].get_position()

    x = 0.5 * (x0 + x1)
    y = 0.5 * (y0 + y1)

    text = ax.text(x, y, unit)
    text.update_from(labels[-1])

    unitlabels.append(text)

  plt.draw()

  return unitlabels

t = np.arange(0.0, 1.0 + 0.01, 0.01)
s = np.cos(4 * np.pi * t) + 2

plt.plot(t, s)

#Der Plot muss schon gezeichnet sein, damit Du ihn veraendern kannst!
plt.gcf().canvas.draw()

plt.xlabel(r'$t$',fontsize=25)
plt.ylabel(r'$U$ ', rotation='horizontal',fontsize=25)

ax = plt.gca()
add_ax_units(ax, "s", "V")


plt.savefig('demo.pdf')
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Dienstag 1. Juli 2014, 07:47

dl6tud hat geschrieben:Kann man einen Pfeil in die Achsenbeschriftung malen, wie z.B. "t ---->" und kann man die Beschriftung seitlich verschieben?
Mit LaTeX Syntax:

Code: Alles auswählen

import numpy as N
import matplotlib.pyplot as P

x = N.linspace(0,1,100)
P.plot(x,x**2)
P.xlabel(r"$\qquad t \longrightarrow$", fontsize=18)
P.show()
a fool with a tool is still a fool, www.magben.de, YouTube
Antworten