gnuplot: কিভাবে কোনও মার্জিন ছাড়াই পিক্সেল প্রতি 2D অ্যারে উপাদান প্লট করবেন


9

মার্জিন বা সীমানা বা অক্ষ ছাড়াই 2D অ্যারের ডেটা প্লট করতে আমি gnuplot 5.0 ব্যবহার করার চেষ্টা করছি ... কিছু ডেটা উপস্থাপন করে কেবল একটি 2D চিত্র (.png বা .jpg)। আমি প্রতিটি অ্যারে উপাদানটি স্কেলিং / ইন্টারপোলেশন ইত্যাদি এবং প্রান্তগুলিতে কোনও অতিরিক্ত সাদা পিক্সেল সহ চিত্রের ঠিক এক পিক্সেলের সাথে সামঞ্জস্য করতে চাই

এখনও অবধি, যখন আমি মার্জিনগুলি 0 তে সেট করতে এবং pixelsপতাকা ব্যবহার করেও চেষ্টা করি তখনও আমি চিত্রের ডান এবং উপরের সীমানায় সাদা পিক্সেলের একটি সারি রেখে এসেছি।

আমি কীভাবে একটি ডেটা অ্যারের পিক্সেল-বাই-পিক্সেল উপস্থাপনা এবং অতিরিক্ত কিছু দিয়ে একটি চিত্র ফাইল পেতে পারি?

gnuplot লিপি:

#!/usr/bin/gnuplot --persist

set terminal png size 400, 200

set size ratio -1
set lmargin at screen 0
set rmargin at screen 1
set tmargin at screen 0
set bmargin at screen 1

unset colorbox
unset tics
unset xtics
unset ytics
unset border
unset key

set output "pic.png"

plot "T.dat" binary array=400x200 format="%f" with image pixels notitle

ফরট্রান 90 থেকে ডেটা উদাহরণ:

program main
implicit none
integer, parameter :: nx = 400
integer, parameter :: ny = 200
real, dimension (:,:), allocatable :: T
allocate (T(nx,ny))

T(:,:)=0.500
T(2,2)=5.
T(nx-1,ny-1)=5.
T(2,ny-1)=5.
T(nx-1,2)=5.

open(3, file="T.dat", access="stream")
write(3) T(:,:)
close(3)

end program main

অতিরিক্ত পিক্সেল


তথ্য x y zতালিকা বিন্যাসে থাকলে তা গ্রহণযোগ্য হবে?
theozh

উত্তর:


5

কিছু gnuplot টার্মিনাল চিত্রযুক্ত একটি পৃথক png ফাইল তৈরি করে ফলাফলের প্লটের অভ্যন্তরে এর সাথে যুক্ত করে "চিত্র সহ" প্রয়োগ করে। পৃথক পৃথক পিএনজি চিত্র ফাইলটি ব্যবহার করা পৃষ্ঠার বিন্যাস, মার্জিন ইত্যাদি কোনও সমস্যা এড়াতে পারে এখানে আমি ক্যানভাস টার্মিনালটি ব্যবহার করি। চক্রান্ত নিজেই ফেলে দেওয়া হয়; আমরা যা রাখি তা হ'ল পছন্দসই সামগ্রী দিয়ে তৈরি পিএনজি ফাইল।

gnuplot> set term canvas name 'myplot'
Terminal type is now 'canvas'
Options are ' rounded size 600,400 enhanced fsize 10 lw 1 fontscale 1 standalone'
gnuplot> set output '/dev/null'
gnuplot> plot "T.dat" binary array=400x200 format="%f" with image 
   linking image 1 to external file myplot_image_01.png
gnuplot> quit

$identify myplot_image_01.png
myplot_image_01.png PNG 400x200 400x200+0+0 8-bit sRGB 348B 0.000u 0:00.000

এটি সংক্ষিপ্ত এবং দ্রুত এবং কাজ করে! আমি এখনও সফল হতে পারি নি: উইন্ডোজে আউটপুট এড়িয়ে চলুন, ২. পিএনজি ফাইলে সূচি ছাড়াই আমার নিজের নাম দিন বা কমপক্ষে আপনি যখন প্লটটি পুনরায় তৈরি করবেন তখন পিএনজি ফাইলের সূচি বাড়ানো বন্ধ করুন।
theozh

আমি উইন্ডোজ আউটপুট সাহায্য করতে পারি না। আপনি ক্যানভাস টার্মিনালের কাউন্টার সম্পর্কে ঠিক বলেছেন; এটি কখনই পুনরায় সেট করে না। তবে আপনি একই কৌশলটি খেলতে পারেন set term tikz externalimagesএবং সেই টার্মিনালটি প্রতি "সেট টার্ম" এ কাউন্টারটিকে পুনরায় সেট করে। আপনি set output "/dev/null"টিক্জ দিয়ে ব্যবহার করতে পারবেন না , তবে এটি যদি আপনার জন্য আউটপুট দমন করতে কাজ না করে তবে আপনার পাত্তা নাও লাগতে পারে। টেক্কানভাস এবং এসভিজি টার্মিনালগুলি অন্যান্য সম্ভাবনা, তবে সেগুলির মধ্যে বাহ্যিক পিএনজি প্রক্রিয়াটি gnuplot সংস্করণ এবং সংকলনের বিকল্পগুলির উপর নির্ভর করে।
ইথান

এটি দুর্দান্ত কাজ করে! সত্যটির পরে সামান্য নামকরণ করা প্রয়োজন, তবে শেষ পর্যন্ত আমি পিক্সেল-হুবহু চিত্র ফাইলটি পেয়ে যাচ্ছি যেমনটি আমি খুঁজছিলাম। ধন্যবাদ!
হটডগকননন

3

Gnuplot ব্যবহার করবেন না।

পরিবর্তে, এমন কোনও স্ক্রিপ্ট লিখুন যা আপনার ডেটা পড়ে এবং এটিকে কোনও পোর্টেবল যেকোনম্যাপ ফর্ম্যাটে রূপান্তর করে । পাইথনের উদাহরণ এখানে:

#!/usr/bin/env python3
import math
import struct

width = 400
height = 200
levels = 255

raw_datum_fmt = '=d' # native, binary double-precision float
raw_datum_size = struct.calcsize(raw_datum_fmt)

with open('T.dat', 'rb') as f:
    print("P2")
    print("{} {}".format(width, height))
    print("{}".format(levels))

    raw_data = f.read(width * height * raw_datum_size)

    for y in range(height):
        for x in range(width):
            raw_datum, = struct.unpack_from(raw_datum_fmt, raw_data, (y * width + x) * raw_datum_size)
            datum = math.floor(raw_datum * levels) # assume a number in the range [0, 1]
            print("{:>3} ".format(datum), end='')
        print()

আপনি যদি প্রোগ্রামটি সংশোধন করতে পারেন যা ডেটা ফাইল তৈরি করে, আপনি উপরের পদক্ষেপটি এড়িয়ে যেতে পারেন এবং পরিবর্তে সরাসরি পিএনএম ফর্ম্যাটে ডেটা উত্পন্ন করতে পারেন।

যে কোনও উপায়েই আপনি চিত্রটিকে নিজের পছন্দের বিন্যাসে রূপান্তর করতে ইমেজম্যাগিক ব্যবহার করতে পারেন:

./convert.py | convert - pic.png

1
প্রকৃতপক্ষে এই ধরণের কাজের জন্য Gnuplot ব্যবহার করা কোনও জিনিসকে পেরেক চালানোর জন্য কোনও বই ব্যবহার করার মতো। এটি কাজ করতে পারে তবে বই এই কাজের জন্য তৈরি করা হয় না। আমার পছন্দসই সরঞ্জামটি জিএনইউ অষ্টাভে "জিএনইউ" ডোমেইনে থাকবে :) imwriteফাংশনটি 2 ডি ডেটা পিএনজি চিত্র হিসাবে সংরক্ষণ করতে ব্যবহৃত হতে পারে।
blerontin

এটি একটি আকর্ষণীয় রুট, এবং অবশ্যই একটি মূল্যবান ব্যাকআপ, তবে আমি যদি ব্যবহার করতে যাচ্ছি না gnuplot, তবে আমি কেবল matplotlibপরিবর্তে ব্যবহার করব (নীচে আমার উত্তরটি দেখুন)। এটি একটি দুর্দান্ত অবদান, তবে প্রযুক্তিগতভাবে প্রশ্ন / অনুগ্রহ একটি gnuplotসমাধান জিজ্ঞাসা করে , যতটা অযোগ্য হিসাবে এটি নির্দিষ্ট কাজের জন্য মনে হয়।
হটডগনক্যানন

3

এটি একটি সহজ কাজ হওয়া উচিত, তবে দৃশ্যত এটি তা নয়। নিম্নলিখিত অন্যান্য (প্রচেষ্টা) সমাধান হতে পারে কারণ অন্যান্য সমস্ত প্রচেষ্টা ব্যর্থ হয়েছে। আমার সন্দেহ হ'ল কিছু গ্রাফিক্স লাইব্রেরিতে একটি সমস্যা রয়েছে যা আপনি সম্ভবত একটি gnuplot ব্যবহারকারী হিসাবে সমাধান করতে পারবেন না।

আপনি উল্লেখ করেছেন যে এএসসিআইআই ম্যাট্রিক্স ডেটাও ঠিক আছে। "কৌশল" এখানে ডেটা প্লট করা with linesযেখানে ডেটা ফাঁকা লাইনে "বাধা" দেওয়া হয়, মূলত একক পয়েন্ট আঁকতে। আপনার ডেটাফিল 1: 1 একটি ডেটাব্লকের মধ্যে পাওয়ার প্রয়োজন হলে এটি পরীক্ষা করে দেখুন ।

যাইহোক, যদি এটি ইতিমধ্যে অদ্ভুত যথেষ্ট নয়, এটা কাজ বলে মনে হয় pngএবং gifটার্মিনাল কিন্তু না pngcairoবা wxt। আমার ধারণা অনুমানটি সম্ভবত ধীর এবং অদক্ষ তবে কমপক্ষে এটি পছন্দসই আউটপুট তৈরি করে। আকারের সীমা আছে কিনা তা আমি নিশ্চিত নই। Win7, gnuplot 5.2.6 দিয়ে 100x100 পিক্সেল দিয়ে পরীক্ষা করা হয়েছে। মন্তব্য এবং উন্নতি স্বাগত।

কোড:

### pixel image from matrix data without strange white border
reset session

SizeX = 100
SizeY = 100
set terminal png size SizeX,SizeY
set output "tbPixelImage.png"

# generate some random matrix data
set print $Data2
    do for [y=1:SizeY] {
        Line = ''
        do for [x=1:SizeX] {
            Line = Line.sprintf(" %9d",int(rand(0)*0x01000000))  # random color
        }
        print Line
    }
set print
# print $Data2

# convert matrix data into x y z data with empty lines inbetween
set print $Data3
    do for [y=1:SizeY] {
        do for [x=1:SizeX] {
            print sprintf("%g %g %s", x, y, word($Data2[y],x))
            print ""
        }
    }
set print
# print $Data3

set margins 0,0,0,0
unset colorbox
unset border
unset key
unset tics

set xrange[1:SizeX]
set yrange[1:SizeY]

plot $Data3 u 1:2:3 w l lw 1 lc rgb var notitle

set output
### end of code

ফলাফল: (100x100 পিক্সেল)

এখানে চিত্র বর্ণনা লিখুন

(কালো পটভূমিতে প্রসারিত):

এখানে চিত্র বর্ণনা লিখুন

400x200 পিক্সেল সহ চিত্র (আমার 8 বছরের পুরানো ল্যাপটপে প্রায় 22 সেকেন্ড লাগে)।

এখানে চিত্র বর্ণনা লিখুন


এবং যদি সাইজএক্স এবং সাইজওয়াই সমান না হয় তবে কী হবে?
হটডগকননন

দুঃখিত, আমি মিশ্রিত xএবং y। এটি সমান SizeXএবং SizeYনা থাকলে এখনও এটি কাজ করে । আমি কোড সংশোধন করব।
theozh

ঠিক আছে, আকর্ষণীয় পদ্ধতির, তবে আমি কীভাবে ফোর্টরান থেকে আপনার মতো একটি অ্যারে বা প্রবাহে বাইনারি ডেটাতে প্রথম পড়ব Data2?
হটডগনক্যানন

আপনি কি কোনওভাবে ভাসমান পয়েন্ট ডেটা পরীক্ষার জন্য 400x200 বাইনারি ফাইল সরবরাহ করতে পারেন?
theozh

1

প্রশ্ন / অনুগ্রহীর gnuplotসমাধানের জন্য জিজ্ঞাসা করা সত্ত্বেও আমার যা প্রয়োজন তা পেতে আসলে আমি কী শেষ করেছি :

matplotlibmatplotlib.pyplot.imsave এর একটি ফাংশন রয়েছে যা আমি যা খুঁজছিলাম তা করে ... যেমন 'স্রেফ ডেটা পিক্সেল প্লট করা' এবং সীমানা, মার্জিন, অক্ষ ইত্যাদি ইত্যাদির মতো কোনও অতিরিক্ত নেই মূলত আমি কেবল ম্যাটপ্ল্লোবিব.পাইপ্লট.আইমশো সম্পর্কে জানতাম এবং তা করতে হয়েছিল চিত্র ফাইলটি থেকে সমস্ত অতিরিক্ত মুছে ফেলার জন্য এবং যেকোনো প্রবৃদ্ধি / স্মুথিং ইত্যাদি প্রতিরোধ করার জন্য প্রচুর কৌশল অবলম্বন করুন (এবং সেজন্য gnuplotএকটি নির্দিষ্ট বিন্দুতে পরিণত হয়েছে )। সঙ্গে imsaveএটা মোটামুটি সহজ, তাই আমি ব্যবহারে ফিরে আছি matplotlibএকটি সহজ এখনো 'ঠিক পিক্সেলের' প্লট জন্য এখনো নমনীয় সমাধান (colormap, স্কেলিং, ইত্যাদি পদ)। এখানে একটি উদাহরণ:

#!/usr/bin/env python3

import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt

nx = 400
ny = 200

data = np.fromfile('T.dat', dtype=np.float32, count=nx*ny)
data = data.reshape((nx,ny), order='F')
matplotlib.image.imsave('T.png', np.transpose(data), origin='lower', format='png')

1

ঠিক আছে, এখানে আরও একটি সম্ভাব্য সমাধান রয়েছে (আমি এটিকে আমার প্রথম জটিল পদ্ধতির থেকে পৃথক করেছি)। এটি অবিলম্বে প্লট তৈরি করে, এক সেকেন্ডেরও কম। কোনও নাম পরিবর্তন করার প্রয়োজন নেই বা অকেজো ফাইল তৈরি করা।

আমি অনুমান করি কী ব্যবহার করা হয় term pngএবং ps 0.1

আমার কাছে প্রমাণ নেই তবে আমার মনে হয় ps 1সিএ হবে। 6 পিক্সেল বড় এবং কোণায় কিছু ওভারল্যাপ এবং / অথবা সাদা পিক্সেল তৈরি করবে। আবার যে কোনও কারণে এটি কাজ করে বলে মনে হয় term pngতবে সাথে নয় term pngcairo

আমি যা পরীক্ষা করেছি (Win7, gnuplot 5.2.6) একটি বাইনারি ফাইল যা প্যাটার্নটি পুরোপুরি 00 00 FFপুনরাবৃত্তি করা হয়েছে (আমি এখানে নাল বাইট প্রদর্শন করতে পারি না)। যেহেতু gnuplot স্পষ্টতই অ্যারে আইটেমটি 4 বাইট পড়েন ( format="%d"), তাই আমি যদি প্লট করছি তবে এটি একটি বিকল্প আরজিবি প্যাটার্নের দিকে নিয়ে যায় with lc rgb var

একইভাবে (আশাবাদী) আমরা কীভাবে format="%f"একটি রঙ প্যালেট সহ একসাথে এটি পড়তে এবং ব্যবহার করতে পারি তা নির্ধারণ করতে পারি। আমার ধারণা আপনি ঠিক তাই খুঁজছেন? পরবর্তী পরীক্ষার ফলাফল, মন্তব্য, উন্নতি এবং ব্যাখ্যা স্বাগত।

কোড:

### pixel image from matrix data without strange white border
reset session

SizeX = 400
SizeY = 200
set terminal png size SizeX,SizeY
set output "tbPixelImage.png"

set margins 0,0,0,0
unset colorbox
unset border
unset key
unset tics

set xrange[0:SizeX-1]
set yrange[0:SizeY-1]

plot "tbBinary.dat" binary array=(SizeX,SizeY) format="%d" w p pt 5 ps 0.1 lc rgb var
### end of code

ফলাফল:

এখানে চিত্র বর্ণনা লিখুন

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.